Search in sources :

Example 1 with Polygon2D_F64

use of georegression.struct.shapes.Polygon2D_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 2 with Polygon2D_F64

use of georegression.struct.shapes.Polygon2D_F64 in project BoofCV by lessthanoptimal.

the class BaseDetectFiducialSquare method process.

/**
 * Examines the input image to detect fiducials inside of it
 *
 * @param gray Undistorted input image
 */
public void process(T gray) {
    configureContourDetector(gray);
    binary.reshape(gray.width, gray.height);
    inputToBinary.process(gray, binary);
    squareDetector.process(gray, binary);
    squareDetector.refineAll();
    // These are in undistorted pixels
    squareDetector.getPolygons(candidates, candidatesInfo);
    found.reset();
    if (verbose)
        System.out.println("---------- Got Polygons! " + candidates.size());
    for (int i = 0; i < candidates.size(); i++) {
        // compute the homography from the input image to an undistorted square image
        Polygon2D_F64 p = candidates.get(i);
        // sanity check before processing
        if (!checkSideSize(p)) {
            if (verbose)
                System.out.println("  rejected side aspect ratio or size");
            continue;
        }
        // REMOVE EVENTUALLY  This is a hack around how interpolation is performed
        // Using a surface integral instead would remove the need for this.  Basically by having it start
        // interpolating from the lower extent it samples inside the image more
        // A good unit test to see if this hack is no longer needed is to rotate the order of the polygon and
        // see if it returns the same undistorted image each time
        double best = Double.MAX_VALUE;
        for (int j = 0; j < 4; j++) {
            double found = p.get(0).normSq();
            if (found < best) {
                best = found;
                interpolationHack.set(p);
            }
            UtilPolygons2D_F64.shiftDown(p);
        }
        UtilPolygons2D_F64.convert(interpolationHack, q);
        // remember, visual clockwise isn't the same as math clockwise, hence
        // counter clockwise visual to the clockwise quad
        pairsRemovePerspective.get(0).set(0, 0, q.a.x, q.a.y);
        pairsRemovePerspective.get(1).set(square.width, 0, q.b.x, q.b.y);
        pairsRemovePerspective.get(2).set(square.width, square.height, q.c.x, q.c.y);
        pairsRemovePerspective.get(3).set(0, square.height, q.d.x, q.d.y);
        if (!computeHomography.process(pairsRemovePerspective, H)) {
            if (verbose)
                System.out.println("  rejected initial homography");
            continue;
        }
        // refine homography estimate
        if (!refineHomography.fitModel(pairsRemovePerspective, H, H_refined)) {
            if (verbose)
                System.out.println("  rejected refine homography");
            continue;
        }
        // pass the found homography onto the image transform
        ConvertDMatrixStruct.convert(H_refined, H_fixed);
        ConvertFloatType.convert(H_fixed, transformHomography.getModel());
        // TODO Improve how perspective is removed
        // The current method introduces artifacts.  If the "square" is larger
        // than the detected region and bilinear interpolation is used then pixels outside will// influence the
        // value of pixels inside and shift things over.  this is all bad
        // remove the perspective distortion and process it
        removePerspective.apply(gray, square);
        DetectPolygonFromContour.Info info = candidatesInfo.get(i);
        // see if the black border is actually black
        if (minimumBorderBlackFraction > 0) {
            double pixelThreshold = (info.edgeInside + info.edgeOutside) / 2;
            double foundFraction = computeFractionBoundary((float) pixelThreshold);
            if (foundFraction < minimumBorderBlackFraction) {
                if (verbose)
                    System.out.println("  rejected black border fraction " + foundFraction);
                continue;
            }
        }
        if (processSquare(square, result, info.edgeInside, info.edgeOutside)) {
            prepareForOutput(q, result);
            if (verbose)
                System.out.println("  accepted!");
        } else {
            if (verbose)
                System.out.println("  rejected process square");
        }
    }
}
Also used : DetectPolygonFromContour(boofcv.alg.shapes.polygon.DetectPolygonFromContour) Polygon2D_F64(georegression.struct.shapes.Polygon2D_F64)

Example 3 with Polygon2D_F64

use of georegression.struct.shapes.Polygon2D_F64 in project BoofCV by lessthanoptimal.

the class TextureGrayTrackerObjectRectangleTests method convexFill.

