Search in sources :

Example 1 with EllipseRotated_F64

use of georegression.struct.curve.EllipseRotated_F64 in project BoofCV by lessthanoptimal.

the class ShapeFittingOps method fitEllipse_F64.

/**
 * Computes the best fit ellipse based on minimizing Euclidean distance.  An estimate is initially provided
 * using algebraic algorithm which is then refined using non-linear optimization.  The amount of non-linear
 * optimization can be controlled using 'iterations' parameter.  Will work with partial and complete contours
 * of objects.
 *
 * <p>NOTE: To improve speed, make calls directly to classes in Georegression.  Look at the code for details.</p>
 *
 * @param points (Input) Set of unordered points. Not modified.
 * @param iterations Number of iterations used to refine the fit. If set to zero then an algebraic solution
 *                   is returned.
 * @param computeError If true it will compute the average Euclidean distance error
 * @param outputStorage (Output/Optional) Storage for the ellipse.  Can be null.
 * @return Found ellipse.
 */
public static FitData<EllipseRotated_F64> fitEllipse_F64(List<Point2D_F64> points, int iterations, boolean computeError, FitData<EllipseRotated_F64> outputStorage) {
    if (outputStorage == null) {
        outputStorage = new FitData<>(new EllipseRotated_F64());
    }
    // Compute the optimal algebraic error
    FitEllipseAlgebraic_F64 algebraic = new FitEllipseAlgebraic_F64();
    if (!algebraic.process(points)) {
        // could be a line or some other weird case. Create a crude estimate instead
        FitData<Circle2D_F64> circleData = averageCircle_F64(points, null, null);
        Circle2D_F64 circle = circleData.shape;
        outputStorage.shape.set(circle.center.x, circle.center.y, circle.radius, circle.radius, 0);
    } else {
        UtilEllipse_F64.convert(algebraic.getEllipse(), outputStorage.shape);
    }
    // Improve the solution from algebraic into Euclidean
    if (iterations > 0) {
        RefineEllipseEuclideanLeastSquares_F64 leastSquares = new RefineEllipseEuclideanLeastSquares_F64();
        leastSquares.setMaxIterations(iterations);
        leastSquares.refine(outputStorage.shape, points);
        outputStorage.shape.set(leastSquares.getFound());
    }
    // compute the average Euclidean error if the user requests it
    if (computeError) {
        ClosestPointEllipseAngle_F64 closestPoint = new ClosestPointEllipseAngle_F64(1e-8, 100);
        closestPoint.setEllipse(outputStorage.shape);
        double total = 0;
        for (Point2D_F64 p : points) {
            closestPoint.process(p);
            total += p.distance(closestPoint.getClosest());
        }
        outputStorage.error = total / points.size();
    } else {
        outputStorage.error = 0;
    }
    return outputStorage;
}
Also used : Circle2D_F64(georegression.struct.trig.Circle2D_F64) EllipseRotated_F64(georegression.struct.curve.EllipseRotated_F64) Point2D_F64(georegression.struct.point.Point2D_F64) RefineEllipseEuclideanLeastSquares_F64(georegression.fitting.curves.RefineEllipseEuclideanLeastSquares_F64) FitEllipseAlgebraic_F64(georegression.fitting.curves.FitEllipseAlgebraic_F64) ClosestPointEllipseAngle_F64(georegression.fitting.curves.ClosestPointEllipseAngle_F64)

Example 2 with EllipseRotated_F64

use of georegression.struct.curve.EllipseRotated_F64 in project BoofCV by lessthanoptimal.

the class CommonDetectCalibrationApp method renderShapes.

