Search in sources :

Example 26 with Point2D_F64

use of georegression.struct.point.Point2D_F64 in project BoofCV by lessthanoptimal.

the class AdjustPolygonForThresholdBias method process.

/**
 * Processes and adjusts the polygon
 *
 * @param polygon The polygon that is to be adjusted. Modified.
 * @param clockwise Is the polygon in a lockwise orientation?
 */
public void process(Polygon2D_F64 polygon, boolean clockwise) {
    int N = polygon.size();
    segments.resize(N);
    // Apply the adjustment independently to each side
    for (int i = N - 1, j = 0; j < N; i = j, j++) {
        int ii, jj;
        if (clockwise) {
            ii = i;
            jj = j;
        } else {
            ii = j;
            jj = i;
        }
        Point2D_F64 a = polygon.get(ii), b = polygon.get(jj);
        double dx = b.x - a.x;
        double dy = b.y - a.y;
        double l = Math.sqrt(dx * dx + dy * dy);
        // only needs to be shifted in two directions
        if (dx < 0)
            dx = 0;
        if (dy > 0)
            dy = 0;
        LineSegment2D_F64 s = segments.get(ii);
        s.a.x = a.x - dy / l;
        s.a.y = a.y + dx / l;
        s.b.x = b.x - dy / l;
        s.b.y = b.y + dx / l;
    }
    // Find the intersection between the adjusted lines to convert it back into polygon format
    for (int i = N - 1, j = 0; j < N; i = j, j++) {
        int ii, jj;
        if (clockwise) {
            ii = i;
            jj = j;
        } else {
            ii = j;
            jj = i;
        }
        UtilLine2D_F64.convert(segments.get(ii), ga);
        UtilLine2D_F64.convert(segments.get(jj), gb);
        if (null != Intersection2D_F64.intersection(ga, gb, intersection)) {
            // very acute angles can cause a large delta. This is conservative and prevents that
            if (intersection.distance2(polygon.get(jj)) < 20) {
                polygon.get(jj).set(intersection);
            }
        }
    }
}
Also used : LineSegment2D_F64(georegression.struct.line.LineSegment2D_F64) Point2D_F64(georegression.struct.point.Point2D_F64)

Example 27 with Point2D_F64

use of georegression.struct.point.Point2D_F64 in project BoofCV by lessthanoptimal.

the class RefinePolygonToGrayLine method checkShapeTooSmall.

/**
 * Looks at the distance between each vertex.  If that distance is so small the edge can't be measured the
 * return true.
 * @param input polygon
 * @return true if too small or false if not
 */
private boolean checkShapeTooSmall(Polygon2D_F64 input) {
    // must be longer than the border plus some small fudge factor
    double minLength = cornerOffset * 2 + 2;
    for (int i = 0; i < input.size(); i++) {
        int j = (i + 1) % input.size();
        Point2D_F64 a = input.get(i);
        Point2D_F64 b = input.get(j);
        if (a.distance2(b) < minLength * minLength)
            return true;
    }
    return false;
}
Also used : Point2D_F64(georegression.struct.point.Point2D_F64)

Example 28 with Point2D_F64

use of georegression.struct.point.Point2D_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 29 with Point2D_F64

use of georegression.struct.point.Point2D_F64 in project BoofCV by lessthanoptimal.

the class EdgeIntensityPolygon method computeEdge.

/**
 * Checks to see if its a valid polygon or a false positive by looking at edge intensity
 *
 * @param polygon The polygon being tested
 * @param ccw True if the polygon is counter clockwise
 * @return true if it could compute the edge intensity, otherwise false
 */
