Difference between revisions of "Example Image Pyramid"
m |
(Added float pyramid code and updated text) |
||
Line 9: | Line 9: | ||
[http://en.wikipedia.org/wiki/Pyramid_%28image_processing Image pyramids] are a common way to represent multi-resolution image information. In an image pyramid, upper layers are lower resolution versions of the lower layers. BoofCV provides two types of image pyramids built in; PyramidDiscrete and PyramidFloat. PyramidDiscrete only allows the ratio between adjacent to have positive integer values, while PyramidFloat allows any arbitrary positive value. Discrete pyramids are much faster than float pyramids, but much more restrictive. | [http://en.wikipedia.org/wiki/Pyramid_%28image_processing Image pyramids] are a common way to represent multi-resolution image information. In an image pyramid, upper layers are lower resolution versions of the lower layers. BoofCV provides two types of image pyramids built in; PyramidDiscrete and PyramidFloat. PyramidDiscrete only allows the ratio between adjacent to have positive integer values, while PyramidFloat allows any arbitrary positive value. Discrete pyramids are much faster than float pyramids, but much more restrictive. | ||
Two code examples are provided below which demonstrate how to | Inside of BoofCV several algorithms make use of these two types of pyramids. The KLT feature tracker uses a discrete pyramid and is the fastest feature tracker. Pyramid based scale space feature detectors use the float pyramid. | ||
Two code examples are provided below which demonstrate how to construct and visualize each type of pyramid. | |||
Example Code: | Example Code: | ||
* [https://github.com/lessthanoptimal/BoofCV/blob/master/examples/src/boofcv/examples/ExamplePyramidDiscrete.java ExamplePyramidDiscrete.java ] | * [https://github.com/lessthanoptimal/BoofCV/blob/master/examples/src/boofcv/examples/ExamplePyramidDiscrete.java ExamplePyramidDiscrete.java ] | ||
* | * [https://github.com/lessthanoptimal/BoofCV/blob/master/examples/src/boofcv/examples/ExamplePyramidFloat.java ExamplePyramidFloat.java ] | ||
Concepts: | Concepts: | ||
Line 23: | Line 25: | ||
* [[Applet_Pyramid_Discrete| Discrete Pyramid]] | * [[Applet_Pyramid_Discrete| Discrete Pyramid]] | ||
* [[Applet_Pyramid_Float| Float Pyramid]] | * [[Applet_Pyramid_Float| Float Pyramid]] | ||
= Image Pyramid Discrete = | = Image Pyramid Discrete = | ||
Line 108: | Line 108: | ||
= Image Pyramid Float = | = Image Pyramid Float = | ||
<syntaxhighlight lang="java"> | |||
/** | |||
* Demonstrates how to construct and display a {@link PyramidFloat}. Float pyramids require only require | |||
* that each layer's scale be larger than the scale of the previous layer. Interpolation is used to allow | |||
* sub-sampling at arbitrary scales. All of this additional flexibility comes at the cost of speed | |||
* when compared to a {@link PyramidDiscrete}. | |||
* | |||
* @author Peter Abeles | |||
*/ | |||
public class ExamplePyramidFloat<T extends ImageBase> { | |||
// specifies the image type | |||
Class<T> imageType; | |||
// The pyramid data structure | |||
PyramidFloat<T> pyramid; | |||
// update the pyramid given from | |||
PyramidUpdaterFloat<T> updater; | |||
public ExamplePyramidFloat(Class<T> imageType) { | |||
this.imageType = imageType; | |||
} | |||
/** | |||
* Creates a fairly standard pyramid and updater. | |||
*/ | |||
public void standard() { | |||
// Scale factory for each layer can be any floating point value which is larger than | |||
// the previous layer's scale. | |||
pyramid = new PyramidFloat<T>(imageType,1,1.5,2,2.5,3,5,8,15); | |||
// Specify the amount of blur to apply to each scale | |||
// Using a custom updater other types of blur and interpolation can be applied | |||
updater = FactoryPyramid.floatGaussian(imageType, 1,1,1,1,1,1,1,1); | |||
} | |||
/** | |||
* Updates and displays the pyramid. | |||
*/ | |||
public void process( BufferedImage image ) { | |||
T input = ConvertBufferedImage.convertFrom(image,null,imageType); | |||
updater.update(input,pyramid); | |||
ImagePyramidPanel<T> gui = new ImagePyramidPanel<T>(); | |||
gui.set(pyramid, true); | |||
gui.render(); | |||
ShowImages.showWindow(gui,"Image Pyramid Float"); | |||
} | |||
public static void main( String[] args ) { | |||
BufferedImage image = UtilImageIO.loadImage("data/standard/barbara.png"); | |||
ExamplePyramidFloat<ImageFloat32> app = new ExamplePyramidFloat<ImageFloat32>(ImageFloat32.class); | |||
// ExamplePyramidFloat<ImageUInt8> app = new ExamplePyramidFloat<ImageUInt8>(ImageUInt8.class); | |||
app.standard(); | |||
app.process(image); | |||
} | |||
} | |||
</syntaxhighlight> |
Revision as of 11:12, 16 November 2011
Image Pyramid Example
Image pyramids are a common way to represent multi-resolution image information. In an image pyramid, upper layers are lower resolution versions of the lower layers. BoofCV provides two types of image pyramids built in; PyramidDiscrete and PyramidFloat. PyramidDiscrete only allows the ratio between adjacent to have positive integer values, while PyramidFloat allows any arbitrary positive value. Discrete pyramids are much faster than float pyramids, but much more restrictive.
Inside of BoofCV several algorithms make use of these two types of pyramids. The KLT feature tracker uses a discrete pyramid and is the fastest feature tracker. Pyramid based scale space feature detectors use the float pyramid.
Two code examples are provided below which demonstrate how to construct and visualize each type of pyramid.
Example Code:
Concepts:
- Multi-resolution image processing
- Discrete Vs. Float pyramids
- Image scaling
Relevant Applets:
Image Pyramid Discrete
/**
* Demonstrates how to construct and display a {@link PyramidDiscrete}. Discrete pyramids require that
* each level has a relative scale with an integer ratio and is updated by sparsely sub-sampling. These
* restrictions allows a very quick update across scale space.
*
* @author Peter Abeles
*/
public class ExamplePyramidDiscrete<T extends ImageBase> {
// specifies the image type
Class<T> imageType;
// The pyramid data structure
PyramidDiscrete<T> pyramid;
// update the pyramid given from
PyramidUpdaterDiscrete<T> updater;
public ExamplePyramidDiscrete(Class<T> imageType) {
this.imageType = imageType;
}
/**
* Creates a fairly standard pyramid and updater.
*/
public void standard() {
// Each level in the pyramid must have a ratio with the previously layer that is an integer value
pyramid = new PyramidDiscrete<T>(imageType,true,1,2,4,8);
// In most cases sub-sampling with a Gaussian is preferred
updater = FactoryPyramid.discreteGaussian(imageType,-1,2);
}
/**
* Creates a more unusual pyramid and updater.
*/
public void unusual() {
// Note that the first level does not have to be one
pyramid = new PyramidDiscrete<T>(imageType,true,2,6);
// Other kernels can also be used besides Gaussian
Kernel1D kernel;
if(GeneralizedImageOps.isFloatingPoint(imageType) ) {
kernel = FactoryKernel.table1D_F32(2,true);
} else {
kernel = FactoryKernel.table1D_I32(2);
}
updater = new PyramidUpdateIntegerDown<T>(kernel,imageType);
}
/**
* Updates and displays the pyramid.
*/
public void process( BufferedImage image ) {
T input = ConvertBufferedImage.convertFrom(image,null,imageType);
updater.update(input,pyramid);
DiscretePyramidPanel gui = new DiscretePyramidPanel();
gui.setPyramid(pyramid);
gui.render();
ShowImages.showWindow(gui,"Image Pyramid");
}
public static void main( String[] args ) {
BufferedImage image = UtilImageIO.loadImage("data/standard/barbara.png");
ExamplePyramidDiscrete<ImageFloat32> app = new ExamplePyramidDiscrete<ImageFloat32>(ImageFloat32.class);
// ExamplePyramidDiscrete<ImageUInt8> app = new ExamplePyramidDiscrete<ImageUInt8>(ImageUInt8.class);
app.standard();
// app.unusual();
app.process(image);
}
}
Image Pyramid Float
/**
* Demonstrates how to construct and display a {@link PyramidFloat}. Float pyramids require only require
* that each layer's scale be larger than the scale of the previous layer. Interpolation is used to allow
* sub-sampling at arbitrary scales. All of this additional flexibility comes at the cost of speed
* when compared to a {@link PyramidDiscrete}.
*
* @author Peter Abeles
*/
public class ExamplePyramidFloat<T extends ImageBase> {
// specifies the image type
Class<T> imageType;
// The pyramid data structure
PyramidFloat<T> pyramid;
// update the pyramid given from
PyramidUpdaterFloat<T> updater;
public ExamplePyramidFloat(Class<T> imageType) {
this.imageType = imageType;
}
/**
* Creates a fairly standard pyramid and updater.
*/
public void standard() {
// Scale factory for each layer can be any floating point value which is larger than
// the previous layer's scale.
pyramid = new PyramidFloat<T>(imageType,1,1.5,2,2.5,3,5,8,15);
// Specify the amount of blur to apply to each scale
// Using a custom updater other types of blur and interpolation can be applied
updater = FactoryPyramid.floatGaussian(imageType, 1,1,1,1,1,1,1,1);
}
/**
* Updates and displays the pyramid.
*/
public void process( BufferedImage image ) {
T input = ConvertBufferedImage.convertFrom(image,null,imageType);
updater.update(input,pyramid);
ImagePyramidPanel<T> gui = new ImagePyramidPanel<T>();
gui.set(pyramid, true);
gui.render();
ShowImages.showWindow(gui,"Image Pyramid Float");
}
public static void main( String[] args ) {
BufferedImage image = UtilImageIO.loadImage("data/standard/barbara.png");
ExamplePyramidFloat<ImageFloat32> app = new ExamplePyramidFloat<ImageFloat32>(ImageFloat32.class);
// ExamplePyramidFloat<ImageUInt8> app = new ExamplePyramidFloat<ImageUInt8>(ImageUInt8.class);
app.standard();
app.process(image);
}
}