Difference between revisions of "Example Convolution"
From BoofCV
Jump to navigationJump to searchm |
m |
||
Line 2: | Line 2: | ||
Example Code: | Example Code: | ||
* [https://github.com/lessthanoptimal/BoofCV/blob/v0. | * [https://github.com/lessthanoptimal/BoofCV/blob/v0.23/examples/src/boofcv/examples/imageprocessing/ExampleConvolution.java ExampleConvolution.java] | ||
Concepts: | Concepts: | ||
Line 17: | Line 17: | ||
*/ | */ | ||
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(UtilIO.pathExample("sunflowers.jpg")); | BufferedImage image = UtilImageIO.loadImage(UtilIO.pathExample("sunflowers.jpg")); | ||
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 35: | ||
* Convolves a 1D kernel horizontally and vertically | * Convolves a 1D kernel horizontally and vertically | ||
*/ | */ | ||
private static void convolve1D( | private static void convolve1D(GrayU8 gray) { | ||
ImageBorder< | ImageBorder<GrayU8> border = FactoryImageBorder.single(gray, BorderType.EXTENDED); | ||
Kernel1D_I32 kernel = new Kernel1D_I32(2); | Kernel1D_I32 kernel = new Kernel1D_I32(2); | ||
kernel.offset = 1; // specify the kernel's origin | kernel.offset = 1; // specify the kernel's origin | ||
Line 38: | Line 42: | ||
kernel.data[1] = -1; | kernel.data[1] = -1; | ||
GrayS16 output = new GrayS16(gray.width,gray.height); | |||
GConvolveImageOps.horizontal(kernel, gray, output, border); | GConvolveImageOps.horizontal(kernel, gray, output, border); | ||
panel.addImage(VisualizeImageData.standard(output, null), "1D Horizontal"); | |||
GConvolveImageOps.vertical(kernel, gray, output, border); | GConvolveImageOps.vertical(kernel, gray, output, border); | ||
panel.addImage(VisualizeImageData.standard(output, null), "1D Vertical"); | |||
} | } | ||
Line 50: | Line 54: | ||
* Convolves a 2D kernel | * Convolves a 2D kernel | ||
*/ | */ | ||
private static void convolve2D( | 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_I32 kernel = new Kernel2D_I32(3); | ||
Line 59: | Line 63: | ||
// 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 | ||
GrayS16 output = new GrayS16(gray.width,gray.height); | |||
ImageBorder< | ImageBorder<GrayU8> border = FactoryImageBorder.single(gray, BorderType.EXTENDED); | ||
GConvolveImageOps.convolve(kernel, gray, output, border); | GConvolveImageOps.convolve(kernel, gray, output, border); | ||
panel.addImage(VisualizeImageData.standard(output, null), "2D Kernel"); | |||
} | } | ||
Line 69: | Line 73: | ||
* 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( | 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( | Kernel2D_I32 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 | ||
GrayU8 output = new GrayU8(gray.width,gray.height); | |||
GConvolveImageOps.convolveNormalized(kernel, gray, output); | GConvolveImageOps.convolveNormalized(kernel, gray, output); | ||
panel.addImage(VisualizeImageData.standard(output, null), "2D Normalized Kernel"); | |||
} | } | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> |
Revision as of 20:44, 27 March 2016
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 {
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.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;
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_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
GrayS16 output = new GrayS16(gray.width,gray.height);
ImageBorder<GrayU8> border = FactoryImageBorder.single(gray, BorderType.EXTENDED);
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_I32 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");
}
}