protected void renderShapes(Graphics2D g2, double scale) {
    List<Polygon2D_F64> squares = getFoundPolygons();
    for (int i = 0; i < squares.size(); i++) {
        Polygon2D_F64 p = squares.get(i);
        // if (isInGrids(p)) TODO fix broken method isInGrids
        // continue;
        g2.setColor(Color.cyan);
        g2.setStroke(new BasicStroke(4));
        drawPolygon(p, g2, scale);
        g2.setColor(Color.blue);
        g2.setStroke(new BasicStroke(2));
        drawPolygon(p, g2, scale);
        drawCornersInside(g2, scale, p);
    }
    List<EllipseRotated_F64> ellipses = getFoundEllipses();
    AffineTransform rotate = new AffineTransform();
    for (int i = 0; i < ellipses.size(); i++) {
        EllipseRotated_F64 ellipse = ellipses.get(i);
        rotate.setToIdentity();
        rotate.rotate(ellipse.phi);
        double w = scale * ellipse.a * 2;
        double h = scale * ellipse.b * 2;
        Shape shape = rotate.createTransformedShape(new Ellipse2D.Double(-w / 2, -h / 2, w, h));
        shape = AffineTransform.getTranslateInstance(scale * ellipse.center.x, scale * ellipse.center.y).createTransformedShape(shape);
        g2.setColor(Color.cyan);
        g2.setStroke(new BasicStroke(4));
        g2.draw(shape);
        g2.setColor(Color.blue);
        g2.setStroke(new BasicStroke(2));
        g2.draw(shape);
    }
}
Also used : EllipseRotated_F64(georegression.struct.curve.EllipseRotated_F64) AffineTransform(java.awt.geom.AffineTransform) Polygon2D_F64(georegression.struct.shapes.Polygon2D_F64) Ellipse2D(java.awt.geom.Ellipse2D)

Example 3 with EllipseRotated_F64

use of georegression.struct.curve.EllipseRotated_F64 in project BoofCV by lessthanoptimal.

the class DetectCalibrationCircleHexagonalApp method renderGrid.

@Override
protected void renderGrid(Graphics2D g2, double scale) {
    List<Grid> grids = detector.getDetector().getGrider().getGrids().toList();
    BasicStroke thin = new BasicStroke(3);
    BasicStroke thick = new BasicStroke(5);
    for (Grid g : grids) {
        double x0 = Double.MAX_VALUE;
        double x1 = -Double.MAX_VALUE;
        double y0 = Double.MAX_VALUE;
        double y1 = -Double.MAX_VALUE;
        for (int i = 0; i < g.ellipses.size(); i++) {
            EllipseRotated_F64 e = g.ellipses.get(i);
            if (e == null)
                continue;
            x0 = Math.min(e.center.x, x0);
            x1 = Math.max(e.center.x, x1);
            y0 = Math.min(e.center.y, y0);
            y1 = Math.max(e.center.y, y1);
        }
        x0 *= scale;
        y0 *= scale;
        x1 *= scale;
        y1 *= scale;
        g2.setColor(Color.WHITE);
        g2.setStroke(thick);
        VisualizeShapes.drawRectangle(x0, y0, x1, y1, line, g2);
        g2.setColor(Color.ORANGE);
        g2.setStroke(thin);
        VisualizeShapes.drawRectangle(x0, y0, x1, y1, line, g2);
    }
    renderTangents(g2, scale);
}
Also used : EllipseRotated_F64(georegression.struct.curve.EllipseRotated_F64) ConfigCircleHexagonalGrid(boofcv.abst.fiducial.calib.ConfigCircleHexagonalGrid) CalibrationDetectorCircleHexagonalGrid(boofcv.abst.fiducial.calib.CalibrationDetectorCircleHexagonalGrid) SquareGrid(boofcv.alg.fiducial.calib.squares.SquareGrid) Grid(boofcv.alg.fiducial.calib.circle.EllipseClustersIntoGrid.Grid)

Example 4 with EllipseRotated_F64

use of georegression.struct.curve.EllipseRotated_F64 in project BoofCV by lessthanoptimal.

the class DetectCalibrationCircleHexagonalApp method renderClusters.

