use of org.ejml.data.FMatrixRMaj in project BoofCV by lessthanoptimal.
the class ExampleRectifyCalibratedStereo method main.
public static void main(String[] args) {
String dir = UtilIO.pathExample("calibration/stereo/Bumblebee2_Chess/");
StereoParameters param = CalibrationIO.load(new File(dir, "stereo.yaml"));
// load images
BufferedImage origLeft = UtilImageIO.loadImage(dir, "left05.jpg");
BufferedImage origRight = UtilImageIO.loadImage(dir, "right05.jpg");
// distorted images
Planar<GrayF32> distLeft = ConvertBufferedImage.convertFromPlanar(origLeft, null, true, GrayF32.class);
Planar<GrayF32> distRight = ConvertBufferedImage.convertFromPlanar(origRight, null, true, GrayF32.class);
// storage for undistorted + rectified images
Planar<GrayF32> rectLeft = distLeft.createSameShape();
Planar<GrayF32> rectRight = distRight.createSameShape();
// Compute rectification
RectifyCalibrated rectifyAlg = RectifyImageOps.createCalibrated();
Se3_F64 leftToRight = param.getRightToLeft().invert(null);
// original camera calibration matrices
DMatrixRMaj K1 = PerspectiveOps.pinholeToMatrix(param.getLeft(), (DMatrixRMaj) null);
DMatrixRMaj K2 = PerspectiveOps.pinholeToMatrix(param.getRight(), (DMatrixRMaj) null);
rectifyAlg.process(K1, new Se3_F64(), K2, leftToRight);
// rectification matrix for each image
DMatrixRMaj rect1 = rectifyAlg.getUndistToRectPixels1();
DMatrixRMaj rect2 = rectifyAlg.getUndistToRectPixels2();
// New calibration matrix,
// Both cameras have the same one after rectification.
DMatrixRMaj rectK = rectifyAlg.getCalibrationMatrix();
// Adjust the rectification to make the view area more useful
RectifyImageOps.fullViewLeft(param.left, rect1, rect2, rectK, null);
// RectifyImageOps.allInsideLeft(param.left, rect1, rect2, rectK, null);
// undistorted and rectify images
// TODO simplify code some how
var rect1_F32 = new FMatrixRMaj(3, 3);
var rect2_F32 = new FMatrixRMaj(3, 3);
ConvertMatrixData.convert(rect1, rect1_F32);
ConvertMatrixData.convert(rect2, rect2_F32);
ImageDistort<Planar<GrayF32>, Planar<GrayF32>> rectifyImageLeft = RectifyDistortImageOps.rectifyImage(param.getLeft(), rect1_F32, BorderType.SKIP, distLeft.getImageType());
ImageDistort<Planar<GrayF32>, Planar<GrayF32>> rectifyImageRight = RectifyDistortImageOps.rectifyImage(param.getRight(), rect2_F32, BorderType.SKIP, distRight.getImageType());
rectifyImageLeft.apply(distLeft, rectLeft);
rectifyImageRight.apply(distRight, rectRight);
// convert for output
BufferedImage outLeft = ConvertBufferedImage.convertTo(rectLeft, null, true);
BufferedImage outRight = ConvertBufferedImage.convertTo(rectRight, null, true);
// show results and draw a horizontal line where the user clicks to see rectification easier
var panel = new ListDisplayPanel();
panel.addItem(new RectifiedPairPanel(true, origLeft, origRight), "Original");
panel.addItem(new RectifiedPairPanel(true, outLeft, outRight), "Rectified");
ShowImages.showWindow(panel, "Stereo Rectification Calibrated", true);
}
use of org.ejml.data.FMatrixRMaj in project BoofCV by lessthanoptimal.
the class ExampleStereoTwoViewsOneCamera method rectifyImages.
/**
* Remove lens distortion and rectify stereo images
*
* @param distortedLeft Input distorted image from left camera.
* @param distortedRight Input distorted image from right camera.
* @param leftToRight Camera motion from left to right
* @param intrinsicLeft Intrinsic camera parameters
* @param rectifiedLeft Output rectified image for left camera.
* @param rectifiedRight Output rectified image for right camera.
* @param rectifiedMask Mask that indicates invalid pixels in rectified image. 1 = valid, 0 = invalid
* @param rectifiedK Output camera calibration matrix for rectified camera
*/
public static <T extends ImageBase<T>> void rectifyImages(T distortedLeft, T distortedRight, Se3_F64 leftToRight, CameraPinholeBrown intrinsicLeft, CameraPinholeBrown intrinsicRight, T rectifiedLeft, T rectifiedRight, GrayU8 rectifiedMask, DMatrixRMaj rectifiedK, DMatrixRMaj rectifiedR) {
RectifyCalibrated rectifyAlg = RectifyImageOps.createCalibrated();
// original camera calibration matrices
DMatrixRMaj K1 = PerspectiveOps.pinholeToMatrix(intrinsicLeft, (DMatrixRMaj) null);
DMatrixRMaj K2 = PerspectiveOps.pinholeToMatrix(intrinsicRight, (DMatrixRMaj) null);
rectifyAlg.process(K1, new Se3_F64(), K2, leftToRight);
// rectification matrix for each image
DMatrixRMaj rect1 = rectifyAlg.getUndistToRectPixels1();
DMatrixRMaj rect2 = rectifyAlg.getUndistToRectPixels2();
rectifiedR.setTo(rectifyAlg.getRectifiedRotation());
// New calibration matrix,
rectifiedK.setTo(rectifyAlg.getCalibrationMatrix());
// Adjust the rectification to make the view area more useful
ImageDimension rectShape = new ImageDimension();
RectifyImageOps.fullViewLeft(intrinsicLeft, rect1, rect2, rectifiedK, rectShape);
// RectifyImageOps.allInsideLeft(intrinsicLeft, rect1, rect2, rectifiedK, rectShape);
// Taking in account the relative rotation between the image axis and the baseline is important in
// this scenario since a person can easily hold the camera at an odd angle. If you don't adjust
// the rectified image size you might end up with a lot of wasted pixels and a low resolution model!
rectifiedLeft.reshape(rectShape.width, rectShape.height);
rectifiedRight.reshape(rectShape.width, rectShape.height);
// undistorted and rectify images
FMatrixRMaj rect1_F32 = new FMatrixRMaj(3, 3);
FMatrixRMaj rect2_F32 = new FMatrixRMaj(3, 3);
ConvertMatrixData.convert(rect1, rect1_F32);
ConvertMatrixData.convert(rect2, rect2_F32);
// Extending the image prevents a harsh edge reducing false matches at the image border
// SKIP is another option, possibly a tinny bit faster, but has a harsh edge which will need to be filtered
ImageDistort<T, T> distortLeft = RectifyDistortImageOps.rectifyImage(intrinsicLeft, rect1_F32, BorderType.EXTENDED, distortedLeft.getImageType());
ImageDistort<T, T> distortRight = RectifyDistortImageOps.rectifyImage(intrinsicRight, rect2_F32, BorderType.EXTENDED, distortedRight.getImageType());
distortLeft.apply(distortedLeft, rectifiedLeft, rectifiedMask);
distortRight.apply(distortedRight, rectifiedRight);
}
use of org.ejml.data.FMatrixRMaj in project BoofCV by lessthanoptimal.
the class RectifyDistortImageOps method rectifyImage.
/**
* Creates an {@link ImageDistort} for rectifying an image given its rectification matrix.
* Lens distortion is assumed to have been previously removed.
*
* @param rectify Transform for rectifying the image.
* @param imageType Type of single band image the transform is to be applied to.
* @return ImageDistort for rectifying the image.
*/
public static <T extends ImageGray<T>> ImageDistort<T, T> rectifyImage(FMatrixRMaj rectify, BorderType borderType, Class<T> imageType) {
boolean skip = borderType == BorderType.SKIP;
if (skip) {
borderType = BorderType.EXTENDED;
}
InterpolatePixelS<T> interp = FactoryInterpolation.bilinearPixelS(imageType, borderType);
FMatrixRMaj rectifyInv = new FMatrixRMaj(3, 3);
CommonOps_FDRM.invert(rectify, rectifyInv);
PointTransformHomography_F32 rectifyTran = new PointTransformHomography_F32(rectifyInv);
// don't bother caching the results since it is likely to only be applied once and is cheap to compute
ImageDistort<T, T> ret = FactoryDistort.distortSB(false, interp, imageType);
ret.setRenderAll(!skip);
ret.setModel(new PointToPixelTransform_F32(rectifyTran));
return ret;
}
use of org.ejml.data.FMatrixRMaj in project BoofCV by lessthanoptimal.
the class TestRemovePerspectiveDistortion method applyForwardTransform.
private void applyForwardTransform(GrayF32 expected, GrayF32 input, Point2D_F64 topLeft, Point2D_F64 topRight, Point2D_F64 bottomRight, Point2D_F64 bottomLeft) {
Estimate1ofEpipolar computeHomography = FactoryMultiView.homographyDLT(true);
ArrayList<AssociatedPair> associatedPairs = new ArrayList<>();
associatedPairs.add(new AssociatedPair(topLeft, new Point2D_F64(0, 0)));
associatedPairs.add(new AssociatedPair(topRight, new Point2D_F64(expected.width - 1, 0)));
associatedPairs.add(new AssociatedPair(bottomRight, new Point2D_F64(expected.width - 1, expected.height - 1)));
associatedPairs.add(new AssociatedPair(bottomLeft, new Point2D_F64(0, expected.height - 1)));
DMatrixRMaj H = new DMatrixRMaj(3, 3);
computeHomography.process(associatedPairs, H);
FMatrixRMaj H32 = new FMatrixRMaj(3, 3);
ConvertMatrixData.convert(H, H32);
new FDistort(expected, input).transform(new PointTransformHomography_F32(H32)).apply();
}
use of org.ejml.data.FMatrixRMaj in project BoofCV by lessthanoptimal.
the class TestPerspectiveOps method pinholeToMatrix_class_F.
@Test
void pinholeToMatrix_class_F() {
FMatrixRMaj K = PerspectiveOps.pinholeToMatrix(new CameraPinhole(1.0, 2, 3, 4, 5, 400, 500), (FMatrixRMaj) null);
assertEquals(1, K.get(0, 0), UtilEjml.TEST_F32);
assertEquals(2, K.get(1, 1), UtilEjml.TEST_F32);
assertEquals(3, K.get(0, 1), UtilEjml.TEST_F32);
assertEquals(4, K.get(0, 2), UtilEjml.TEST_F32);
assertEquals(5, K.get(1, 2), UtilEjml.TEST_F32);
assertEquals(1, K.get(2, 2), UtilEjml.TEST_F32);
}
Aggregations