use of boofcv.struct.distort.Point2Transform2_F64 in project BoofCV by lessthanoptimal.
the class BaseChecksPnP method createObservations.
public List<Point2D3D> createObservations(Se3_F64 worldToCamera, double nominalZ, int total) {
Se3_F64 cameraToWorld = worldToCamera.invert(null);
// transform from pixel coordinates to normalized pixel coordinates, which removes lens distortion
Point2Transform2_F64 pixelToNorm = LensDistortionOps.narrow(intrinsic).undistort_F64(true, false);
List<Point2D3D> observations = new ArrayList<>();
Point2D_F64 norm = new Point2D_F64();
for (int i = 0; i < total; i++) {
// randomly pixel a point inside the image
double x = rand.nextDouble() * intrinsic.width;
double y = rand.nextDouble() * intrinsic.height;
pixelToNorm.compute(x, y, norm);
// Randomly pick a depth and compute 3D coordinate
double Z = rand.nextDouble() + nominalZ;
double X = norm.x * Z;
double Y = norm.y * Z;
// Change the point's reference frame from camera to world
Point3D_F64 cameraPt = new Point3D_F64(X, Y, Z);
Point3D_F64 worldPt = new Point3D_F64();
SePointOps_F64.transform(cameraToWorld, cameraPt, worldPt);
// Save the perfect noise free observation
Point2D3D o = new Point2D3D();
o.getLocation().set(worldPt);
o.getObservation().set(norm.x, norm.y);
observations.add(o);
}
return observations;
}
use of boofcv.struct.distort.Point2Transform2_F64 in project BoofCV by lessthanoptimal.
the class TestBaseDetectFiducialSquare method detectWithLensDistortion.
private void detectWithLensDistortion(List<Point2D_F64> expected, DetectCorner detector, CameraPinholeRadial intrinsic) {
// create a pattern with a corner for orientation and put it into the image
GrayU8 pattern = createPattern(6 * 20, true);
GrayU8 image = new GrayU8(width, height);
ImageMiscOps.fill(image, 255);
image.subimage(60, 300, 60 + pattern.width, 300 + pattern.height, null).setTo(pattern);
// place the pattern right next to one of the corners to maximize distortion
// add lens distortion
Point2Transform2_F32 distToUndistort = LensDistortionOps.narrow(intrinsic).undistort_F32(true, true);
Point2Transform2_F64 undistTodist = LensDistortionOps.narrow(intrinsic).distort_F64(true, true);
InterpolatePixelS interp = FactoryInterpolation.createPixelS(0, 255, InterpolationType.BILINEAR, BorderType.ZERO, GrayU8.class);
ImageDistort<GrayU8, GrayU8> distorter = FactoryDistort.distortSB(false, interp, GrayU8.class);
distorter.setModel(new PointToPixelTransform_F32(distToUndistort));
GrayU8 distorted = new GrayU8(width, height);
distorter.apply(image, distorted);
detector.configure(new LensDistortionRadialTangential(intrinsic), width, height, false);
detector.process(distorted);
assertEquals(1, detector.getFound().size());
FoundFiducial ff = detector.getFound().get(0);
// see if the returned corners
Point2D_F64 expectedDist = new Point2D_F64();
for (int j = 0; j < 4; j++) {
Point2D_F64 f = ff.distortedPixels.get(j);
Point2D_F64 e = expected.get((j + 1) % 4);
undistTodist.compute(e.x, e.y, expectedDist);
assertTrue(f.distance(expectedDist) <= 0.4);
}
// The check to see if square is correctly undistorted is inside the processing function itself
}
use of boofcv.struct.distort.Point2Transform2_F64 in project BoofCV by lessthanoptimal.
the class VisualizeSquareFiducial method process.
public void process(String nameImage, String nameIntrinsic) {
CameraPinholeRadial intrinsic = nameIntrinsic == null ? null : (CameraPinholeRadial) CalibrationIO.load(nameIntrinsic);
GrayF32 input = UtilImageIO.loadImage(nameImage, GrayF32.class);
GrayF32 undistorted = new GrayF32(input.width, input.height);
Detector detector = new Detector();
if (intrinsic != null) {
CameraPinholeRadial paramUndist = new CameraPinholeRadial();
ImageDistort<GrayF32, GrayF32> undistorter = LensDistortionOps.changeCameraModel(AdjustmentType.EXPAND, BorderType.EXTENDED, intrinsic, new CameraPinhole(intrinsic), paramUndist, ImageType.single(GrayF32.class));
detector.configure(new LensDistortionRadialTangential(paramUndist), paramUndist.width, paramUndist.height, false);
undistorter.apply(input, undistorted);
} else {
undistorted.setTo(input);
}
detector.process(undistorted);
System.out.println("Total Found: " + detector.squares.size());
FastQueue<FoundFiducial> fiducials = detector.getFound();
int N = Math.min(20, detector.squares.size());
ListDisplayPanel squares = new ListDisplayPanel();
for (int i = 0; i < N; i++) {
squares.addImage(ConvertBufferedImage.convertTo(detector.squares.get(i), null), " " + i);
}
BufferedImage output = new BufferedImage(input.width, input.height, BufferedImage.TYPE_INT_RGB);
VisualizeBinaryData.renderBinary(detector.getBinary(), false, output);
Graphics2D g2 = output.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.RED);
g2.setStroke(new BasicStroke(2));
if (intrinsic != null) {
Point2Transform2_F64 add_p_to_p = LensDistortionOps.narrow(intrinsic).distort_F64(true, true);
for (int i = 0; i < N; i++) {
// add back in lens distortion
Quadrilateral_F64 q = fiducials.get(i).distortedPixels;
apply(add_p_to_p, q.a, q.a);
apply(add_p_to_p, q.b, q.b);
apply(add_p_to_p, q.c, q.c);
apply(add_p_to_p, q.d, q.d);
VisualizeShapes.draw(q, g2);
}
}
BufferedImage outputGray = new BufferedImage(input.width, input.height, BufferedImage.TYPE_INT_RGB);
ConvertBufferedImage.convertTo(undistorted, outputGray);
g2 = outputGray.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (int i = 0; i < N; i++) {
// add back in lens distortion
Quadrilateral_F64 q = fiducials.get(i).distortedPixels;
// g2.setStroke(new BasicStroke(2));
// VisualizeBinaryData.render(detector.getSquareDetector().getUsedContours(),Color.BLUE,outputGray);
VisualizeShapes.drawArrowSubPixel(q, 3, 1, g2);
}
ShowImages.showWindow(output, "Binary");
ShowImages.showWindow(outputGray, "Gray");
ShowImages.showWindow(squares, "Candidates");
}
use of boofcv.struct.distort.Point2Transform2_F64 in project BoofCV by lessthanoptimal.
the class ExamplePnP method createObservations.
/**
* Generates synthetic observations randomly in front of the camera. Observations are in normalized image
* coordinates and not pixels! See {@link PerspectiveOps#convertPixelToNorm} for how to go from pixels
* to normalized image coordinates.
*/
public List<Point2D3D> createObservations(Se3_F64 worldToCamera, int total) {
Se3_F64 cameraToWorld = worldToCamera.invert(null);
// transform from pixel coordinates to normalized pixel coordinates, which removes lens distortion
Point2Transform2_F64 pixelToNorm = LensDistortionOps.narrow(intrinsic).undistort_F64(true, false);
List<Point2D3D> observations = new ArrayList<>();
Point2D_F64 norm = new Point2D_F64();
for (int i = 0; i < total; i++) {
// randomly pixel a point inside the image
double x = rand.nextDouble() * intrinsic.width;
double y = rand.nextDouble() * intrinsic.height;
pixelToNorm.compute(x, y, norm);
// Randomly pick a depth and compute 3D coordinate
double Z = rand.nextDouble() + 4;
double X = norm.x * Z;
double Y = norm.y * Z;
// Change the point's reference frame from camera to world
Point3D_F64 cameraPt = new Point3D_F64(X, Y, Z);
Point3D_F64 worldPt = new Point3D_F64();
SePointOps_F64.transform(cameraToWorld, cameraPt, worldPt);
// Save the perfect noise free observation
Point2D3D o = new Point2D3D();
o.getLocation().set(worldPt);
o.getObservation().set(norm.x, norm.y);
observations.add(o);
}
return observations;
}
use of boofcv.struct.distort.Point2Transform2_F64 in project BoofCV by lessthanoptimal.
the class ExampleStereoTwoViewsOneCamera method drawInliers.
/**
* Draw inliers for debugging purposes. Need to convert from normalized to pixel coordinates.
*/
public static void drawInliers(BufferedImage left, BufferedImage right, CameraPinholeRadial intrinsic, List<AssociatedPair> normalized) {
Point2Transform2_F64 n_to_p = LensDistortionOps.narrow(intrinsic).distort_F64(false, true);
List<AssociatedPair> pixels = new ArrayList<>();
for (AssociatedPair n : normalized) {
AssociatedPair p = new AssociatedPair();
n_to_p.compute(n.p1.x, n.p1.y, p.p1);
n_to_p.compute(n.p2.x, n.p2.y, p.p2);
pixels.add(p);
}
// display the results
AssociationPanel panel = new AssociationPanel(20);
panel.setAssociation(pixels);
panel.setImages(left, right);
ShowImages.showWindow(panel, "Inlier Features");
}
Aggregations