Search in sources :

Example 16 with FMatrixRMaj

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);
}
Also used : FMatrixRMaj(org.ejml.data.FMatrixRMaj) ListDisplayPanel(boofcv.gui.ListDisplayPanel) RectifyCalibrated(boofcv.alg.geo.rectify.RectifyCalibrated) DMatrixRMaj(org.ejml.data.DMatrixRMaj) RectifiedPairPanel(boofcv.gui.stereo.RectifiedPairPanel) BufferedImage(java.awt.image.BufferedImage) ConvertBufferedImage(boofcv.io.image.ConvertBufferedImage) GrayF32(boofcv.struct.image.GrayF32) Planar(boofcv.struct.image.Planar) StereoParameters(boofcv.struct.calib.StereoParameters) File(java.io.File) Se3_F64(georegression.struct.se.Se3_F64)

Example 17 with FMatrixRMaj

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);
}
Also used : FMatrixRMaj(org.ejml.data.FMatrixRMaj) RectifyCalibrated(boofcv.alg.geo.rectify.RectifyCalibrated) DMatrixRMaj(org.ejml.data.DMatrixRMaj) Se3_F64(georegression.struct.se.Se3_F64)

Example 18 with FMatrixRMaj

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;
}
Also used : FMatrixRMaj(org.ejml.data.FMatrixRMaj) PointTransformHomography_F32(boofcv.alg.distort.PointTransformHomography_F32) PointToPixelTransform_F32(boofcv.struct.distort.PointToPixelTransform_F32)

Example 19 with FMatrixRMaj

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();
}
Also used : AssociatedPair(boofcv.struct.geo.AssociatedPair) FMatrixRMaj(org.ejml.data.FMatrixRMaj) FDistort(boofcv.abst.distort.FDistort) Estimate1ofEpipolar(boofcv.abst.geo.Estimate1ofEpipolar) Point2D_F64(georegression.struct.point.Point2D_F64) ArrayList(java.util.ArrayList) DMatrixRMaj(org.ejml.data.DMatrixRMaj)

Example 20 with FMatrixRMaj

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);
}
Also used : FMatrixRMaj(org.ejml.data.FMatrixRMaj) CameraPinhole(boofcv.struct.calib.CameraPinhole) Test(org.junit.jupiter.api.Test)

Aggregations

FMatrixRMaj (org.ejml.data.FMatrixRMaj)36 DMatrixRMaj (org.ejml.data.DMatrixRMaj)10 Test (org.junit.Test)8 Point2D_F32 (georegression.struct.point.Point2D_F32)7 Se3_F64 (georegression.struct.se.Se3_F64)7 RectifyCalibrated (boofcv.alg.geo.rectify.RectifyCalibrated)6 PointTransformHomography_F32 (boofcv.alg.distort.PointTransformHomography_F32)5 Point2Transform2_F32 (boofcv.struct.distort.Point2Transform2_F32)5 ConvertBufferedImage (boofcv.io.image.ConvertBufferedImage)4 CameraPinholeRadial (boofcv.struct.calib.CameraPinholeRadial)4 BufferedImage (java.awt.image.BufferedImage)4 RectifiedPairPanel (boofcv.gui.stereo.RectifiedPairPanel)3 GrayF32 (boofcv.struct.image.GrayF32)3 GrayU8 (boofcv.struct.image.GrayU8)3 Planar (boofcv.struct.image.Planar)3 ArrayList (java.util.ArrayList)3 Test (org.junit.jupiter.api.Test)3 Estimate1ofEpipolar (boofcv.abst.geo.Estimate1ofEpipolar)2 CameraPinhole (boofcv.struct.calib.CameraPinhole)2 PointToPixelTransform_F32 (boofcv.struct.distort.PointToPixelTransform_F32)2