Difference between revisions of "Example Detect Corners"

From BoofCV
Jump to navigationJump to search
m
m
Line 8: Line 8:


Example Code:
Example Code:
* [https://github.com/lessthanoptimal/BoofCV/blob/v0.37/examples/src/boofcv/examples/features/ExampleCornerFeature.java ExampleCornerFeature.java]
* [https://github.com/lessthanoptimal/BoofCV/blob/v0.38/examples/src/boofcv/examples/features/ExampleCornerFeature.java ExampleCornerFeature.java]


Concepts:
Concepts:
Line 24: Line 24:
  */
  */
public class ExampleCornerFeature {
public class ExampleCornerFeature {
public static void main(String[] args) {
public static void main( String[] args ) {
ConfigGeneralDetector configNonMax = new ConfigGeneralDetector();
ConfigGeneralDetector configNonMax = new ConfigGeneralDetector();
// a large radius is used to exaggerate weighted/unweighted affects. Try 1 or 2 for a typical value
// a large radius is used to exaggerate weighted/unweighted affects. Try 1 or 2 for a typical value
Line 35: Line 35:


// set weighted to false and see what happens to the feature's locations. unweighted is much faster
// set weighted to false and see what happens to the feature's locations. unweighted is much faster
GeneralFeatureDetector<GrayU8,GrayS16> detector = FactoryDetectPoint.createShiTomasi(configNonMax,configCorner, GrayS16.class);
GeneralFeatureDetector<GrayU8, GrayS16> detector = FactoryDetectPoint.createShiTomasi(configNonMax, configCorner, GrayS16.class);
ImageGradient<GrayU8, GrayS16> sobel = FactoryDerivative.sobel(GrayU8.class,GrayS16.class);
ImageGradient<GrayU8, GrayS16> sobel = FactoryDerivative.sobel(GrayU8.class, GrayS16.class);


BufferedImage image = UtilImageIO.loadImage(UtilIO.pathExample("calibration/mono/Sony_DSC-HX5V_Chess/frame05.jpg"));
BufferedImage image = UtilImageIO.loadImage(UtilIO.pathExample("calibration/mono/Sony_DSC-HX5V_Chess/frame05.jpg"));


// Convert the image into a usable format and predeclare memory
// Convert the image into a usable format and predeclare memory
GrayU8 gray = ConvertBufferedImage.convertFrom(image,(GrayU8)null);
GrayU8 gray = ConvertBufferedImage.convertFrom(image, (GrayU8)null);
GrayS16 derivX = new GrayS16(gray.width,gray.height);
GrayS16 derivX = new GrayS16(gray.width, gray.height);
GrayS16 derivY = new GrayS16(gray.width,gray.height);
GrayS16 derivY = new GrayS16(gray.width, gray.height);


// The first image derivatives are needed
// The first image derivatives are needed
sobel.process(gray, derivX,derivY);
sobel.process(gray, derivX, derivY);


// Compute the corners
// Compute the corners
detector.process(gray,derivX,derivY,null,null,null);
detector.process(gray, derivX, derivY, null, null, null);


// Visualize the results
// Visualize the results
Line 56: Line 56:
for (int i = 0; i < corners.size; i++) {
for (int i = 0; i < corners.size; i++) {
Point2D_I16 c = corners.get(i);
Point2D_I16 c = corners.get(i);
VisualizeFeatures.drawPoint(g2,c.x,c.y,4,Color.RED,true);
VisualizeFeatures.drawPoint(g2, c.x, c.y, 4, Color.RED, true);
}
}


ShowImages.showWindow(image,"Corners",true);
ShowImages.showWindow(image, "Corners", true);
}
}
}
}
</syntaxhighlight>
</syntaxhighlight>

Revision as of 10:38, 12 July 2021

Corner features and other point features (e.g. Laplacian) are commonly used in SFM and 2D geometric applications. Perhaps the most well known corner feature is Shi-Tomasi (a.k.a. Good Features) and Harris corner features.

Example Code:

Concepts:

  • Image Features
  • SFM

Example Code

/**
 * Example showing how corner features can be detected. These features are not scale invariant, but are
 * fast to compute. In OpenCV Shi-Tomasi has the name of goodFeaturesToTrack and uses the unweighted variant.
 *
 * @author Peter Abeles
 */
public class ExampleCornerFeature {
	public static void main( String[] args ) {
		ConfigGeneralDetector configNonMax = new ConfigGeneralDetector();
		// a large radius is used to exaggerate weighted/unweighted affects. Try 1 or 2 for a typical value
		configNonMax.radius = 10;
		configNonMax.threshold = 100;
		configNonMax.maxFeatures = 100;
		ConfigShiTomasi configCorner = new ConfigShiTomasi();
		configCorner.radius = configNonMax.radius; // in general you should use the same radius here
		configCorner.weighted = true;              // weighted corners will appear at the corners on a chessboard

		// set weighted to false and see what happens to the feature's locations. unweighted is much faster
		GeneralFeatureDetector<GrayU8, GrayS16> detector = FactoryDetectPoint.createShiTomasi(configNonMax, configCorner, GrayS16.class);
		ImageGradient<GrayU8, GrayS16> sobel = FactoryDerivative.sobel(GrayU8.class, GrayS16.class);

		BufferedImage image = UtilImageIO.loadImage(UtilIO.pathExample("calibration/mono/Sony_DSC-HX5V_Chess/frame05.jpg"));

		// Convert the image into a usable format and predeclare memory
		GrayU8 gray = ConvertBufferedImage.convertFrom(image, (GrayU8)null);
		GrayS16 derivX = new GrayS16(gray.width, gray.height);
		GrayS16 derivY = new GrayS16(gray.width, gray.height);

		// The first image derivatives are needed
		sobel.process(gray, derivX, derivY);

		// Compute the corners
		detector.process(gray, derivX, derivY, null, null, null);

		// Visualize the results
		QueueCorner corners = detector.getMaximums();
		Graphics2D g2 = image.createGraphics();
		for (int i = 0; i < corners.size; i++) {
			Point2D_I16 c = corners.get(i);
			VisualizeFeatures.drawPoint(g2, c.x, c.y, 4, Color.RED, true);
		}

		ShowImages.showWindow(image, "Corners", true);
	}
}