Difference between revisions of "Example Calibration Target Pose"
From BoofCV
Jump to navigationJump to searchm  | 
				m  | 
				||
| (3 intermediate revisions by the same user not shown) | |||
| Line 4: | Line 4: | ||
Example Code:  | Example Code:  | ||
* [https://github.com/lessthanoptimal/BoofCV/blob/v0.  | * [https://github.com/lessthanoptimal/BoofCV/blob/v0.40/examples/src/main/java/boofcv/examples/fiducial/ExamplePoseOfCalibrationTarget.java ExamplePoseOfCalibrationTarget.java]  | ||
Concepts:  | Concepts:  | ||
| Line 31: | Line 31: | ||
  */  |   */  | ||
public class ExamplePoseOfCalibrationTarget {  | public class ExamplePoseOfCalibrationTarget {  | ||
	public static void main( String[] args ) {  | |||
	public static void main( String   | |||
		// Load camera calibration  | 		// Load camera calibration  | ||
		CameraPinholeBrown intrinsic =  | 		CameraPinholeBrown intrinsic =  | ||
| Line 46: | Line 44: | ||
		// Let's use the FiducialDetector interface since it is much easier than coding up  | 		// Let's use the FiducialDetector interface since it is much easier than coding up  | ||
		// the entire thing ourselves.   | 		// the entire thing ourselves. Look at FiducialDetector's code if you want to understand how it works.  | ||
		CalibrationFiducialDetector<GrayF32> detector =  | 		CalibrationFiducialDetector<GrayF32> detector =  | ||
				FactoryFiducial.  | 				FactoryFiducial.calibChessboardX(null, new ConfigGridDimen(4, 5, 0.03), GrayF32.class);  | ||
		detector.setLensDistortion(lensDistortion,intrinsic.width,intrinsic.height);  | 		detector.setLensDistortion(lensDistortion, intrinsic.width, intrinsic.height);  | ||
		// Get the 2D coordinate of calibration points for visualization purposes  | 		// Get the 2D coordinate of calibration points for visualization purposes  | ||
| Line 60: | Line 58: | ||
		viewer.setTranslationStep(0.01);  | 		viewer.setTranslationStep(0.01);  | ||
		viewer.setBackgroundColor(0xFFFFFF); // white background  | 		viewer.setBackgroundColor(0xFFFFFF); // white background  | ||
		// make the view more interest.   | 		// make the view more interest. From the side.  | ||
		DMatrixRMaj rotY = ConvertRotation3D_F64.rotY(-Math.PI/2.0,null);  | 		DMatrixRMaj rotY = ConvertRotation3D_F64.rotY(-Math.PI/2.0, null);  | ||
		viewer.setCameraToWorld(new Se3_F64(rotY,new Vector3D_F64(0.75,0,1.25)).invert(null));  | 		viewer.setCameraToWorld(new Se3_F64(rotY, new Vector3D_F64(0.75, 0, 1.25)).invert(null));  | ||
		var imagePanel = new ImagePanel(intrinsic.width, intrinsic.height);  | |||
		var viewerComponent = viewer.getComponent();  | |||
		viewerComponent.setPreferredSize(new Dimension(intrinsic.width,intrinsic.height));  | 		viewerComponent.setPreferredSize(new Dimension(intrinsic.width, intrinsic.height));  | ||
		var gui = new PanelGridPanel(1, imagePanel, viewerComponent);  | |||
		gui.setMaximumSize(gui.getPreferredSize());  | 		gui.setMaximumSize(gui.getPreferredSize());  | ||
		ShowImages.showWindow(gui,"Calibration Target Pose",true);  | 		ShowImages.showWindow(gui, "Calibration Target Pose", true);  | ||
		// Allows the user to click on the image and pause  | 		// Allows the user to click on the image and pause  | ||
		var pauseHelper = new MousePauseHelper(gui);  | |||
		// saves the target's center location  | 		// saves the target's center location  | ||
		var path = new ArrayList<Point3D_F64>();  | |||
		// Process each frame in the video sequence  | 		// Process each frame in the video sequence  | ||
		var targetToCamera = new Se3_F64();  | |||
		while( video.hasNext() ) {  | 		while (video.hasNext()) {  | ||
			// detect calibration points  | 			// detect calibration points  | ||
			detector.detect(video.next());  | 			detector.detect(video.next());  | ||
			if( detector.totalFound() == 1 ) {  | 			if (detector.totalFound() == 1) {  | ||
				detector.getFiducialToCamera(0, targetToCamera);  | 				detector.getFiducialToCamera(0, targetToCamera);  | ||
				// Visualization.   | 				// Visualization. Show a path with green points and the calibration points in black  | ||
				viewer.clearPoints();  | 				viewer.clearPoints();  | ||
| Line 105: | Line 102: | ||
			}  | 			}  | ||
			imagePanel.setImage((BufferedImage) video.getGuiImage());  | 			imagePanel.setImage((BufferedImage)video.getGuiImage());  | ||
			viewerComponent.repaint();  | 			viewerComponent.repaint();  | ||
			imagePanel.repaint();  | 			imagePanel.repaint();  | ||
			BoofMiscOps.pause(30);  | 			BoofMiscOps.pause(30);  | ||
			while( pauseHelper.isPaused() ) {  | 			while (pauseHelper.isPaused()) {  | ||
				BoofMiscOps.pause(30);  | 				BoofMiscOps.pause(30);  | ||
			}  | 			}  | ||
Latest revision as of 14:45, 17 January 2022
In addition to calibration, calibration targets can be used to estimate the pose of objects in the scene to a high degree of accuracy. The location of calibration points can be estimated to a high degree of accuracy in the image making this approach more accurate than more generate purpose fiducials. How accurate is a function of distance and orientation.
Example Code:
Concepts:
- Calibration target
 - Pose estimation
 
Related Examples:
Videos
Example Code
/**
 * The 6-DOF pose of calibration targets can be estimated very accurately[*] once a camera has been calibrated.
 * In this example the high level FiducialDetector interface is used with a chessboard calibration target to
 * process a video sequence. Once the pose of the target is known the location of each calibration point is
 * found in the camera frame and visualized.
 *
 * [*] Accuracy is dependent on a variety of factors. Calibration targets are primarily designed to be viewed up close
 * and their accuracy drops with range, as can be seen in this example.
 *
 * @author Peter Abeles
 */
public class ExamplePoseOfCalibrationTarget {
	public static void main( String[] args ) {
		// Load camera calibration
		CameraPinholeBrown intrinsic =
				CalibrationIO.load(UtilIO.pathExample("calibration/mono/Sony_DSC-HX5V_Chess/intrinsic.yaml"));
		LensDistortionNarrowFOV lensDistortion = new LensDistortionBrown(intrinsic);
		// load the video file
		String fileName = UtilIO.pathExample("tracking/chessboard_SonyDSC_01.mjpeg");
		SimpleImageSequence<GrayF32> video =
				DefaultMediaManager.INSTANCE.openVideo(fileName, ImageType.single(GrayF32.class));
//				DefaultMediaManager.INSTANCE.openCamera(null, 640, 480, ImageType.single(GrayF32.class));
		// Let's use the FiducialDetector interface since it is much easier than coding up
		// the entire thing ourselves. Look at FiducialDetector's code if you want to understand how it works.
		CalibrationFiducialDetector<GrayF32> detector =
				FactoryFiducial.calibChessboardX(null, new ConfigGridDimen(4, 5, 0.03), GrayF32.class);
		detector.setLensDistortion(lensDistortion, intrinsic.width, intrinsic.height);
		// Get the 2D coordinate of calibration points for visualization purposes
		List<Point2D_F64> calibPts = detector.getCalibrationPoints();
		// Set up visualization
		PointCloudViewer viewer = VisualizeData.createPointCloudViewer();
		viewer.setCameraHFov(PerspectiveOps.computeHFov(intrinsic));
		viewer.setTranslationStep(0.01);
		viewer.setBackgroundColor(0xFFFFFF); // white background
		// make the view more interest. From the side.
		DMatrixRMaj rotY = ConvertRotation3D_F64.rotY(-Math.PI/2.0, null);
		viewer.setCameraToWorld(new Se3_F64(rotY, new Vector3D_F64(0.75, 0, 1.25)).invert(null));
		var imagePanel = new ImagePanel(intrinsic.width, intrinsic.height);
		var viewerComponent = viewer.getComponent();
		viewerComponent.setPreferredSize(new Dimension(intrinsic.width, intrinsic.height));
		var gui = new PanelGridPanel(1, imagePanel, viewerComponent);
		gui.setMaximumSize(gui.getPreferredSize());
		ShowImages.showWindow(gui, "Calibration Target Pose", true);
		// Allows the user to click on the image and pause
		var pauseHelper = new MousePauseHelper(gui);
		// saves the target's center location
		var path = new ArrayList<Point3D_F64>();
		// Process each frame in the video sequence
		var targetToCamera = new Se3_F64();
		while (video.hasNext()) {
			// detect calibration points
			detector.detect(video.next());
			if (detector.totalFound() == 1) {
				detector.getFiducialToCamera(0, targetToCamera);
				// Visualization. Show a path with green points and the calibration points in black
				viewer.clearPoints();
				Point3D_F64 center = new Point3D_F64();
				SePointOps_F64.transform(targetToCamera, center, center);
				path.add(center);
				for (Point3D_F64 p : path) {
					viewer.addPoint(p.x, p.y, p.z, 0x00FF00);
				}
				for (int j = 0; j < calibPts.size(); j++) {
					Point2D_F64 p = calibPts.get(j);
					Point3D_F64 p3 = new Point3D_F64(p.x, p.y, 0);
					SePointOps_F64.transform(targetToCamera, p3, p3);
					viewer.addPoint(p3.x, p3.y, p3.z, 0);
				}
			}
			imagePanel.setImage((BufferedImage)video.getGuiImage());
			viewerComponent.repaint();
			imagePanel.repaint();
			BoofMiscOps.pause(30);
			while (pauseHelper.isPaused()) {
				BoofMiscOps.pause(30);
			}
		}
	}
}
