use of boofcv.struct.calib.StereoParameters in project BoofCV by lessthanoptimal.
the class CalibrateStereoPlanarGuiApp method process.
public void process(String outputFileName) {
// displays progress so the impatient don't give up
final ProcessThread monitor = new ProcessThread();
monitor.start();
// load images
calibrator.reset();
int N = leftImages.size();
for (int i = 0; i < N; i++) {
final BufferedImage leftOrig = media.openImage(leftImages.get(i).getPath());
final BufferedImage rightOrig = media.openImage(rightImages.get(i).getPath());
if (leftOrig != null && rightOrig != null) {
GrayF32 leftInput = ConvertBufferedImage.convertFrom(leftOrig, (GrayF32) null);
GrayF32 rightInput = ConvertBufferedImage.convertFrom(rightOrig, (GrayF32) null);
CalibrationObservation calibLeft, calibRight;
if (!detector.process(leftInput)) {
System.out.println("Feature detection failed in " + leftImages.get(i));
continue;
}
calibLeft = detector.getDetectedPoints();
if (!detector.process(rightInput)) {
System.out.println("Feature detection failed in " + rightImages.get(i));
continue;
}
calibRight = detector.getDetectedPoints();
calibrator.addPair(calibLeft, calibRight);
final int number = i;
SwingUtilities.invokeLater(() -> {
gui.addPair("Image " + number, leftImages.get(number), rightImages.get(number));
gui.repaint();
monitor.setMessage(0, "Image " + number);
});
} else {
System.out.println("Failed to load left = " + leftImages.get(i));
System.out.println("Failed to load right = " + rightImages.get(i));
}
}
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
// gui.setObservations(calibrator.getCalibLeft().getObservations(),calibrator.getCalibLeft().getErrors(),
// calibrator.getCalibRight().getObservations(),calibrator.getCalibRight().getErrors());
// }});
// gui.repaint();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
monitor.setMessage(1, "Estimating Parameters");
}
});
StereoParameters param = calibrator.process();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
gui.setObservations(calibrator.getCalibLeft().getObservations(), calibrator.getCalibLeft().getErrors(), calibrator.getCalibRight().getObservations(), calibrator.getCalibRight().getErrors());
}
});
gui.repaint();
// compute stereo rectification
setRectification(param);
monitor.stopThread();
calibrator.printStatistics();
param.print();
if (outputFileName != null)
CalibrationIO.save(param, outputFileName);
}
use of boofcv.struct.calib.StereoParameters in project BoofCV by lessthanoptimal.
the class ExampleCalibrateStereo method process.
/**
* Process calibration images, compute intrinsic parameters, save to a file
*/
public void process() {
// Declare and setup the calibration algorithm
var calibratorAlg = new CalibrateStereoPlanar(detector.getLayout());
calibratorAlg.configure(/*zero skew*/
true, /* radial */
4, /* tangential */
false);
// Uncomment to print more information to stdout
// calibratorAlg.setVerbose(System.out,null);
// ensure the lists are in the same order
Collections.sort(left);
Collections.sort(right);
for (int i = 0; i < left.size(); i++) {
BufferedImage l = UtilImageIO.loadImageNotNull(left.get(i));
BufferedImage r = UtilImageIO.loadImageNotNull(right.get(i));
GrayF32 imageLeft = ConvertBufferedImage.convertFrom(l, (GrayF32) null);
GrayF32 imageRight = ConvertBufferedImage.convertFrom(r, (GrayF32) null);
CalibrationObservation calibLeft, calibRight;
if (!detector.process(imageLeft)) {
System.out.println("Failed to detect target in " + left.get(i));
continue;
}
calibLeft = detector.getDetectedPoints();
if (!detector.process(imageRight)) {
System.out.println("Failed to detect target in " + right.get(i));
continue;
}
calibRight = detector.getDetectedPoints();
calibratorAlg.addPair(calibLeft, calibRight);
}
// Process and compute calibration parameters
StereoParameters stereoCalib = calibratorAlg.process();
// print out information on its accuracy and errors
calibratorAlg.printStatistics();
// save results to a file and print out
CalibrationIO.save(stereoCalib, "stereo.yaml");
stereoCalib.print();
// Note that the stereo baseline translation will be specified in the same units as the calibration grid.
// Which is in millimeters (mm) in this example.
}
use of boofcv.struct.calib.StereoParameters in project BoofCV by lessthanoptimal.
the class ExampleOverheadView method main.
public static void main(String[] args) {
BufferedImage input = UtilImageIO.loadImageNotNull(UtilIO.pathExample("road/left01.png"));
Planar<GrayU8> imageRGB = ConvertBufferedImage.convertFromPlanar(input, null, true, GrayU8.class);
StereoParameters stereoParam = CalibrationIO.load(UtilIO.pathExample("road/stereo01.yaml"));
Se3_F64 groundToLeft = CalibrationIO.load(UtilIO.pathExample("road/ground_to_left_01.yaml"));
CreateSyntheticOverheadView<Planar<GrayU8>> generateOverhead = new CreateSyntheticOverheadViewPL<>(InterpolationType.BILINEAR, 3, GrayU8.class);
// size of cells in the overhead image in world units
double cellSize = 0.05;
// You can use this to automatically select reasonable values for the overhead image
SelectOverheadParameters selectMapSize = new SelectOverheadParameters(cellSize, 20, 0.5);
selectMapSize.process(stereoParam.left, groundToLeft);
int overheadWidth = selectMapSize.getOverheadWidth();
int overheadHeight = selectMapSize.getOverheadHeight();
Planar<GrayU8> overheadRGB = new Planar<>(GrayU8.class, overheadWidth, overheadHeight, 3);
generateOverhead.configure(stereoParam.left, groundToLeft, selectMapSize.getCenterX(), selectMapSize.getCenterY(), cellSize, overheadRGB.width, overheadRGB.height);
generateOverhead.process(imageRGB, overheadRGB);
// note that the left/right values are swapped in the overhead image. This is an artifact of the plane's
// 2D coordinate system having +y pointing up, while images have +y pointing down.
BufferedImage output = ConvertBufferedImage.convertTo(overheadRGB, null, true);
ShowImages.showWindow(input, "Input Image", true);
ShowImages.showWindow(output, "Overhead Image", true);
}
use of boofcv.struct.calib.StereoParameters in project BoofCV by lessthanoptimal.
the class ExampleStereoDisparity method main.
public static void main(String[] args) {
String calibDir = UtilIO.pathExample("calibration/stereo/Bumblebee2_Chess/");
String imageDir = UtilIO.pathExample("stereo/");
StereoParameters param = CalibrationIO.load(new File(calibDir, "stereo.yaml"));
// load and convert images into a BoofCV format
BufferedImage origLeft = UtilImageIO.loadImage(imageDir, "chair01_left.jpg");
BufferedImage origRight = UtilImageIO.loadImage(imageDir, "chair01_right.jpg");
GrayU8 distLeft = ConvertBufferedImage.convertFrom(origLeft, (GrayU8) null);
GrayU8 distRight = ConvertBufferedImage.convertFrom(origRight, (GrayU8) null);
// rectify images
GrayU8 rectLeft = distLeft.createSameShape();
GrayU8 rectRight = distRight.createSameShape();
rectify(distLeft, distRight, param, rectLeft, rectRight);
// compute disparity
int disparityRange = 60;
GrayU8 disparity = denseDisparity(rectLeft, rectRight, 5, 10, disparityRange);
// GrayF32 disparity = denseDisparitySubpixel(rectLeft, rectRight, 5, 10, disparityRange);
// show results
BufferedImage visualized = VisualizeImageData.disparity(disparity, null, disparityRange, 0);
var gui = new ListDisplayPanel();
gui.addImage(rectLeft, "Rectified");
gui.addImage(visualized, "Disparity");
ShowImages.showWindow(gui, "Stereo Disparity", true);
}
use of boofcv.struct.calib.StereoParameters 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);
}
Aggregations