public boolean computeEdge(Polygon2D_F64 polygon, boolean ccw) {
    averageInside = 0;
    averageOutside = 0;
    double tangentSign = ccw ? 1 : -1;
    int totalSides = 0;
    for (int i = polygon.size() - 1, j = 0; j < polygon.size(); i = j, j++) {
        Point2D_F64 a = polygon.get(i);
        Point2D_F64 b = polygon.get(j);
        double dx = b.x - a.x;
        double dy = b.y - a.y;
        double t = Math.sqrt(dx * dx + dy * dy);
        dx /= t;
        dy /= t;
        // see if the side is too small
        if (t < 3 * cornerOffset) {
            offsetA.set(a);
            offsetB.set(b);
        } else {
            offsetA.x = a.x + cornerOffset * dx;
            offsetA.y = a.y + cornerOffset * dy;
            offsetB.x = b.x - cornerOffset * dx;
            offsetB.y = b.y - cornerOffset * dy;
        }
        double tanX = -dy * tangentDistance * tangentSign;
        double tanY = dx * tangentDistance * tangentSign;
        scorer.computeAverageDerivative(offsetA, offsetB, tanX, tanY);
        if (scorer.getSamplesInside() > 0) {
            totalSides++;
            averageInside += scorer.getAverageUp() / tangentDistance;
            averageOutside += scorer.getAverageDown() / tangentDistance;
        }
    }
    if (totalSides > 0) {
        averageInside /= totalSides;
        averageOutside /= totalSides;
    } else {
        averageInside = averageOutside = 0;
        return false;
    }
    return true;
}
Also used : Point2D_F64(georegression.struct.point.Point2D_F64)

Example 30 with Point2D_F64

use of georegression.struct.point.Point2D_F64 in project BoofCV by lessthanoptimal.

the class TestNarrowToWidePtoP_F64 method rotateCamera.

/**
 * Rotate the camera and see if the point moves in the expected way
 */
@Test
public void rotateCamera() {
    NarrowToWidePtoP_F64 alg = createAlg();
    Point2D_F64 found = new Point2D_F64();
    DMatrixRMaj R = ConvertRotation3D_F64.eulerToMatrix(EulerType.YXZ, 0.1, 0, 0, null);
    alg.setRotationWideToNarrow(R);
    alg.compute(250, 250, found);
    assertTrue(480 < found.x - 5);
    R = ConvertRotation3D_F64.eulerToMatrix(EulerType.YXZ, -0.1, 0, 0, null);
    alg.setRotationWideToNarrow(R);
    alg.compute(250, 250, found);
    assertTrue(480 > found.x + 5);
    R = ConvertRotation3D_F64.eulerToMatrix(EulerType.YXZ, 0, -0.1, 0, null);
    alg.setRotationWideToNarrow(R);
    alg.compute(250, 250, found);
    assertTrue(480 < found.y - 5);
    R = ConvertRotation3D_F64.eulerToMatrix(EulerType.YXZ, 0, 0.1, 0, null);
    alg.setRotationWideToNarrow(R);
    alg.compute(250, 250, found);
    assertTrue(480 > found.y + 5);
}
Also used : Point2D_F64(georegression.struct.point.Point2D_F64) DMatrixRMaj(org.ejml.data.DMatrixRMaj) Test(org.junit.Test)

Aggregations

Point2D_F64 (georegression.struct.point.Point2D_F64)360 Test (org.junit.Test)129 Point3D_F64 (georegression.struct.point.Point3D_F64)85 Se3_F64 (georegression.struct.se.Se3_F64)68 ArrayList (java.util.ArrayList)57 DMatrixRMaj (org.ejml.data.DMatrixRMaj)48 AssociatedPair (boofcv.struct.geo.AssociatedPair)28 CameraPinholeRadial (boofcv.struct.calib.CameraPinholeRadial)16 Point2Transform2_F64 (boofcv.struct.distort.Point2Transform2_F64)15 GrayF32 (boofcv.struct.image.GrayF32)13 Vector3D_F64 (georegression.struct.point.Vector3D_F64)13 Polygon2D_F64 (georegression.struct.shapes.Polygon2D_F64)13 Point2D3D (boofcv.struct.geo.Point2D3D)11 GrayU8 (boofcv.struct.image.GrayU8)11 Point2D_I32 (georegression.struct.point.Point2D_I32)11 AssociatedIndex (boofcv.struct.feature.AssociatedIndex)10 EllipseRotated_F64 (georegression.struct.curve.EllipseRotated_F64)9 DescribeRegionPoint (boofcv.abst.feature.describe.DescribeRegionPoint)8 ConvertBufferedImage (boofcv.io.image.ConvertBufferedImage)8 BufferedImage (java.awt.image.BufferedImage)8