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);
}
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;
}
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);
}
}
}
}
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);
}
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);
}
Aggregations