/*
* Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved.
*
* This file is part of BoofCV (http://boofcv.org).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package boofcv.demonstrations.calibration;
import boofcv.alg.distort.DistortImageOps;
import boofcv.alg.distort.ImageDistort;
import boofcv.alg.geo.PerspectiveOps;
import boofcv.alg.geo.RectifyImageOps;
import boofcv.alg.geo.rectify.RectifyCalibrated;
import boofcv.alg.misc.GImageMiscOps;
import boofcv.core.image.border.BorderType;
import boofcv.gui.ListDisplayPanel;
import boofcv.gui.SelectAlgorithmAndInputPanel;
import boofcv.gui.image.ShowImages;
import boofcv.gui.stereo.RectifiedPairPanel;
import boofcv.io.PathLabel;
import boofcv.io.UtilIO;
import boofcv.io.image.ConvertBufferedImage;
import boofcv.struct.calib.StereoParameters;
import boofcv.struct.image.GrayF32;
import boofcv.struct.image.ImageType;
import boofcv.struct.image.Planar;
import georegression.struct.se.Se3_F64;
import org.ejml.data.DenseMatrix64F;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
/**
* Given a set of stereo images and their intrinsic parameters, display the rectified images and a horizontal line
* where the user clicks. The different rectified images show how the view can be optimized for different purposes.
*
* @author Peter Abeles
*/
public class ShowRectifyCalibratedApp extends SelectAlgorithmAndInputPanel {
ListDisplayPanel gui = new ListDisplayPanel();
StereoParameters param;
// distorted input images
Planar distLeft;
Planar distRight;
// storage for undistorted and rectified images
Planar rectLeft;
Planar rectRight;
boolean hasProcessed = false;
public ShowRectifyCalibratedApp() {
super(0);
setMainGUI(gui);
}
public void configure( final BufferedImage origLeft , final BufferedImage origRight , StereoParameters param )
{
this.param = param;
// distorted images
distLeft = ConvertBufferedImage.convertFromMulti(origLeft, null, true, GrayF32.class);
distRight = ConvertBufferedImage.convertFromMulti(origRight, null, true, GrayF32.class);
// storage for undistorted + rectified images
rectLeft = new Planar(GrayF32.class,
distLeft.getWidth(),distLeft.getHeight(),distLeft.getNumBands());
rectRight = new Planar(GrayF32.class,
distRight.getWidth(),distRight.getHeight(),distRight.getNumBands());
// Compute rectification
RectifyCalibrated rectifyAlg = RectifyImageOps.createCalibrated();
Se3_F64 leftToRight = param.getRightToLeft().invert(null);
// original camera calibration matrices
DenseMatrix64F K1 = PerspectiveOps.calibrationMatrix(param.getLeft(), null);
DenseMatrix64F K2 = PerspectiveOps.calibrationMatrix(param.getRight(), null);
rectifyAlg.process(K1,new Se3_F64(),K2,leftToRight);
// rectification matrix for each image
DenseMatrix64F rect1 = rectifyAlg.getRect1();
DenseMatrix64F rect2 = rectifyAlg.getRect2();
DenseMatrix64F rectK = rectifyAlg.getCalibrationMatrix();
// show results and draw a horizontal line where the user clicks to see rectification easier
SwingUtilities.invokeLater(new Runnable() {
public void run() {
gui.reset();
gui.addItem(new RectifiedPairPanel(true, origLeft, origRight), "Original");
}
});
// add different types of adjustments
addRectified("No Adjustment", rect1,rect2);
RectifyImageOps.allInsideLeft(param.left, rect1, rect2, rectK);
addRectified("All Inside", rect1,rect2);
RectifyImageOps.fullViewLeft(param.left, rect1, rect2, rectK);
addRectified("Full View", rect1,rect2);
hasProcessed = true;
}
private void addRectified( final String name , final DenseMatrix64F rect1 , final DenseMatrix64F rect2 ) {
// Will rectify the image
ImageType imageType = ImageType.single(GrayF32.class);
ImageDistort imageDistortLeft =
RectifyImageOps.rectifyImage(param.getLeft(), rect1, BorderType.ZERO, imageType);
ImageDistort imageDistortRight =
RectifyImageOps.rectifyImage(param.getRight(), rect2, BorderType.ZERO, imageType);
// Fill the image with all black
GImageMiscOps.fill(rectLeft, 0);
GImageMiscOps.fill(rectRight,0);
// Render the rectified image
DistortImageOps.distortPL(distLeft, rectLeft, imageDistortLeft);
DistortImageOps.distortPL(distRight, rectRight, imageDistortRight);
// convert for output
final BufferedImage outLeft = ConvertBufferedImage.convertTo(rectLeft, null,true);
final BufferedImage outRight = ConvertBufferedImage.convertTo(rectRight, null, true);
// Add this rectified image
SwingUtilities.invokeLater(new Runnable() {
public void run() {
gui.addItem(new RectifiedPairPanel(true, outLeft, outRight), name);
}});
}
@Override
public void refreshAll(Object[] cookies) {}
@Override
public void setActiveAlgorithm(int indexFamily, String name, Object cookie) {}
@Override
public void changeInput(String name, int index) {
PathLabel refs = inputRefs.get(index);
StereoParameters param = UtilIO.loadXML(media.openFile(refs.getPath(0)));
BufferedImage origLeft = media.openImage(refs.getPath(1));
BufferedImage origRight = media.openImage(refs.getPath(2));
configure(origLeft,origRight,param);
}
@Override
public void loadConfigurationFile(String fileName) {}
@Override
public boolean getHasProcessedImage() {
return hasProcessed;
}
public static void main( String args[] ) {
ShowRectifyCalibratedApp app = new ShowRectifyCalibratedApp();
// camera config, image left, image right
String dir = UtilIO.pathExample("calibration/stereo/Bumblebee2_Chess/");
java.util.List inputs = new ArrayList();
inputs.add(new PathLabel("BumbleBee",dir + "stereo.xml",dir + "left05.jpg",dir + "right05.jpg"));
app.setInputList(inputs);
// wait for it to process one image so that the size isn't all screwed up
while( !app.getHasProcessedImage() ) {
Thread.yield();
}
ShowImages.showWindow(app, "Calibrated Camera Rectification", true);
System.out.println("Done");
}
}
Ads help maintain this website.