Search in sources :

Example 6 with WorldToCameraToPixel

use of boofcv.alg.geo.WorldToCameraToPixel in project BoofCV by lessthanoptimal.

the class TestSimulatePlanarWorld method checkApparentSize.

/**
 * Sees if a box appears to be the correct size using pinhole distortion
 */
@Test
void checkApparentSize() {
    double markerZ = 2;
    double markerWidth = 0.5;
    CameraPinhole pinhole = new CameraPinhole(400, 400, 0, 300, 250, 600, 500);
    GrayF32 marker = new GrayF32(40, 30);
    GImageMiscOps.fill(marker, 255);
    Se3_F64 markerToWorld = eulerXyz(0, 0, markerZ, 0, Math.PI, 0, null);
    SimulatePlanarWorld alg = new SimulatePlanarWorld();
    alg.setCamera(pinhole);
    alg.addSurface(markerToWorld, markerWidth, marker);
    alg.render();
    // Project the points from 3D onto the image and compute the distance the pixels are apart along
    // the x and y axis
    Point2D_F64 p0 = new Point2D_F64();
    Point2D_F64 p1 = new Point2D_F64();
    double ratio = marker.height / (double) marker.width;
    WorldToCameraToPixel w2p = new WorldToCameraToPixel();
    w2p.configure(pinhole, new Se3_F64());
    assertTrue(w2p.transform(new Point3D_F64(-markerWidth / 2, -ratio * markerWidth / 2, markerZ), p0));
    assertTrue(w2p.transform(new Point3D_F64(markerWidth / 2, ratio * markerWidth / 2, markerZ), p1));
    double expectedWidth = p1.x - p0.x;
    double expectedHeight = p1.y - p0.y;
    GrayF32 image = alg.getOutput();
    assertEquals(expectedWidth, findWidth(image, image.height / 2), 1);
    assertEquals(expectedWidth, findWidth(image, image.height / 2 - 10), 1);
    assertEquals(expectedWidth, findWidth(image, image.height / 2 + 10), 1);
    assertEquals(expectedHeight, findHeight(image, image.width / 2), 1);
    assertEquals(expectedHeight, findHeight(image, image.width / 2 - 10), 1);
    assertEquals(expectedHeight, findHeight(image, image.width / 2 + 10), 1);
}
Also used : Point3D_F64(georegression.struct.point.Point3D_F64) GrayF32(boofcv.struct.image.GrayF32) Point2D_F64(georegression.struct.point.Point2D_F64) WorldToCameraToPixel(boofcv.alg.geo.WorldToCameraToPixel) CameraPinhole(boofcv.struct.calib.CameraPinhole) Se3_F64(georegression.struct.se.Se3_F64) Test(org.junit.jupiter.api.Test)

Example 7 with WorldToCameraToPixel

use of boofcv.alg.geo.WorldToCameraToPixel in project BoofCV by lessthanoptimal.

the class TestScaleSceneStructure method createProjectiveScene.

public static SceneObservations createProjectiveScene(SceneStructureMetric scene, long seed) {
    Random rand = new Random(seed);
    scene.initialize(2, 5, 20);
    SceneObservations observations = new SceneObservations();
    observations.initialize(scene.views.size);
    CameraPinhole camera0 = new CameraPinhole(500 + rand.nextDouble() * 10, 510 + rand.nextDouble() * 10, 0, 450, 400, 900, 800);
    // CameraPinhole camera1 = new CameraPinhole(456+rand.nextDouble()*10,510+rand.nextDouble()*10,0,420,410,900,800);
    scene.setCamera(0, false, camera0);
    for (int i = 0; i < scene.views.size; i++) {
        Se3_F64 worldToView = new Se3_F64();
        worldToView.T.x = i * 0.2 + rand.nextGaussian() * 0.1;
        worldToView.T.y = -i * 0.1 + rand.nextGaussian() * 0.1;
        worldToView.T.z = rand.nextGaussian() * 0.05;
        double rotX = rand.nextGaussian() * 0.05;
        double rotY = rand.nextGaussian() * 0.05;
        double rotZ = rand.nextGaussian() * 0.05;
        ConvertRotation3D_F64.eulerToMatrix(EulerType.XYZ, rotX, rotY, rotZ, worldToView.R);
        scene.setView(i, 0, false, worldToView);
    }
    WorldToCameraToPixel w2p = new WorldToCameraToPixel();
    for (int i = 0; i < scene.points.size; i++) {
        // Point in world frame
        Point3D_F64 X = new Point3D_F64(rand.nextGaussian(), rand.nextGaussian(), 3 + rand.nextGaussian());
        if (scene.homogenous) {
            scene.points.data[i].set(X.x, X.y, X.z, 1);
        } else {
            scene.points.data[i].set(X.x, X.y, X.z);
        }
        // Connect the point to views if it's visible inside of
        for (int viewIndex = 0; viewIndex < scene.views.size; viewIndex++) {
            // approximate by using the same camera
            w2p.configure(camera0, scene.getParentToView(viewIndex));
            Point2D_F64 pixel = w2p.transform(X);
            if (pixel != null && pixel.x >= 0 && pixel.y >= 0 && pixel.x < camera0.width && pixel.y < camera0.height) {
                scene.connectPointToView(i, viewIndex);
                observations.getView(viewIndex).add(i, (float) pixel.x, (float) pixel.y);
            }
        }
    }
    return observations;
}
Also used : Point3D_F64(georegression.struct.point.Point3D_F64) Random(java.util.Random) Point2D_F64(georegression.struct.point.Point2D_F64) WorldToCameraToPixel(boofcv.alg.geo.WorldToCameraToPixel) CameraPinhole(boofcv.struct.calib.CameraPinhole) Se3_F64(georegression.struct.se.Se3_F64)