public static void convexFill(Polygon2D_I32 poly, GrayU8 image, double value) {
    int minX = Integer.MAX_VALUE;
    int maxX = Integer.MIN_VALUE;
    int minY = Integer.MAX_VALUE;
    int maxY = Integer.MIN_VALUE;
    for (int i = 0; i < poly.size(); i++) {
        Point2D_I32 p = poly.vertexes.data[i];
        if (p.y < minY) {
            minY = p.y;
        } else if (p.y > maxY) {
            maxY = p.y;
        }
        if (p.x < minX) {
            minX = p.x;
        } else if (p.x > maxX) {
            maxX = p.x;
        }
    }
    ImageRectangle bounds = new ImageRectangle(minX, minY, maxX, maxY);
    BoofMiscOps.boundRectangleInside(image, bounds);
    Point2D_F64 p = new Point2D_F64();
    Polygon2D_F64 poly64 = new Polygon2D_F64(4);
    for (int i = 0; i < 4; i++) poly64.vertexes.data[i].set(poly.vertexes.data[i].x, poly.vertexes.data[i].y);
    for (int y = bounds.y0; y < bounds.y1; y++) {
        p.y = y;
        for (int x = bounds.x0; x < bounds.x1; x++) {
            p.x = x;
            if (Intersection2D_F64.containConvex(poly64, p)) {
                GeneralizedImageOps.set(image, x, y, value);
            }
        }
    }
}
Also used : Point2D_F64(georegression.struct.point.Point2D_F64) Point2D_I32(georegression.struct.point.Point2D_I32) ImageRectangle(boofcv.struct.ImageRectangle) Polygon2D_F64(georegression.struct.shapes.Polygon2D_F64)

Example 4 with Polygon2D_F64

use of georegression.struct.shapes.Polygon2D_F64 in project BoofCV by lessthanoptimal.

the class TestChessboardPolygonHelper method filterPixelPolygon_AllBorder.

@Test
public void filterPixelPolygon_AllBorder() {
    ChessboardPolygonHelper alg = new ChessboardPolygonHelper();
    Polygon2D_F64 distorted = new Polygon2D_F64(3);
    GrowQueue_B touches = new GrowQueue_B();
    touches.add(false);
    touches.add(false);
    touches.add(false);
    // nothing is actually touching the border, should be valid
    assertTrue(alg.filterPixelPolygon(null, distorted, touches, true));
    touches.set(0, true);
    touches.set(1, true);
    touches.set(2, true);
    assertFalse(alg.filterPixelPolygon(null, distorted, touches, true));
}
Also used : Polygon2D_F64(georegression.struct.shapes.Polygon2D_F64) GrowQueue_B(org.ddogleg.struct.GrowQueue_B) Test(org.junit.Test)

Example 5 with Polygon2D_F64

use of georegression.struct.shapes.Polygon2D_F64 in project BoofCV by lessthanoptimal.

the class TestChessboardPolygonHelper method filterPixelPolygon_border.

@Test
public void filterPixelPolygon_border() {
    ChessboardPolygonHelper alg = new ChessboardPolygonHelper();
    Polygon2D_F64 distorted = new Polygon2D_F64(2);
    GrowQueue_B touches = new GrowQueue_B();
    // test initially with all corners inside
    touches.add(false);
    touches.add(false);
    assertFalse(alg.filterPixelPolygon(null, distorted, touches, true));
    distorted.vertexes.resize(3);
    touches.add(false);
    assertTrue(alg.filterPixelPolygon(null, distorted, touches, true));
    distorted.vertexes.resize(3);
    touches.add(false);
    assertTrue(alg.filterPixelPolygon(null, distorted, touches, true));
    // these should all fail because there are too many corners inside not touching the border
    for (int i = 0; i < 3; i++) {
        distorted.vertexes.resize(4 + i + 1);
        touches.add(false);
        assertFalse(alg.filterPixelPolygon(null, distorted, touches, true));
    }
    // this should pass because only 1 or 3 corners are inside
    for (int i = 0; i < touches.size(); i++) {
        touches.set(i, true);
    }
    for (int i = 0; i < 3; i++) {
        touches.set(i, false);
        assertTrue(alg.filterPixelPolygon(null, distorted, touches, true));
    }
}
Also used : Polygon2D_F64(georegression.struct.shapes.Polygon2D_F64) GrowQueue_B(org.ddogleg.struct.GrowQueue_B) Test(org.junit.Test)

Aggregations

Polygon2D_F64 (georegression.struct.shapes.Polygon2D_F64)79 Test (org.junit.Test)40 Point2D_F64 (georegression.struct.point.Point2D_F64)13 ArrayList (java.util.ArrayList)9 GrayU8 (boofcv.struct.image.GrayU8)6 Rectangle2D_I32 (georegression.struct.shapes.Rectangle2D_I32)6 ConvertBufferedImage (boofcv.io.image.ConvertBufferedImage)5 BufferedImage (java.awt.image.BufferedImage)5 GrowQueue_B (org.ddogleg.struct.GrowQueue_B)5 Point2D_I32 (georegression.struct.point.Point2D_I32)4 PixelTransformAffine_F32 (boofcv.alg.distort.PixelTransformAffine_F32)3 DetectPolygonFromContour (boofcv.alg.shapes.polygon.DetectPolygonFromContour)3 GrayF32 (boofcv.struct.image.GrayF32)3 Affine2D_F32 (georegression.struct.affine.Affine2D_F32)3 Se3_F64 (georegression.struct.se.Se3_F64)3 Rectangle2D_F64 (georegression.struct.shapes.Rectangle2D_F64)3 File (java.io.File)3 LensDistortionNarrowFOV (boofcv.alg.distort.LensDistortionNarrowFOV)2 LensDistortionRadialTangential (boofcv.alg.distort.radtan.LensDistortionRadialTangential)2 SquareNode (boofcv.alg.fiducial.calib.squares.SquareNode)2