Difference between revisions of "Example Convolution"

From BoofCV
Jump to navigationJump to search
(Created page with "Example of how to convolve 1D and 2D convolution kernels across an image. Besides providing the kernel, how the border is handled needs to be specified. A normalized kernel...")
 
m
(4 intermediate revisions by the same user not shown)
Line 2: Line 2:


Example Code:
Example Code:
* [https://github.com/lessthanoptimal/BoofCV/blob/v0.18/examples/src/boofcv/examples/imageprocessing/ExampleConvolution.java ExampleConvolution.java]
* [https://github.com/lessthanoptimal/BoofCV/blob/v0.27/examples/src/boofcv/examples/imageprocessing/ExampleConvolution.java ExampleConvolution.java]


Concepts:
Concepts:
* Convolution
* Convolution
* Spacial filtering
* Spacial filtering
Relevant Examples:
* [[Example_Image_Blur|Image Blur]]


= Example Code =
= Example Code =
Line 17: Line 20:
  */
  */
public class ExampleConvolution {
public class ExampleConvolution {
private static ListDisplayPanel panel = new ListDisplayPanel();


public static void main(String[] args) {
public static void main(String[] args) {
BufferedImage image = UtilImageIO.loadImage("../data/applet/sunflowers.jpg");
BufferedImage image = UtilImageIO.loadImage(UtilIO.pathExample("sunflowers.jpg"));


ImageUInt8 gray = ConvertBufferedImage.convertFromSingle(image, null, ImageUInt8.class);
GrayU8 gray = ConvertBufferedImage.convertFromSingle(image, null, GrayU8.class);


convolve1D(gray);
convolve1D(gray);
convolve2D(gray);
convolve2D(gray);
normalize2D(gray);
normalize2D(gray);
ShowImages.showWindow(panel,"Convolution Examples",true);
}
}


Line 31: Line 38:
* Convolves a 1D kernel horizontally and vertically
* Convolves a 1D kernel horizontally and vertically
*/
*/
private static void convolve1D(ImageUInt8 gray) {
private static void convolve1D(GrayU8 gray) {
ImageBorder<ImageUInt8> border = FactoryImageBorder.general(gray, BorderType.EXTENDED);
ImageBorder<GrayU8> border = FactoryImageBorder.wrap(BorderType.EXTENDED, gray);
Kernel1D_I32 kernel = new Kernel1D_I32(2);
Kernel1D_S32 kernel = new Kernel1D_S32(2);
kernel.offset = 1; // specify the kernel's origin
kernel.offset = 1; // specify the kernel's origin
kernel.data[0] = 1;
kernel.data[0] = 1;
kernel.data[1] = -1;
kernel.data[1] = -1;


ImageSInt16 output = new ImageSInt16(gray.width,gray.height);
GrayS16 output = new GrayS16(gray.width,gray.height);


GConvolveImageOps.horizontal(kernel, gray, output, border);
GConvolveImageOps.horizontal(kernel, gray, output, border);
ShowImages.showWindow(VisualizeImageData.standard(output, null), "1D Horizontal");
panel.addImage(VisualizeImageData.standard(output, null), "1D Horizontal");


GConvolveImageOps.vertical(kernel, gray, output, border);
GConvolveImageOps.vertical(kernel, gray, output, border);
ShowImages.showWindow(VisualizeImageData.standard(output, null), "1D Vertical");
panel.addImage(VisualizeImageData.standard(output, null), "1D Vertical");
}
}


Line 50: Line 57:
* Convolves a 2D kernel
* Convolves a 2D kernel
*/
*/
private static void convolve2D(ImageUInt8 gray) {
private static void convolve2D(GrayU8 gray) {
// By default 2D kernels will be centered around width/2
// By default 2D kernels will be centered around width/2
Kernel2D_I32 kernel = new Kernel2D_I32(3);
Kernel2D_S32 kernel = new Kernel2D_S32(3);
kernel.set(1,0,2);
kernel.set(1,0,2);
kernel.set(2,1,2);
kernel.set(2,1,2);
Line 59: Line 66:


// Output needs to handle the increased domain after convolution.  Can't be 8bit
// Output needs to handle the increased domain after convolution.  Can't be 8bit
ImageSInt16 output = new ImageSInt16(gray.width,gray.height);
GrayS16 output = new GrayS16(gray.width,gray.height);
ImageBorder<ImageUInt8> border = FactoryImageBorder.general(gray, BorderType.EXTENDED);
ImageBorder<GrayU8> border = FactoryImageBorder.wrap( BorderType.EXTENDED,gray);


GConvolveImageOps.convolve(kernel, gray, output, border);
GConvolveImageOps.convolve(kernel, gray, output, border);
ShowImages.showWindow(VisualizeImageData.standard(output, null), "2D Kernel");
panel.addImage(VisualizeImageData.standard(output, null), "2D Kernel");
}
}


Line 69: Line 76:
* Convolves a 2D normalized kernel.  This kernel is divided by its sum after computation.
* Convolves a 2D normalized kernel.  This kernel is divided by its sum after computation.
*/
*/
private static void normalize2D(ImageUInt8 gray) {
private static void normalize2D(GrayU8 gray) {
// Create a Gaussian kernel with radius of 3
// Create a Gaussian kernel with radius of 3
Kernel2D_I32 kernel = FactoryKernelGaussian.gaussian2D(ImageUInt8.class, -1, 3);
Kernel2D_S32 kernel = FactoryKernelGaussian.gaussian2D(GrayU8.class, -1, 3);
// Note that there is a more efficient way to compute this convolution since it is a separable kernel
// Note that there is a more efficient way to compute this convolution since it is a separable kernel
// just use BlurImageOps instead.
// just use BlurImageOps instead.


// Since it's normalized it can be saved inside an 8bit image
// Since it's normalized it can be saved inside an 8bit image
ImageUInt8 output = new ImageUInt8(gray.width,gray.height);
GrayU8 output = new GrayU8(gray.width,gray.height);


GConvolveImageOps.convolveNormalized(kernel, gray, output);
GConvolveImageOps.convolveNormalized(kernel, gray, output);
ShowImages.showWindow(VisualizeImageData.standard(output, null), "2D Normalized Kernel");
panel.addImage(VisualizeImageData.standard(output, null), "2D Normalized Kernel");
}
}
}
}
</syntaxhighlight>
</syntaxhighlight>

Revision as of 08:55, 17 August 2017

Example of how to convolve 1D and 2D convolution kernels across an image. Besides providing the kernel, how the border is handled needs to be specified. A normalized kernel will renormalize the

Example Code:

Concepts:

  • Convolution
  • Spacial filtering

Relevant Examples:

Example Code

/**
 * Several examples demonstrating convolution.
 *
 * @author Peter Abeles
 */
public class ExampleConvolution {

	private static ListDisplayPanel panel = new ListDisplayPanel();

	public static void main(String[] args) {
		BufferedImage image = UtilImageIO.loadImage(UtilIO.pathExample("sunflowers.jpg"));

		GrayU8 gray = ConvertBufferedImage.convertFromSingle(image, null, GrayU8.class);

		convolve1D(gray);
		convolve2D(gray);
		normalize2D(gray);

		ShowImages.showWindow(panel,"Convolution Examples",true);
	}

	/**
	 * Convolves a 1D kernel horizontally and vertically
	 */
	private static void convolve1D(GrayU8 gray) {
		ImageBorder<GrayU8> border = FactoryImageBorder.wrap(BorderType.EXTENDED, gray);
		Kernel1D_S32 kernel = new Kernel1D_S32(2);
		kernel.offset = 1; // specify the kernel's origin
		kernel.data[0] = 1;
		kernel.data[1] = -1;

		GrayS16 output = new GrayS16(gray.width,gray.height);

		GConvolveImageOps.horizontal(kernel, gray, output, border);
		panel.addImage(VisualizeImageData.standard(output, null), "1D Horizontal");

		GConvolveImageOps.vertical(kernel, gray, output, border);
		panel.addImage(VisualizeImageData.standard(output, null), "1D Vertical");
	}

	/**
	 * Convolves a 2D kernel
	 */
	private static void convolve2D(GrayU8 gray) {
		// By default 2D kernels will be centered around width/2
		Kernel2D_S32 kernel = new Kernel2D_S32(3);
		kernel.set(1,0,2);
		kernel.set(2,1,2);
		kernel.set(0,1,-2);
		kernel.set(1,2,-2);

		// Output needs to handle the increased domain after convolution.  Can't be 8bit
		GrayS16 output = new GrayS16(gray.width,gray.height);
		ImageBorder<GrayU8> border = FactoryImageBorder.wrap( BorderType.EXTENDED,gray);

		GConvolveImageOps.convolve(kernel, gray, output, border);
		panel.addImage(VisualizeImageData.standard(output, null), "2D Kernel");
	}

	/**
	 * Convolves a 2D normalized kernel.  This kernel is divided by its sum after computation.
	 */
	private static void normalize2D(GrayU8 gray) {
		// Create a Gaussian kernel with radius of 3
		Kernel2D_S32 kernel = FactoryKernelGaussian.gaussian2D(GrayU8.class, -1, 3);
		// Note that there is a more efficient way to compute this convolution since it is a separable kernel
		// just use BlurImageOps instead.

		// Since it's normalized it can be saved inside an 8bit image
		GrayU8 output = new GrayU8(gray.width,gray.height);

		GConvolveImageOps.convolveNormalized(kernel, gray, output);
		panel.addImage(VisualizeImageData.standard(output, null), "2D Normalized Kernel");
	}
}