Example SURF Feature

From BoofCV
Revision as of 06:44, 5 December 2012 by Peter (talk | contribs)
Jump to navigationJump to search

Computing SURF Features

Speeded Up Robust Feature (SURF) is a region descriptor and interest point detector. Two different ways of using SURF are demonstrated in this example. The easy way uses a high level interface that is easy to work with, but sacrifices flexibility. The harder way directly creates the SURF classes, is more complex, and requires a better understanding of how the code works.

Example File: ExampleFeatureSurf.java

Concepts:

  • SURF
  • Region Descriptor
  • Interest Point

Relevant Applets:

Example Code

/**
 * Example of how to use SURF detector and descriptors in BoofCV. 
 * 
 * @author Peter Abeles
 */
public class ExampleFeatureSurf {

	/**
	 * Use generalized interfaces for working with SURF.  Removed much of the drugery, but also reduces
	 * your ability to customize your code.
	 * 
	 *  @param image Input image type. DOES NOT NEED TO BE ImageFloat32, ImageUInt8 works too
	 */
	public static void easy( ImageFloat32 image ) {
		// create the detector and descriptors
		DetectDescribePoint<ImageFloat32,SurfFeature>
				surf = FactoryDetectDescribe.surf(0, 2, 200, 2, 9, 4, 4, true, ImageFloat32.class);

		 // specify the image to process
		surf.detect(image);

		System.out.println("Found Features: "+surf.getNumberOfFeatures());
		System.out.println("First descriptor's first value: "+surf.getDescriptor(0).value[0]);
	}

	/**
	 * Configured exactly the same as the easy example above, but require a lot more code and a more in depth
	 * understanding of how SURF works and is configured.
	 * 
	 * @param image Input image type. DOES NOT NEED TO BE ImageFloat32, ImageUInt8 works too
	 */
	public static <II extends ImageSingleBand> void harder( ImageFloat32 image ) {
		// SURF works off of integral images
		Class<II> integralType = GIntegralImageOps.getIntegralType(ImageFloat32.class);
		
		// define the feature detection algorithm
		FeatureExtractor extractor = FactoryFeatureExtractor.nonmax(2, 0, 5, true);
		FastHessianFeatureDetector<II> detector = 
				new FastHessianFeatureDetector<II>(extractor,200,2, 9,4,4);

		// estimate orientation
		OrientationIntegral<II> orientation =
				FactoryOrientationAlgs.sliding_ii(0.65, Math.PI / 3.0, 8, -1, 6, integralType);

		DescribePointSurf<II> descriptor = FactoryDescribePointAlgs.<II>msurf(integralType);
		
		// compute the integral image of 'image'
		II integral = GeneralizedImageOps.createSingleBand(integralType,image.width,image.height);
		GIntegralImageOps.transform(image, integral);

		// detect fast hessian features
		detector.detect(integral);
		// tell algorithms which image to process
		orientation.setImage(integral);
		descriptor.setImage(integral);

		List<ScalePoint> points = detector.getFoundPoints();

		List<SurfFeature> descriptions = new ArrayList<SurfFeature>();

		for( ScalePoint p : points ) {
			// estimate orientation
			orientation.setScale(p.scale);
			double angle = orientation.compute(p.x,p.y);
			
			// extract the SURF description for this region
			SurfFeature desc = descriptor.createDescription();
			descriptor.describe(p.x,p.y,angle,p.scale,desc);

			// save everything for processing later on
			descriptions.add(desc);
		}
		
		System.out.println("Found Features: "+points.size());
		System.out.println("First descriptor's first value: "+descriptions.get(0).value[0]);
	}

	public static void main( String args[] ) {
		
		ImageFloat32 image = UtilImageIO.loadImage("../data/evaluation/particles01.jpg",ImageFloat32.class);
		
		// run each example
		ExampleFeatureSurf.easy(image);
		ExampleFeatureSurf.harder(image);
		
		System.out.println("Done!");
		
	}
}