use of boofcv.alg.filter.binary.Contour in project BoofCV by lessthanoptimal.
the class ExampleCannyEdge method main.
public static void main(String[] args) {
BufferedImage image = UtilImageIO.loadImage(UtilIO.pathExample("simple_objects.jpg"));
GrayU8 gray = ConvertBufferedImage.convertFrom(image, (GrayU8) null);
GrayU8 edgeImage = gray.createSameShape();
// Create a canny edge detector which will dynamically compute the threshold based on maximum edge intensity
// It has also been configured to save the trace as a graph. This is the graph created while performing
// hysteresis thresholding.
CannyEdge<GrayU8, GrayS16> canny = FactoryEdgeDetectors.canny(2, true, true, GrayU8.class, GrayS16.class);
// The edge image is actually an optional parameter. If you don't need it just pass in null
canny.process(gray, 0.1f, 0.3f, edgeImage);
// First get the contour created by canny
List<EdgeContour> edgeContours = canny.getContours();
// The 'edgeContours' is a tree graph that can be difficult to process. An alternative is to extract
// the contours from the binary image, which will produce a single loop for each connected cluster of pixels.
// Note that you are only interested in external contours.
List<Contour> contours = BinaryImageOps.contour(edgeImage, ConnectRule.EIGHT, null);
// display the results
BufferedImage visualBinary = VisualizeBinaryData.renderBinary(edgeImage, false, null);
BufferedImage visualCannyContour = VisualizeBinaryData.renderContours(edgeContours, null, gray.width, gray.height, null);
BufferedImage visualEdgeContour = new BufferedImage(gray.width, gray.height, BufferedImage.TYPE_INT_RGB);
VisualizeBinaryData.render(contours, (int[]) null, visualEdgeContour);
ListDisplayPanel panel = new ListDisplayPanel();
panel.addImage(visualBinary, "Binary Edges from Canny");
panel.addImage(visualCannyContour, "Canny Trace Graph");
panel.addImage(visualEdgeContour, "Contour from Canny Binary");
ShowImages.showWindow(panel, "Canny Edge", true);
}
use of boofcv.alg.filter.binary.Contour in project BoofCV by lessthanoptimal.
the class ExampleBinaryOps method main.
public static void main(String[] args) {
// load and convert the image into a usable format
BufferedImage image = UtilImageIO.loadImage(UtilIO.pathExample("particles01.jpg"));
// convert into a usable format
GrayF32 input = ConvertBufferedImage.convertFromSingle(image, null, GrayF32.class);
GrayU8 binary = new GrayU8(input.width, input.height);
GrayS32 label = new GrayS32(input.width, input.height);
// Select a global threshold using Otsu's method.
double threshold = GThresholdImageOps.computeOtsu(input, 0, 255);
// Apply the threshold to create a binary image
ThresholdImageOps.threshold(input, binary, (float) threshold, true);
// remove small blobs through erosion and dilation
// The null in the input indicates that it should internally declare the work image it needs
// this is less efficient, but easier to code.
GrayU8 filtered = BinaryImageOps.erode8(binary, 1, null);
filtered = BinaryImageOps.dilate8(filtered, 1, null);
// Detect blobs inside the image using an 8-connect rule
List<Contour> contours = BinaryImageOps.contour(filtered, ConnectRule.EIGHT, label);
// colors of contours
int colorExternal = 0xFFFFFF;
int colorInternal = 0xFF2020;
// display the results
BufferedImage visualBinary = VisualizeBinaryData.renderBinary(binary, false, null);
BufferedImage visualFiltered = VisualizeBinaryData.renderBinary(filtered, false, null);
BufferedImage visualLabel = VisualizeBinaryData.renderLabeledBG(label, contours.size(), null);
BufferedImage visualContour = VisualizeBinaryData.renderContours(contours, colorExternal, colorInternal, input.width, input.height, null);
ListDisplayPanel panel = new ListDisplayPanel();
panel.addImage(visualBinary, "Binary Original");
panel.addImage(visualFiltered, "Binary Filtered");
panel.addImage(visualLabel, "Labeled Blobs");
panel.addImage(visualContour, "Contours");
ShowImages.showWindow(panel, "Binary Operations", true);
}
use of boofcv.alg.filter.binary.Contour in project BoofCV by lessthanoptimal.
the class ShapeFitContourApp method renderVisuals.
protected void renderVisuals(Graphics2D g2, double scale) {
int activeAlg = controlPanel.getSelectedAlgorithm();
g2.setStroke(new BasicStroke(3));
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (controlPanel.contoursVisible) {
g2.setStroke(new BasicStroke(1));
VisualizeBinaryData.render(contours, null, Color.CYAN, scale, g2);
}
if (activeAlg == 0) {
double cornerPalty = controlPanel.getCornerPenalty();
int minimumSplitPixels = controlPanel.getMinimumSplitPixels();
for (Contour c : contours) {
List<PointIndex_I32> vertexes = ShapeFittingOps.fitPolygon(c.external, true, minimumSplitPixels, cornerPalty);
g2.setColor(Color.RED);
visualizePolygon(g2, scale, vertexes);
for (List<Point2D_I32> internal : c.internal) {
vertexes = ShapeFittingOps.fitPolygon(internal, true, minimumSplitPixels, cornerPalty);
g2.setColor(Color.GREEN);
visualizePolygon(g2, scale, vertexes);
}
}
} else if (activeAlg == 1) {
// Filter small contours since they can generate really wacky ellipses
for (Contour c : contours) {
if (c.external.size() > 10) {
FitData<EllipseRotated_F64> ellipse = ShapeFittingOps.fitEllipse_I32(c.external, 0, false, null);
g2.setColor(Color.RED);
g2.setStroke(new BasicStroke(2.5f));
VisualizeShapes.drawEllipse(ellipse.shape, scale, g2);
}
for (List<Point2D_I32> internal : c.internal) {
if (internal.size() <= 10)
continue;
FitData<EllipseRotated_F64> ellipse = ShapeFittingOps.fitEllipse_I32(internal, 0, false, null);
g2.setColor(Color.GREEN);
g2.setStroke(new BasicStroke(2.5f));
VisualizeShapes.drawEllipse(ellipse.shape, scale, g2);
}
}
}
}
use of boofcv.alg.filter.binary.Contour in project narchy by automenta.
the class ShapeSensor method run.
@Override
public void run() {
long last = now;
now = nar.time();
if (last == ETERNAL)
last = now;
input.update();
if (img == null || img.width != input.width() || img.height != input.height()) {
// img = new GrayF32(input.width(), input.height());
img = new GrayU8(input.width(), input.height());
}
int w = img.width;
int h = img.height;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
img.set(x, y, Math.round(256f * input.brightness(x, y, R, G, B)));
}
}
if (debug) {
if (polyDebug == null)
polyDebug = new BufferedImage(img.width, img.height, BufferedImage.TYPE_INT_RGB);
}
// the mean pixel value is often a reasonable threshold when creating a binary image
int mean = (int) ImageStatistics.mean(img);
// create a binary image by thresholding
ThresholdImageOps.threshold(img, img, mean, true);
// reduce noise with some filtering
GrayU8 filtered = img;
// for (int i = 0; i < 2; i++) {
filtered = BinaryImageOps.dilate8(filtered, 1, null);
filtered = BinaryImageOps.erode8(filtered, 1, null);
// // Fit a polygon to each shape and draw the results
if (debug) {
if (g2 == null) {
g2 = polyDebug.createGraphics();
}
g2.setColor(Color.BLACK);
g2.clearRect(0, 0, polyDebug.getWidth(), polyDebug.getHeight());
} else {
g2 = null;
}
List<Contour> contours = BinaryImageOps.contour(filtered, // ConnectRule.EIGHT,
ConnectRule.FOUR, null);
Grid g = new Grid(id, 12, 8, w, h) {
@Override
public Term line(int ax, int ay, int bx, int by) {
Term l = super.line(ax, ay, bx, by);
if (g2 != null) {
int aax = Math.round(ax * sx);
int aay = Math.round(ay * sy);
int bbx = Math.round(bx * sx);
int bby = Math.round(by * sy);
g2.setColor(Color.GRAY);
g2.setStroke(new BasicStroke(1));
g2.drawLine(Math.round(aax / sx), Math.round(aay / sy), Math.round(bbx / sx), Math.round(bby / sy));
}
return l;
}
};
int k = 0;
for (Contour c : contours) {
// Fit the polygon to the found external contour. Note loop = true
List<PointIndex_I32> outer = ShapeFittingOps.fitPolygon(c.external, true, 100, minimumSideFraction);
if (debug) {
g2.setColor(Color.getHSBColor(k / 10f, 0.8f, 0.8f));
g2.setStroke(new BasicStroke(2));
drawPolygon(outer, true, g2);
// System.out.println(c + ": " + polygon);
}
g.addPoly(k++, outer, true);
// // handle internal contours
// for (List<Point2D_I32> internal : c.internal) {
// List<PointIndex_I32> inner = ShapeFittingOps.fitPolygon(internal, true, splitFraction, minimumSideFraction, 100);
// g2.setColor(Color.getHSBColor(c.id / 10f, 0.8f, 0.4f));
// g2.setStroke(new BasicStroke(2));
// drawPolygon(inner, true, g2);
// g.addPoly(pk, inner, false);
// }
}
g.input(in, last, nar);
if (debug) {
gui.setImageRepaint(polyDebug);
}
}
Aggregations