@Override
protected void renderClusters(Graphics2D g2, double scale) {
    List<EllipseRotated_F64> found = detector.getDetector().getEllipseDetector().getFoundEllipses(null);
    List<List<EllipsesIntoClusters.Node>> clusters = detector.getDetector().getClusters();
    g2.setStroke(new BasicStroke(2));
    int id = 0;
    for (List<EllipsesIntoClusters.Node> c : clusters) {
        g2.setColor(colorId[Math.min(id++, colorId.length - 1)]);
        for (EllipsesIntoClusters.Node n : c) {
            EllipseRotated_F64 a = found.get(n.which);
            line.x1 = scale * a.center.x;
            line.y1 = scale * a.center.y;
            for (int i = 0; i < n.connections.size; i++) {
                EllipseRotated_F64 b = found.get(n.connections.get(i));
                line.x2 = scale * b.center.x;
                line.y2 = scale * b.center.y;
                g2.draw(line);
            }
        }
    }
}
Also used : EllipseRotated_F64(georegression.struct.curve.EllipseRotated_F64) SquareNode(boofcv.alg.fiducial.calib.squares.SquareNode) EllipsesIntoClusters(boofcv.alg.fiducial.calib.circle.EllipsesIntoClusters) ArrayList(java.util.ArrayList) List(java.util.List)

Example 5 with EllipseRotated_F64

use of georegression.struct.curve.EllipseRotated_F64 in project BoofCV by lessthanoptimal.

the class DetectCalibrationCircleRegularApp method renderClusters.

@Override
protected void renderClusters(Graphics2D g2, double scale) {
    List<BinaryEllipseDetector.EllipseInfo> found = detector.getDetector().getEllipseDetector().getFound().toList();
    List<List<EllipsesIntoClusters.Node>> clusters = detector.getDetector().getClusters();
    g2.setStroke(new BasicStroke(2));
    int id = 0;
    for (List<EllipsesIntoClusters.Node> c : clusters) {
        g2.setColor(colorId[Math.min(id++, colorId.length - 1)]);
        for (EllipsesIntoClusters.Node n : c) {
            EllipseRotated_F64 a = found.get(n.which).ellipse;
            line.x1 = a.center.x * scale;
            line.y1 = a.center.y * scale;
            for (int i = 0; i < n.connections.size; i++) {
                EllipseRotated_F64 b = found.get(n.connections.get(i)).ellipse;
                line.x2 = b.center.x * scale;
                line.y2 = b.center.y * scale;
                g2.draw(line);
            }
        }
    }
}
Also used : EllipseRotated_F64(georegression.struct.curve.EllipseRotated_F64) SquareNode(boofcv.alg.fiducial.calib.squares.SquareNode) EllipsesIntoClusters(boofcv.alg.fiducial.calib.circle.EllipsesIntoClusters) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

EllipseRotated_F64 (georegression.struct.curve.EllipseRotated_F64)62 ArrayList (java.util.ArrayList)34 Test (org.junit.Test)25 Grid (boofcv.alg.fiducial.calib.circle.EllipseClustersIntoGrid.Grid)18 GrayU8 (boofcv.struct.image.GrayU8)15 Point2D_F64 (georegression.struct.point.Point2D_F64)9 List (java.util.List)9 NodeInfo (boofcv.alg.fiducial.calib.circle.EllipseClustersIntoGrid.NodeInfo)5 Node (boofcv.alg.fiducial.calib.circle.EllipsesIntoClusters.Node)5 EllipsesIntoClusters (boofcv.alg.fiducial.calib.circle.EllipsesIntoClusters)2 TestDetectCircleHexagonalGrid.createGrid (boofcv.alg.fiducial.calib.circle.TestDetectCircleHexagonalGrid.createGrid)2 SquareGrid (boofcv.alg.fiducial.calib.squares.SquareGrid)2 SquareNode (boofcv.alg.fiducial.calib.squares.SquareNode)2 EllipseInfo (boofcv.alg.shapes.ellipse.BinaryEllipseDetector.EllipseInfo)2 ConvertBufferedImage (boofcv.io.image.ConvertBufferedImage)2 Vector3D_F64 (georegression.struct.point.Vector3D_F64)2 AffineTransform (java.awt.geom.AffineTransform)2 BufferedImage (java.awt.image.BufferedImage)2 CalibrationDetectorCircleHexagonalGrid (boofcv.abst.fiducial.calib.CalibrationDetectorCircleHexagonalGrid)1 CalibrationDetectorCircleRegularGrid (boofcv.abst.fiducial.calib.CalibrationDetectorCircleRegularGrid)1