Difference between revisions of "Example Detect Corners"
From BoofCV
Jump to navigationJump to searchm |
m |
||
Line 8: | Line 8: | ||
Example Code: | Example Code: | ||
* [https://github.com/lessthanoptimal/BoofCV/blob/v0. | * [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 09: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);
}
}