Example 8 with WorldToCameraToPixel

use of boofcv.alg.geo.WorldToCameraToPixel in project BoofCV by lessthanoptimal.

the class GenericBundleAdjustmentMetricChecks method checkReprojectionError.

public static void checkReprojectionError(SceneStructureMetric structure, SceneObservations observations, double tol) {
    BundlePinhole c = (BundlePinhole) structure.cameras.get(0).model;
    // making a bunch of assumptions here...
    CameraPinhole intrinsic = new CameraPinhole(c.fx, c.fy, c.skew, c.cx, c.cy, 600, 600);
    WorldToCameraToPixel wcp = new WorldToCameraToPixel();
    PointIndex2D_F64 o = new PointIndex2D_F64();
    Point2D_F64 predicted = new Point2D_F64();
    if (structure.homogenous) {
        Point4D_F64 p4 = new Point4D_F64();
        Point3D_F64 p3 = new Point3D_F64();
        for (int viewIndex = 0; viewIndex < observations.views.size; viewIndex++) {
            SceneObservations.View v = observations.views.data[viewIndex];
            Se3_F64 parent_to_view = structure.getParentToView(viewIndex);
            wcp.configure(intrinsic, parent_to_view);
            for (int j = 0; j < v.point.size; j++) {
                v.getPixel(j, o);
                structure.points.data[o.index].get(p4);
                p3.x = p4.x / p4.w;
                p3.y = p4.y / p4.w;
                p3.z = p4.z / p4.w;
                wcp.transform(p3, predicted);
                double residual = o.p.distance(predicted);
                if (Math.abs(residual) > tol)
                    fail("Error is too large. " + residual);
            }
        }
    } else {
        Point3D_F64 p3 = new Point3D_F64();
        for (int viewIndex = 0; viewIndex < observations.views.size; viewIndex++) {
            SceneObservations.View v = observations.views.data[viewIndex];
            Se3_F64 parent_to_view = structure.getParentToView(viewIndex);
            wcp.configure(intrinsic, parent_to_view);
            for (int j = 0; j < v.point.size; j++) {
                v.getPixel(j, o);
                structure.points.data[o.index].get(p3);
                wcp.transform(p3, predicted);
                double residual = o.p.distance(predicted);
                if (Math.abs(residual) > tol)
                    fail("Error is too large. " + residual);
            }
        }
    }
}
Also used : Point3D_F64(georegression.struct.point.Point3D_F64) BundlePinhole(boofcv.alg.geo.bundle.cameras.BundlePinhole) PointIndex2D_F64(boofcv.struct.geo.PointIndex2D_F64) Point2D_F64(georegression.struct.point.Point2D_F64) Point4D_F64(georegression.struct.point.Point4D_F64) WorldToCameraToPixel(boofcv.alg.geo.WorldToCameraToPixel) CameraPinhole(boofcv.struct.calib.CameraPinhole) Se3_F64(georegression.struct.se.Se3_F64)

Example 9 with WorldToCameraToPixel

use of boofcv.alg.geo.WorldToCameraToPixel in project BoofCV by lessthanoptimal.

the class VisualizeFiducial method drawLabelCenter.

/**
 * Draws a flat cube to show where the square fiducial is on the image
 */
public static void drawLabelCenter(Se3_F64 targetToCamera, CameraPinholeBrown intrinsic, String label, Graphics2D g2, double scale) {
    // Computer the center of the fiducial in pixel coordinates
    Point2D_F64 p = new Point2D_F64();
    Point3D_F64 c = new Point3D_F64();
    WorldToCameraToPixel worldToPixel = PerspectiveOps.createWorldToPixel(intrinsic, targetToCamera);
    worldToPixel.transform(c, p);
    drawLabel(p, label, g2, scale);
}
Also used : Point3D_F64(georegression.struct.point.Point3D_F64) Point2D_F64(georegression.struct.point.Point2D_F64) WorldToCameraToPixel(boofcv.alg.geo.WorldToCameraToPixel)

Example 10 with WorldToCameraToPixel

use of boofcv.alg.geo.WorldToCameraToPixel in project BoofCV by lessthanoptimal.

the class VisualizeFiducial method drawCube.

/**
 * Draws a flat cube to show where the square fiducial is on the image
 */
