Difference between revisions of "Example Dense Optical Flow"

From BoofCV
Jump to navigationJump to search
(Created page with "<center> <gallery widths=640px heights=260px> file:Example_dense_optical_flow.gif | Colorized optical flow. Color is direction and intensity is magnitude. </gallery> </center...")
 
m
 
(6 intermediate revisions by the same user not shown)
Line 5: Line 5:
</center>
</center>


Dense optical flow estimates the apparent motion of each pixel in the image.  It is used in video compression, object detection, object tracking, and image segmentation. Dense optical flow is a computationally expensive operation and many techniques use hardware acceleration.
Dense optical flow compares two images to estimate the apparent motion of each pixel in the one of the images.  It is used in video compression, object detection, object tracking, and image segmentation. Dense optical flow is a computationally expensive operation and many techniques use hardware acceleration.


Example Code:
Example Code:
* [https://github.com/lessthanoptimal/BoofCV/blob/v0.17/examples/src/boofcv/examples/features/ExampleDenseOpticalFlow.java ExampleDenseOpticalFlow.java]
* [https://github.com/lessthanoptimal/BoofCV/blob/v0.38/examples/src/boofcv/examples/features/ExampleDenseOpticalFlow.java ExampleDenseOpticalFlow.java]


Concepts:
Concepts:
* Optical Flow
* Optical Flow
Relevant Applets:
* [[Applet Dense Optical Flow| Dense Optical Flow]]


= Example Code =
= Example Code =
Line 20: Line 17:
<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
/**
/**
  * Demonstration of how to compute the dense optical flow between two images. Dense optical flow of an image
  * Demonstration of how to compute the dense optical flow between two images. Dense optical flow of an image
  * describes how each pixel moves from one image to the next. The results is visualized in a color image. The
  * describes how each pixel moves from one image to the next. The results is visualized in a color image. The
  * color indicates the direction of motion and the intensity the magnitude.
  * color indicates the direction of motion and the intensity the magnitude.
  *
  *
Line 28: Line 25:
public class ExampleDenseOpticalFlow {
public class ExampleDenseOpticalFlow {


public static void main(String[] args) {
public static void main( String[] args ) {
MediaManager media = DefaultMediaManager.INSTANCE;
MediaManager media = DefaultMediaManager.INSTANCE;


// String fileName0 = "../data/applet/denseflow/dogdance07.png";
// String fileName0 = UtilIO.pathExample("denseflow/dogdance07.png");
// String fileName1 = "../data/applet/denseflow/dogdance08.png";
// String fileName1 = UtilIO.pathExample("denseflow/dogdance08.png");


String fileName0 = "../data/applet/denseflow/Urban2_07.png";
String fileName0 = UtilIO.pathExample("denseflow/Urban2_07.png");
String fileName1 = "../data/applet/denseflow/Urban2_08.png";
String fileName1 = UtilIO.pathExample("denseflow/Urban2_08.png");


// String fileName0 = "../data/applet/denseflow/Grove2_07.png";
// String fileName0 = UtilIO.pathExample("denseflow/Grove2_07.png");
// String fileName1 = "../data/applet/denseflow/Grove2_09.png";
// String fileName1 = UtilIO.pathExample("denseflow/Grove2_09.png");


DenseOpticalFlow<ImageFloat32> denseFlow =
DenseOpticalFlow<GrayF32> denseFlow =
// FactoryDenseOpticalFlow.flowKlt(null, 6, ImageFloat32.class, null);
// FactoryDenseOpticalFlow.flowKlt(null, 6, GrayF32.class, null);
// FactoryDenseOpticalFlow.region(null,ImageFloat32.class);
// FactoryDenseOpticalFlow.region(null,GrayF32.class);
// FactoryDenseOpticalFlow.hornSchunck(20, 1000, ImageFloat32.class);
// FactoryDenseOpticalFlow.hornSchunck(20, 1000, GrayF32.class);
// FactoryDenseOpticalFlow.hornSchunckPyramid(null,ImageFloat32.class);
// FactoryDenseOpticalFlow.hornSchunckPyramid(null,GrayF32.class);
FactoryDenseOpticalFlow.broxWarping(null, ImageFloat32.class);
FactoryDenseOpticalFlow.broxWarping(null, GrayF32.class);


BufferedImage buff0 = media.openImage(fileName0);
BufferedImage buff0 = media.openImage(fileName0);
BufferedImage buff1 = media.openImage(fileName1);
BufferedImage buff1 = media.openImage(fileName1);


ImageFloat32 full = new ImageFloat32(buff0.getWidth(),buff0.getHeight());
GrayF32 full = new GrayF32(buff0.getWidth(), buff0.getHeight());


// Dense optical flow is very computationally expensive. Just process the image at 1/2 resolution
// Dense optical flow is very computationally expensive. Just process the image at 1/2 resolution
ImageFloat32 previous = new ImageFloat32(full.width/2,full.height/2);
GrayF32 previous = new GrayF32(full.width/2, full.height/2);
ImageFloat32 current = new ImageFloat32(previous.width,previous.height);
GrayF32 current = previous.createSameShape();
ImageFlow flow = new ImageFlow(previous.width,previous.height);
ImageFlow flow = new ImageFlow(previous.width, previous.height);


ConvertBufferedImage.convertFrom(buff0,full);
ConvertBufferedImage.convertFrom(buff0, full);
DistortImageOps.scale(full, previous, TypeInterpolate.BILINEAR);
new FDistort(full, previous).scaleExt().apply();
ConvertBufferedImage.convertFrom(buff1, full);
ConvertBufferedImage.convertFrom(buff1, full);
DistortImageOps.scale(full,current, TypeInterpolate.BILINEAR);
new FDistort(full, current).scaleExt().apply();


// compute dense motion
// compute dense motion
Line 66: Line 63:


// Visualize the results
// Visualize the results
PanelGridPanel gui = new PanelGridPanel(1,2);
PanelGridPanel gui = new PanelGridPanel(1, 2);


BufferedImage converted0 = new BufferedImage(current.width,current.height,BufferedImage.TYPE_INT_RGB);
BufferedImage converted0 = new BufferedImage(current.width, current.height, BufferedImage.TYPE_INT_RGB);
BufferedImage converted1 = new BufferedImage(current.width,current.height,BufferedImage.TYPE_INT_RGB);
BufferedImage converted1 = new BufferedImage(current.width, current.height, BufferedImage.TYPE_INT_RGB);
BufferedImage visualized = new BufferedImage(current.width,current.height,BufferedImage.TYPE_INT_RGB);
BufferedImage visualized = new BufferedImage(current.width, current.height, BufferedImage.TYPE_INT_RGB);


ConvertBufferedImage.convertTo(previous, converted0, true);
ConvertBufferedImage.convertTo(previous, converted0, true);
Line 76: Line 73:
VisualizeOpticalFlow.colorized(flow, 10, visualized);
VisualizeOpticalFlow.colorized(flow, 10, visualized);


AnimatePanel animate = new AnimatePanel(150,converted0,converted1);
AnimatePanel animate = new AnimatePanel(150, converted0, converted1);
gui.add(animate);
gui.add(animate);
gui.add(visualized);
gui.add(visualized);
animate.start();
animate.start();


ShowImages.showWindow(gui,"Dense Optical Flow");
ShowImages.showWindow(gui, "Dense Optical Flow", true);
}
}
}
}
</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 09:41, 12 July 2021

Dense optical flow compares two images to estimate the apparent motion of each pixel in the one of the images. It is used in video compression, object detection, object tracking, and image segmentation. Dense optical flow is a computationally expensive operation and many techniques use hardware acceleration.

Example Code:

Concepts:

  • Optical Flow

Example Code

/**
 * Demonstration of how to compute the dense optical flow between two images. Dense optical flow of an image
 * describes how each pixel moves from one image to the next. The results is visualized in a color image. The
 * color indicates the direction of motion and the intensity the magnitude.
 *
 * @author Peter Abeles
 */
public class ExampleDenseOpticalFlow {

	public static void main( String[] args ) {
		MediaManager media = DefaultMediaManager.INSTANCE;

//		String fileName0 = UtilIO.pathExample("denseflow/dogdance07.png");
//		String fileName1 = UtilIO.pathExample("denseflow/dogdance08.png");

		String fileName0 = UtilIO.pathExample("denseflow/Urban2_07.png");
		String fileName1 = UtilIO.pathExample("denseflow/Urban2_08.png");

//		String fileName0 = UtilIO.pathExample("denseflow/Grove2_07.png");
//		String fileName1 = UtilIO.pathExample("denseflow/Grove2_09.png");

		DenseOpticalFlow<GrayF32> denseFlow =
//				FactoryDenseOpticalFlow.flowKlt(null, 6, GrayF32.class, null);
//				FactoryDenseOpticalFlow.region(null,GrayF32.class);
//				FactoryDenseOpticalFlow.hornSchunck(20, 1000, GrayF32.class);
//				FactoryDenseOpticalFlow.hornSchunckPyramid(null,GrayF32.class);
				FactoryDenseOpticalFlow.broxWarping(null, GrayF32.class);

		BufferedImage buff0 = media.openImage(fileName0);
		BufferedImage buff1 = media.openImage(fileName1);

		GrayF32 full = new GrayF32(buff0.getWidth(), buff0.getHeight());

		// Dense optical flow is very computationally expensive. Just process the image at 1/2 resolution
		GrayF32 previous = new GrayF32(full.width/2, full.height/2);
		GrayF32 current = previous.createSameShape();
		ImageFlow flow = new ImageFlow(previous.width, previous.height);

		ConvertBufferedImage.convertFrom(buff0, full);
		new FDistort(full, previous).scaleExt().apply();
		ConvertBufferedImage.convertFrom(buff1, full);
		new FDistort(full, current).scaleExt().apply();

		// compute dense motion
		denseFlow.process(previous, current, flow);

		// Visualize the results
		PanelGridPanel gui = new PanelGridPanel(1, 2);

		BufferedImage converted0 = new BufferedImage(current.width, current.height, BufferedImage.TYPE_INT_RGB);
		BufferedImage converted1 = new BufferedImage(current.width, current.height, BufferedImage.TYPE_INT_RGB);
		BufferedImage visualized = new BufferedImage(current.width, current.height, BufferedImage.TYPE_INT_RGB);

		ConvertBufferedImage.convertTo(previous, converted0, true);
		ConvertBufferedImage.convertTo(current, converted1, true);
		VisualizeOpticalFlow.colorized(flow, 10, visualized);

		AnimatePanel animate = new AnimatePanel(150, converted0, converted1);
		gui.add(animate);
		gui.add(visualized);
		animate.start();

		ShowImages.showWindow(gui, "Dense Optical Flow", true);
	}
}