Example Calibrate Planar Stereo

From BoofCV
Revision as of 07:41, 18 April 2012 by Peter (talk | contribs)
Jump to navigationJump to search

Stereo Camera Calibration with Planar Targets

Calibrating a stereo camera system is the process of learning its intrinsic parameters for each camera and the extrinsic parameters between the two cameras. This example demonstrates how to use multiple pictures of a planar calibration target. Both the square grid and chessboard patterns are supported by this example. For a full description of the calibration process and instruction on how to do it yourself see the tutorial linked to below.

Example File: ExampleCalibrateStereoPlanar.java

Calibration Tutorial: Wikipage

Concepts:

  • Camera calibration
  • Lens distortion
  • Intrinsic parameters
  • Stereo Vision

Relevant Applets:

Related Examples:

Example Code

/**
 * <p>
 * Example of how to calibrate a stereo camera system using a planar calibration grid.  The intrinsic camera parameters
 * are estimated for both cameras individually, then extrinsic parameters for the two cameras relative to each other
 * are found   This example does not rectify the images, which is  required for some algorithms.
 * See {@link ExampleRectifyCalibratedStereo}. Both square grid and chessboard targets are demonstrated in this example.
 * See calibration tutorial for a discussion of different target types and how to collect good calibration images.
 * </p>
 *
 * <<p>
 * All the image processing and calibration is taken care of inside of {@link CalibrateStereoPlanar}.  The code below
 * loads calibration images as inputs, calibrates, and saves results to an XML file.  See in code comments for tuning
 * and implementation issues.
 * </p>
 *
 * @see ExampleRectifyCalibratedStereo
 * @see CalibrateStereoPlanar
 *
 * @author Peter Abeles
 */
public class ExampleCalibrateStereoPlanar {

	// Detects the target and calibration point inside the target
	PlanarCalibrationDetector detector;

	// Description of the target's physical dimension
	PlanarCalibrationTarget target;

	// List of calibration images
	List<String> left;
	List<String> right;

	// Most computer images are in a left handed coordinate system.  If set to true it will be changed into
	// a right handed coordinate system.  This is required for stereo calibration to work correctly.
	boolean isLeftHanded;

	/**
	 * Square grid target taken by a PtGrey Bumblebee camera.
	 */
	public void setupBumblebeeSquare() {
		// Use the wrapper below for square grid targets.
		detector = new WrapPlanarGridTarget(3,4);
		// Target physical description
		target = FactoryPlanarCalibrationTarget.gridSquare(3, 4, 30,30);

		String directory = "../data/evaluation/calibration/stereo/Bumblebee2_Square";

		left = BoofMiscOps.directoryList(directory, "left");
		right = BoofMiscOps.directoryList(directory, "right");

		isLeftHanded = true;
	}

	/**
	 * Chessboard target taken by a PtGrey Bumblebee camera.
	 */
	public void setupBumblebeeChess() {
		// Use the wrapper below for chessboard targets.  The last parameter adjusts the size of the corner detection
		// region.  TUNE THIS PARAMETER FOR OPTIMAL ACCURACY!
		detector = new WrapPlanarChessTarget(3,4,6);
		// Target physical description
		target = FactoryPlanarCalibrationTarget.gridChess(3, 4, 30);

		String directory = "../data/evaluation/calibration/stereo/Bumblebee2_Chess";

		left = BoofMiscOps.directoryList(directory, "left");
		right = BoofMiscOps.directoryList(directory, "right");

		isLeftHanded = true;
	}

	/**
	 * Process calibration images, compute intrinsic parameters, save to a file
	 */
	public void process() {
		// Declare and setup the calibration algorithm
		CalibrateStereoPlanar calibratorAlg = new CalibrateStereoPlanar(detector,isLeftHanded);
		calibratorAlg.configure(target, false, 2);

		// 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.loadImage(left.get(i));
			BufferedImage r = UtilImageIO.loadImage(right.get(i));

			ImageFloat32 imageLeft = ConvertBufferedImage.convertFrom(l,(ImageFloat32)null);
			ImageFloat32 imageRight = ConvertBufferedImage.convertFrom(r,(ImageFloat32)null);

			calibratorAlg.addPair(imageLeft, imageRight);
		}

		// Process and compute calibration parameters
		StereoParameters stereoCalib = calibratorAlg.process();

		// save results to a file and print out
		BoofMiscOps.saveXML(stereoCalib, "stereo.xml");
		stereoCalib.print();
	}

	public static void main( String args[] ) {
		ExampleCalibrateStereoPlanar alg = new ExampleCalibrateStereoPlanar();

		// Select which set of targets to use
		alg.setupBumblebeeChess();
//		alg.setupBumblebeeSquare();

		// compute and save results
		alg.process();
	}
}