public static void drawCube(Se3_F64 targetToCamera, CameraPinholeBrown intrinsic, double width, double heightScale, int lineThickness, Graphics2D g2, double scale) {
    BoofSwingUtil.antialiasing(g2);
    double r = width / 2.0;
    double h = width * heightScale;
    Point3D_F64[] corners = new Point3D_F64[8];
    corners[0] = new Point3D_F64(-r, -r, 0);
    corners[1] = new Point3D_F64(r, -r, 0);
    corners[2] = new Point3D_F64(r, r, 0);
    corners[3] = new Point3D_F64(-r, r, 0);
    corners[4] = new Point3D_F64(-r, -r, h);
    corners[5] = new Point3D_F64(r, -r, h);
    corners[6] = new Point3D_F64(r, r, h);
    corners[7] = new Point3D_F64(-r, r, h);
    Point2D_F64[] pixel = new Point2D_F64[8];
    Point2D_F64 p = new Point2D_F64();
    WorldToCameraToPixel transform = PerspectiveOps.createWorldToPixel(intrinsic, targetToCamera);
    for (int i = 0; i < 8; i++) {
        if (!transform.transform(corners[i], p)) {
            System.err.println("Crap transform failed in drawCube!");
            return;
        }
        pixel[i] = p.copy();
    }
    Line2D.Double l = new Line2D.Double();
    g2.setStroke(new BasicStroke(lineThickness));
    g2.setColor(Color.RED);
    drawLine(g2, l, pixel[0].x, pixel[0].y, pixel[1].x, pixel[1].y, scale);
    drawLine(g2, l, pixel[1].x, pixel[1].y, pixel[2].x, pixel[2].y, scale);
    drawLine(g2, l, pixel[2].x, pixel[2].y, pixel[3].x, pixel[3].y, scale);
    drawLine(g2, l, pixel[3].x, pixel[3].y, pixel[0].x, pixel[0].y, scale);
    g2.setColor(Color.BLACK);
    drawLine(g2, l, pixel[0].x, pixel[0].y, pixel[4].x, pixel[4].y, scale);
    drawLine(g2, l, pixel[1].x, pixel[1].y, pixel[5].x, pixel[5].y, scale);
    drawLine(g2, l, pixel[2].x, pixel[2].y, pixel[6].x, pixel[6].y, scale);
    drawLine(g2, l, pixel[3].x, pixel[3].y, pixel[7].x, pixel[7].y, scale);
    g2.setColor(new Color(0x00, 0xFF, 0x00, 255));
    drawLine(g2, l, pixel[4].x, pixel[4].y, pixel[5].x, pixel[5].y, scale);
    g2.setColor(new Color(0xC0, 0x10, 0xC0, 255));
    drawLine(g2, l, pixel[5].x, pixel[5].y, pixel[6].x, pixel[6].y, scale);
    g2.setColor(new Color(0x00, 0xA0, 0xC0, 255));
    drawLine(g2, l, pixel[6].x, pixel[6].y, pixel[7].x, pixel[7].y, scale);
    g2.setColor(Color.BLUE);
    drawLine(g2, l, pixel[7].x, pixel[7].y, pixel[4].x, pixel[4].y, scale);
}
Also used : Point3D_F64(georegression.struct.point.Point3D_F64) Point2D_F64(georegression.struct.point.Point2D_F64) WorldToCameraToPixel(boofcv.alg.geo.WorldToCameraToPixel) Line2D(java.awt.geom.Line2D)

Aggregations

WorldToCameraToPixel (boofcv.alg.geo.WorldToCameraToPixel)17 Point2D_F64 (georegression.struct.point.Point2D_F64)16 Point3D_F64 (georegression.struct.point.Point3D_F64)14 Se3_F64 (georegression.struct.se.Se3_F64)12 CameraPinhole (boofcv.struct.calib.CameraPinhole)6 Test (org.junit.jupiter.api.Test)5 LensDistortionNarrowFOV (boofcv.alg.distort.LensDistortionNarrowFOV)3 GrayF32 (boofcv.struct.image.GrayF32)3 ImageBase (boofcv.struct.image.ImageBase)2 ImageType (boofcv.struct.image.ImageType)2 Line2D (java.awt.geom.Line2D)2 Random (java.util.Random)2 DMatrixRMaj (org.ejml.data.DMatrixRMaj)2 LensDistortionBrown (boofcv.alg.distort.brown.LensDistortionBrown)1 BundlePinhole (boofcv.alg.geo.bundle.cameras.BundlePinhole)1 CameraPinholeBrown (boofcv.struct.calib.CameraPinholeBrown)1 Point2Transform2_F64 (boofcv.struct.distort.Point2Transform2_F64)1 PointIndex2D_F64 (boofcv.struct.geo.PointIndex2D_F64)1 UtilPoint3D_F64 (georegression.geometry.UtilPoint3D_F64)1 PlaneNormal3D_F64 (georegression.struct.plane.PlaneNormal3D_F64)1