Difference between revisions of "Example Convolution"
From BoofCV
Jump to navigationJump to searchm  | 
				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.  | * [https://github.com/lessthanoptimal/BoofCV/blob/v0.40/examples/src/main/java/boofcv/examples/imageprocessing/ExampleConvolution.java ExampleConvolution.java]  | ||
Concepts:  | Concepts:  | ||
| Line 21: | Line 21: | ||
public class ExampleConvolution {  | public class ExampleConvolution {  | ||
	private static ListDisplayPanel panel = new ListDisplayPanel();  | 	private static final ListDisplayPanel panel = new ListDisplayPanel();  | ||
	public static void main(String[] args) {  | 	public static void main( String[] args ) {  | ||
		BufferedImage image = UtilImageIO.  | 		BufferedImage image = UtilImageIO.loadImageNotNull(UtilIO.pathExample("sunflowers.jpg"));  | ||
		GrayU8 gray = ConvertBufferedImage.convertFromSingle(image, null, GrayU8.class);  | 		GrayU8 gray = ConvertBufferedImage.convertFromSingle(image, null, GrayU8.class);  | ||
| Line 32: | Line 32: | ||
		normalize2D(gray);  | 		normalize2D(gray);  | ||
		ShowImages.showWindow(panel,"Convolution Examples",true);  | 		ShowImages.showWindow(panel, "Convolution Examples", true);  | ||
	}  | 	}  | ||
| Line 38: | Line 38: | ||
	 * Convolves a 1D kernel horizontally and vertically  | 	 * Convolves a 1D kernel horizontally and vertically  | ||
	 */  | 	 */  | ||
	private static void convolve1D(GrayU8 gray) {  | 	private static void convolve1D( GrayU8 gray ) {  | ||
		var 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;  | ||
		var output = new GrayS16(gray.width, gray.height);  | |||
		GConvolveImageOps.horizontal(kernel, gray, output,   | 		GConvolveImageOps.horizontal(kernel, gray, output, BorderType.EXTENDED);  | ||
		panel.addImage(VisualizeImageData.standard(output, null), "1D Horizontal");  | 		panel.addImage(VisualizeImageData.standard(output, null), "1D Horizontal");  | ||
		GConvolveImageOps.vertical(kernel, gray, output,   | 		GConvolveImageOps.vertical(kernel, gray, output, BorderType.EXTENDED);  | ||
		panel.addImage(VisualizeImageData.standard(output, null), "1D Vertical");  | 		panel.addImage(VisualizeImageData.standard(output, null), "1D Vertical");  | ||
	}  | 	}  | ||
| Line 57: | Line 56: | ||
	 * Convolves a 2D kernel  | 	 * Convolves a 2D kernel  | ||
	 */  | 	 */  | ||
	private static void convolve2D(GrayU8 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  | ||
		var 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);  | ||
		kernel.set(0,1,-2);  | 		kernel.set(0, 1, -2);  | ||
		kernel.set(1,2,-2);  | 		kernel.set(1, 2, -2);  | ||
		// Output needs to handle the increased domain after convolution.   | 		// Output needs to handle the increased domain after convolution. Can't be 8bit  | ||
		var output = new GrayS16(gray.width, gray.height);  | |||
		GConvolveImageOps.convolve(kernel, gray, output,   | 		GConvolveImageOps.convolve(kernel, gray, output, BorderType.EXTENDED);  | ||
		panel.addImage(VisualizeImageData.standard(output, null), "2D Kernel");  | 		panel.addImage(VisualizeImageData.standard(output, null), "2D Kernel");  | ||
	}  | 	}  | ||
	/**  | 	/**  | ||
	 * Convolves a 2D normalized kernel.   | 	 * Convolves a 2D normalized kernel. This kernel is divided by its sum after computation.  | ||
	 */  | 	 */  | ||
	private static void normalize2D(GrayU8 gray) {  | 	private static void normalize2D( GrayU8 gray ) {  | ||
		// Create a Gaussian kernel with radius of 3  | 		// Create a Gaussian kernel with radius of 3  | ||
		Kernel2D_S32 kernel = FactoryKernelGaussian.gaussian2D(GrayU8.class, -1, 3);  | 		Kernel2D_S32 kernel = FactoryKernelGaussian.gaussian2D(GrayU8.class, -1, 3);  | ||
| Line 83: | Line 81: | ||
		// Since it's normalized it can be saved inside an 8bit image  | 		// Since it's normalized it can be saved inside an 8bit image  | ||
		var output = new GrayU8(gray.width, gray.height);  | |||
		GConvolveImageOps.convolveNormalized(kernel, gray, output);  | 		GConvolveImageOps.convolveNormalized(kernel, gray, output);  | ||
Latest revision as of 14:59, 17 January 2022
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 final ListDisplayPanel panel = new ListDisplayPanel();
	public static void main( String[] args ) {
		BufferedImage image = UtilImageIO.loadImageNotNull(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 ) {
		var kernel = new Kernel1D_S32(2);
		kernel.offset = 1; // specify the kernel's origin
		kernel.data[0] = 1;
		kernel.data[1] = -1;
		var output = new GrayS16(gray.width, gray.height);
		GConvolveImageOps.horizontal(kernel, gray, output, BorderType.EXTENDED);
		panel.addImage(VisualizeImageData.standard(output, null), "1D Horizontal");
		GConvolveImageOps.vertical(kernel, gray, output, BorderType.EXTENDED);
		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
		var 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
		var output = new GrayS16(gray.width, gray.height);
		GConvolveImageOps.convolve(kernel, gray, output, BorderType.EXTENDED);
		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
		var output = new GrayU8(gray.width, gray.height);
		GConvolveImageOps.convolveNormalized(kernel, gray, output);
		panel.addImage(VisualizeImageData.standard(output, null), "2D Normalized Kernel");
	}
}