Difference between revisions of "Example Calibrate Planar Mono"

From BoofCV
Jump to navigationJump to search
m
m
(7 intermediate revisions by the same user not shown)
Line 7: Line 7:
This example demonstrates how to use a high level calibration class that automatically detects calibration targets as viewed from a single (monocular) camera in a set of images.  After processing the images the intrinsic camera parameters and lens distortion are saved to an XML file.  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.
This example demonstrates how to use a high level calibration class that automatically detects calibration targets as viewed from a single (monocular) camera in a set of images.  After processing the images the intrinsic camera parameters and lens distortion are saved to an XML file.  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: [https://github.com/lessthanoptimal/BoofCV/blob/v0.20/examples/src/boofcv/examples/calibration/ExampleCalibrateMonocular.java ExampleCalibrateMonocular.java]
Example File: [https://github.com/lessthanoptimal/BoofCV/blob/v0.32/examples/src/main/java/boofcv/examples/calibration/ExampleCalibrateMonocular.java ExampleCalibrateMonocular.java]


Calibration Tutorial: [[Tutorial_Camera_Calibration|Wikipage]]
Calibration Tutorial: [[Tutorial_Camera_Calibration|Wikipage]]
Line 15: Line 15:
* Lens distortion
* Lens distortion
* Intrinsic parameters
* Intrinsic parameters
Relevant Applets:
* [[Applet_Calibrate_Planar_Mono| Monocular Calibration]]
* [[Applet_Remove_Lens_Distortion| Removing Lens Distortion]]


Related Examples:
Related Examples:
Line 27: Line 23:
<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
/**
/**
  * Example of how to calibrate a single (monocular) camera using a high level interface that processes images of planar
  * Example of how to calibrate a single (monocular) camera using a high level interface. Depending on the calibration
  * calibration targets.  The entire calibration target must be observable in the image and for best results images
  * target detector and target type, the entire target might need to be visible in the image. All camera images
  * should be in focus and not blurred. For a lower level example of camera calibration which processes a set of
  * should be in focus and that target evenly spread through out the images. In particular the edges of the image
  * observed calibration points see {@link ExampleCalibrateMonocular}.
  * should be covered.
  *
  *
  * After processing both intrinsic camera parameters and lens distortion are estimated.  Square grid and chessboard
  * After processing both intrinsic camera parameters and lens distortion are estimated.  Square grid and chessboard
Line 45: Line 41:
  */
  */
public class ExampleCalibrateMonocular {
public class ExampleCalibrateMonocular {
public static void main( String args[] ) {
DetectorFiducialCalibration detector;
List<String> images;


// Detects the target and calibration point inside the target
// Regular Circle Example
CalibrationDetector detector;
// detector = FactoryFiducialCalibration.circleRegularGrid(new ConfigCircleRegularGrid(8, 10, 1.5, 2.5));
 
// images = UtilIO.listByPrefix(UtilIO.pathExample("calibration/mono/Sony_DSC-HX5V_CircleRegular"),"image");
// List of calibration images
List<String> images;
 
/**
* Images from Zhang's website.  Square grid pattern.
*/
private void setupZhang99() {
// Creates a detector and specifies its physical characteristics
detector = FactoryPlanarCalibrationTarget.detectorSquareGrid(new ConfigSquareGrid(15, 15, 0.5, 7.0 / 18.0));
 
// load image list
String directory = UtilIO.path("data/evaluation/calibration/mono/PULNiX_CCD_6mm_Zhang");
images = BoofMiscOps.directoryList(directory,"CalibIm");
}


/**
// Hexagonal Circle Example
* Images collected from a Bumblee Bee stereo camera.  Large amounts of radial distortion. Chessboard pattern.
// detector = FactoryFiducialCalibration.circleHexagonalGrid(new ConfigCircleHexagonalGrid(24, 28, 1, 1.2));
*/
// images = UtilIO.listByPrefix(UtilIO.pathExample("calibration/mono/Sony_DSC-HX5V_CircleHexagonal"),"image");
private void setupBumbleBee() {
// Creates a detector and specifies its physical characteristics
detector = FactoryPlanarCalibrationTarget.detectorChessboard(new ConfigChessboard(5, 7, 30));


// load image list
// Square Grid example
String directory = UtilIO.pathExample("calibration/stereo/Bumblebee2_Chess");
// detector = FactoryFiducialCalibration.squareGrid(new ConfigSquareGrid(4, 3, 30, 30));
images = BoofMiscOps.directoryList(directory,"left");
// images = UtilIO.listByPrefix(UtilIO.pathExample("calibration/stereo/Bumblebee2_Square"),"left");
}


/**
// Chessboard Example
* Process calibration images, compute intrinsic parameters, save to a file
detector = FactoryFiducialCalibration.chessboard(new ConfigChessboard(7, 5, 30));
*/
images = UtilIO.listByPrefix(UtilIO.pathExample("calibration/stereo/Bumblebee2_Chess"),"left", null);
public void process() {


// Declare and setup the calibration algorithm
// Declare and setup the calibration algorithm
CalibrateMonoPlanar calibrationAlg = new CalibrateMonoPlanar(detector);
CalibrateMonoPlanar calibrationAlg = new CalibrateMonoPlanar(detector.getLayout());


// tell it type type of target and which parameters to estimate
// tell it type type of target and which parameters to estimate
calibrationAlg.configure( true, 2, false);
calibrationAlg.configurePinhole( true, 2, false);


for( String n : images ) {
for( String n : images ) {
BufferedImage input = UtilImageIO.loadImage(n);
BufferedImage input = UtilImageIO.loadImage(n);
if( n != null ) {
if( input != null ) {
ImageFloat32 image = ConvertBufferedImage.convertFrom(input,(ImageFloat32)null);
GrayF32 image = ConvertBufferedImage.convertFrom(input,(GrayF32)null);
if( !calibrationAlg.addImage(image) )
if( detector.process(image)) {
System.err.println("Failed to detect target in "+n);
calibrationAlg.addImage(detector.getDetectedPoints().copy());
} else {
System.err.println("Failed to detect target in " + n);
}
}
}
}
}
// process and compute intrinsic parameters
// process and compute intrinsic parameters
IntrinsicParameters intrinsic = calibrationAlg.process();
CameraPinholeRadial intrinsic = calibrationAlg.process();


// save results to a file and print out
// save results to a file and print out
UtilIO.saveXML(intrinsic, "intrinsic.xml");
CalibrationIO.save(intrinsic, "intrinsic.yaml");


calibrationAlg.printStatistics();
calibrationAlg.printStatistics();
Line 106: Line 89:
System.out.println();
System.out.println();
intrinsic.print();
intrinsic.print();
}
public static void main( String args[] ) {
ExampleCalibrateMonocular alg = new ExampleCalibrateMonocular();
// which target should it process
// alg.setupZhang99();
alg.setupBumbleBee();
// compute and save results
alg.process();
}
}
}
}
</syntaxhighlight>
</syntaxhighlight>

Revision as of 20:50, 26 December 2018

This example demonstrates how to use a high level calibration class that automatically detects calibration targets as viewed from a single (monocular) camera in a set of images. After processing the images the intrinsic camera parameters and lens distortion are saved to an XML file. 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: ExampleCalibrateMonocular.java

Calibration Tutorial: Wikipage

Concepts:

  • Camera calibration
  • Lens distortion
  • Intrinsic parameters

Related Examples:

Example Code

/**
 * Example of how to calibrate a single (monocular) camera using a high level interface. Depending on the calibration
 * target detector and target type, the entire target might need to be visible in the image. All camera images
 * should be in focus and that target evenly spread through out the images. In particular the edges of the image
 * should be covered.
 *
 * After processing both intrinsic camera parameters and lens distortion are estimated.  Square grid and chessboard
 * targets are demonstrated by this example. See calibration tutorial for a discussion of different target types
 * and how to collect good calibration images.
 *
 * All the image processing and calibration is taken care of inside of {@link CalibrateMonoPlanar}.  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.
 *
 * @see CalibrateMonoPlanar
 *
 * @author Peter Abeles
 */
public class ExampleCalibrateMonocular {
	public static void main( String args[] ) {
		DetectorFiducialCalibration detector;
		List<String> images;

		// Regular Circle Example
//		detector = FactoryFiducialCalibration.circleRegularGrid(new ConfigCircleRegularGrid(8, 10, 1.5, 2.5));
//		images = UtilIO.listByPrefix(UtilIO.pathExample("calibration/mono/Sony_DSC-HX5V_CircleRegular"),"image");

		// Hexagonal Circle Example
//		detector = FactoryFiducialCalibration.circleHexagonalGrid(new ConfigCircleHexagonalGrid(24, 28, 1, 1.2));
//		images = UtilIO.listByPrefix(UtilIO.pathExample("calibration/mono/Sony_DSC-HX5V_CircleHexagonal"),"image");

		// Square Grid example
//		detector = FactoryFiducialCalibration.squareGrid(new ConfigSquareGrid(4, 3, 30, 30));
//		images = UtilIO.listByPrefix(UtilIO.pathExample("calibration/stereo/Bumblebee2_Square"),"left");

		// Chessboard Example
		detector = FactoryFiducialCalibration.chessboard(new ConfigChessboard(7, 5, 30));
		images = UtilIO.listByPrefix(UtilIO.pathExample("calibration/stereo/Bumblebee2_Chess"),"left", null);

		// Declare and setup the calibration algorithm
		CalibrateMonoPlanar calibrationAlg = new CalibrateMonoPlanar(detector.getLayout());

		// tell it type type of target and which parameters to estimate
		calibrationAlg.configurePinhole( true, 2, false);

		for( String n : images ) {
			BufferedImage input = UtilImageIO.loadImage(n);
			if( input != null ) {
				GrayF32 image = ConvertBufferedImage.convertFrom(input,(GrayF32)null);
				if( detector.process(image)) {
					calibrationAlg.addImage(detector.getDetectedPoints().copy());
				} else {
					System.err.println("Failed to detect target in " + n);
				}
			}
		}
		// process and compute intrinsic parameters
		CameraPinholeRadial intrinsic = calibrationAlg.process();

		// save results to a file and print out
		CalibrationIO.save(intrinsic, "intrinsic.yaml");

		calibrationAlg.printStatistics();
		System.out.println();
		System.out.println("--- Intrinsic Parameters ---");
		System.out.println();
		intrinsic.print();
	}
}