Difference between revisions of "Example Fit Ellipse"
From BoofCV
Jump to navigationJump to searchm |
m |
||
(5 intermediate revisions by the same user not shown) | |||
Line 8: | Line 8: | ||
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/ExampleFitEllipse.java ExampleFitEllipse.java] | ||
Concepts: | Concepts: | ||
Line 14: | Line 14: | ||
* Best fit shape | * Best fit shape | ||
Relevant | Relevant Examples: | ||
* [[ | * [[Example_Binary_Image| Binary Image Processing]] | ||
* [[ | * [[Example_Fit_Polygon| Polygon Fitting]] | ||
= Example Code = | = Example Code = | ||
Line 27: | Line 27: | ||
*/ | */ | ||
public class ExampleFitEllipse { | public class ExampleFitEllipse { | ||
public static void main( String[] args ) { | |||
public static void main( String | |||
// load and convert the image into a usable format | // load and convert the image into a usable format | ||
BufferedImage image = UtilImageIO. | BufferedImage image = UtilImageIO.loadImageNotNull(UtilIO.pathExample("particles01.jpg")); | ||
GrayF32 input = ConvertBufferedImage.convertFromSingle(image, null, GrayF32.class); | GrayF32 input = ConvertBufferedImage.convertFromSingle(image, null, GrayF32.class); | ||
GrayU8 binary = new GrayU8(input.width,input.height); | GrayU8 binary = new GrayU8(input.width, input.height); | ||
// the mean pixel value is often a reasonable threshold when creating a binary image | // the mean pixel value is often a reasonable threshold when creating a binary image | ||
Line 39: | Line 38: | ||
// create a binary image by thresholding | // create a binary image by thresholding | ||
ThresholdImageOps.threshold(input, binary, (float) mean, true); | ThresholdImageOps.threshold(input, binary, (float)mean, true); | ||
// reduce noise with some filtering | // reduce noise with some filtering | ||
Line 45: | Line 44: | ||
filtered = BinaryImageOps.dilate8(filtered, 1, null); | filtered = BinaryImageOps.dilate8(filtered, 1, null); | ||
// Find | // Find only external contours around each shape. Much faster than if internal + labeled images are considered. | ||
List<Contour> contours = BinaryImageOps. | List<Contour> contours = BinaryImageOps.contourExternal(filtered, ConnectRule.EIGHT); | ||
// Fit an ellipse to each external contour and draw the results | // Fit an ellipse to each external contour and draw the results | ||
Line 53: | Line 52: | ||
g2.setColor(Color.RED); | g2.setColor(Color.RED); | ||
for( Contour c : contours ) { | for (Contour c : contours) { | ||
FitData<EllipseRotated_F64> ellipse = ShapeFittingOps.fitEllipse_I32(c.external,0,false,null); | FitData<EllipseRotated_F64> ellipse = ShapeFittingOps.fitEllipse_I32(c.external, 0, false, null); | ||
VisualizeShapes.drawEllipse(ellipse.shape, g2); | VisualizeShapes.drawEllipse(ellipse.shape, g2); | ||
} | } | ||
// ShowImages.showWindow(VisualizeBinaryData.renderBinary(filtered, false, null),"Binary",true); | // ShowImages.showWindow(VisualizeBinaryData.renderBinary(filtered, false, null),"Binary",true); | ||
ShowImages.showWindow(image,"Ellipses",true); | ShowImages.showWindow(image, "Ellipses", true); | ||
} | } | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> |
Latest revision as of 13:02, 17 January 2022
Fitting ellipses to 2D objects found in images is a common task in industrial and scientific settings. In this example, binary blobs are found inside an image of particles and the best fit ellipses found. In a real application the next step could be to analyze the size distribution of the found ellipses to characterize the particles.
Example Code:
Concepts:
- Object contours/edges
- Best fit shape
Relevant Examples:
Example Code
/**
* Demonstration which fits ellipses to object contours in a binary image.
*
* @author Peter Abeles
*/
public class ExampleFitEllipse {
public static void main( String[] args ) {
// load and convert the image into a usable format
BufferedImage image = UtilImageIO.loadImageNotNull(UtilIO.pathExample("particles01.jpg"));
GrayF32 input = ConvertBufferedImage.convertFromSingle(image, null, GrayF32.class);
GrayU8 binary = new GrayU8(input.width, input.height);
// the mean pixel value is often a reasonable threshold when creating a binary image
double mean = ImageStatistics.mean(input);
// create a binary image by thresholding
ThresholdImageOps.threshold(input, binary, (float)mean, true);
// reduce noise with some filtering
GrayU8 filtered = BinaryImageOps.erode8(binary, 1, null);
filtered = BinaryImageOps.dilate8(filtered, 1, null);
// Find only external contours around each shape. Much faster than if internal + labeled images are considered.
List<Contour> contours = BinaryImageOps.contourExternal(filtered, ConnectRule.EIGHT);
// Fit an ellipse to each external contour and draw the results
Graphics2D g2 = image.createGraphics();
g2.setStroke(new BasicStroke(3));
g2.setColor(Color.RED);
for (Contour c : contours) {
FitData<EllipseRotated_F64> ellipse = ShapeFittingOps.fitEllipse_I32(c.external, 0, false, null);
VisualizeShapes.drawEllipse(ellipse.shape, g2);
}
// ShowImages.showWindow(VisualizeBinaryData.renderBinary(filtered, false, null),"Binary",true);
ShowImages.showWindow(image, "Ellipses", true);
}
}