Example Convolution

From BoofCV
Revision as of 08:13, 9 November 2015 by Peter (talk | contribs)
Jump to navigationJump to search

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

Example Code

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

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

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

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

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

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

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

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

	/**
	 * Convolves a 2D kernel
	 */
	private static void convolve2D(ImageUInt8 gray) {
		// By default 2D kernels will be centered around width/2
		Kernel2D_I32 kernel = new Kernel2D_I32(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
		ImageSInt16 output = new ImageSInt16(gray.width,gray.height);
		ImageBorder<ImageUInt8> border = FactoryImageBorder.single(gray, BorderType.EXTENDED);

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

	/**
	 * Convolves a 2D normalized kernel.  This kernel is divided by its sum after computation.
	 */
	private static void normalize2D(ImageUInt8 gray) {
		// Create a Gaussian kernel with radius of 3
		Kernel2D_I32 kernel = FactoryKernelGaussian.gaussian2D(ImageUInt8.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
		ImageUInt8 output = new ImageUInt8(gray.width,gray.height);

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