Difference between revisions of "Example Detect Black Ellipses"
From BoofCV
Jump to navigationJump to searchm |
m |
||
(5 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
Example Code: | Example Code: | ||
* [https://github.com/lessthanoptimal/BoofCV/blob/v0. | * [https://github.com/lessthanoptimal/BoofCV/blob/v0.40/examples/src/main/java/boofcv/examples/features/ExampleDetectBlackEllipse.java ExampleDetectBlackEllipse.java] | ||
Concepts: | Concepts: | ||
Line 11: | Line 11: | ||
* Fiducials | * Fiducials | ||
Related Examples | Related Examples: | ||
* [[Example_Detect_Black_Polygons|Black Polygons]] | * [[Example_Detect_Black_Polygons|Black Polygons]] | ||
* [[Example_Detect_Calibration_Target| Calibration Target]] | * [[Example_Detect_Calibration_Target| Calibration Target]] | ||
Videos: | |||
* [https://youtu.be/qMTtdiujAtQ?t=513 Ellipse Detector] | |||
= Example Code = | = Example Code = | ||
Line 19: | Line 22: | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
/** | /** | ||
* Example of how to detect black ellipses with a white background inside of images. | * Example of how to detect black ellipses with a white background inside of images. These ellipses will have a | ||
* high level of accuracy and are used in camera calibration else where. | * high level of accuracy and are used in camera calibration else where. | ||
* | * | ||
Line 25: | Line 28: | ||
*/ | */ | ||
public class ExampleDetectBlackEllipse { | public class ExampleDetectBlackEllipse { | ||
public static void main(String[] args) { | public static void main( String[] args ) { | ||
String | String[] images = new String[]{ | ||
"shapes/polygons01.jpg", | "shapes/polygons01.jpg", | ||
"shapes/shapes02.png", | "shapes/shapes02.png", | ||
"fiducial/ | "fiducial/circle_hexagonal/image00.jpg", | ||
"fiducial/ | "fiducial/circle_hexagonal/image01.jpg"}; | ||
ListDisplayPanel panel = new ListDisplayPanel(); | ListDisplayPanel panel = new ListDisplayPanel(); | ||
Line 36: | Line 39: | ||
BinaryEllipseDetector<GrayU8> detector = FactoryShapeDetector.ellipse(null, GrayU8.class); | BinaryEllipseDetector<GrayU8> detector = FactoryShapeDetector.ellipse(null, GrayU8.class); | ||
for( String fileName : images ) { | for (String fileName : images) { | ||
BufferedImage image = UtilImageIO. | BufferedImage image = UtilImageIO.loadImageNotNull(UtilIO.pathExample(fileName)); | ||
GrayU8 input = ConvertBufferedImage.convertFromSingle(image, null, GrayU8.class); | GrayU8 input = ConvertBufferedImage.convertFromSingle(image, null, GrayU8.class); | ||
GrayU8 binary = new GrayU8(input.width,input.height); | GrayU8 binary = new GrayU8(input.width, input.height); | ||
// Binarization is done outside to allows creative tricks. | // Binarization is done outside to allows creative tricks. For example, when applied to a chessboard | ||
// pattern where square touch each other, the binary image is eroded first so that they don't touch. | // pattern where square touch each other, the binary image is eroded first so that they don't touch. | ||
// The squares are expanded automatically during the subpixel optimization step. | // The squares are expanded automatically during the subpixel optimization step. | ||
int threshold = GThresholdImageOps.computeOtsu(input, 0, 255); | int threshold = (int)GThresholdImageOps.computeOtsu(input, 0, 255); | ||
ThresholdImageOps.threshold(input, binary, threshold, true); | ThresholdImageOps.threshold(input, binary, threshold, true); | ||
Line 54: | Line 57: | ||
// visualize results by drawing red polygons | // visualize results by drawing red polygons | ||
DogArray<BinaryEllipseDetector.EllipseInfo> found = detector.getFound(); | |||
Graphics2D g2 = image.createGraphics(); | Graphics2D g2 = image.createGraphics(); | ||
g2.setStroke(new BasicStroke( | g2.setStroke(new BasicStroke(5)); | ||
g2.setColor(Color.RED); | g2.setColor(Color.RED); | ||
for (int i = 0; i < found.size; i++) { | for (int i = 0; i < found.size; i++) { | ||
VisualizeShapes.drawEllipse(found.get(i), g2); | VisualizeShapes.drawEllipse(found.get(i).ellipse, g2); | ||
} | } | ||
panel.addImage(image,new File(fileName).getName()); | panel.addImage(image, new File(fileName).getName()); | ||
} | } | ||
ShowImages.showWindow(panel,"Detected Ellipses",true); | ShowImages.showWindow(panel, "Detected Ellipses", true); | ||
} | } | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> |
Latest revision as of 12:55, 17 January 2022
BinaryEllipseDetector will detect ellipses inside an image which are black to a high level of precision quickly. Detection is done inside a binary image with subpixel refinement inside a gray scale image. These ellipses are used by ellipses based calibration targets
Example Code:
Concepts:
- Ellipses
- Fiducials
Related Examples:
Videos:
Example Code
/**
* Example of how to detect black ellipses with a white background inside of images. These ellipses will have a
* high level of accuracy and are used in camera calibration else where.
*
* @author Peter Abeles
*/
public class ExampleDetectBlackEllipse {
public static void main( String[] args ) {
String[] images = new String[]{
"shapes/polygons01.jpg",
"shapes/shapes02.png",
"fiducial/circle_hexagonal/image00.jpg",
"fiducial/circle_hexagonal/image01.jpg"};
ListDisplayPanel panel = new ListDisplayPanel();
BinaryEllipseDetector<GrayU8> detector = FactoryShapeDetector.ellipse(null, GrayU8.class);
for (String fileName : images) {
BufferedImage image = UtilImageIO.loadImageNotNull(UtilIO.pathExample(fileName));
GrayU8 input = ConvertBufferedImage.convertFromSingle(image, null, GrayU8.class);
GrayU8 binary = new GrayU8(input.width, input.height);
// Binarization is done outside to allows creative tricks. For example, when applied to a chessboard
// pattern where square touch each other, the binary image is eroded first so that they don't touch.
// The squares are expanded automatically during the subpixel optimization step.
int threshold = (int)GThresholdImageOps.computeOtsu(input, 0, 255);
ThresholdImageOps.threshold(input, binary, threshold, true);
// it takes in a grey scale image and binary image
// the binary image is used to do a crude polygon fit, then the grey image is used to refine the lines
// using a sub-pixel algorithm
detector.process(input, binary);
// visualize results by drawing red polygons
DogArray<BinaryEllipseDetector.EllipseInfo> found = detector.getFound();
Graphics2D g2 = image.createGraphics();
g2.setStroke(new BasicStroke(5));
g2.setColor(Color.RED);
for (int i = 0; i < found.size; i++) {
VisualizeShapes.drawEllipse(found.get(i).ellipse, g2);
}
panel.addImage(image, new File(fileName).getName());
}
ShowImages.showWindow(panel, "Detected Ellipses", true);
}
}