Difference between revisions of "Example Calibration Target Pose"
From BoofCV
Jump to navigationJump to searchm |
m |
||
Line 5: | Line 5: | ||
Example Code: | Example Code: | ||
* [https://github.com/lessthanoptimal/BoofCV/blob/v0. | * [https://github.com/lessthanoptimal/BoofCV/blob/v0.19/examples/src/boofcv/examples/fiducial/ExamplePoseOfCalibrationTarget.java ExamplePoseOfCalibrationTarget.java] | ||
Concepts: | Concepts: | ||
Line 18: | Line 18: | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
/** | /** | ||
* The 6-DOF pose of calibration targets | * 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 | * @author Peter Abeles | ||
Line 32: | Line 35: | ||
IntrinsicParameters intrinsic = | IntrinsicParameters intrinsic = | ||
UtilIO.loadXML("../data/applet/calibration/mono/Sony_DSC-HX5V_Chess/intrinsic.xml"); | UtilIO.loadXML("../data/applet/calibration/mono/Sony_DSC-HX5V_Chess/intrinsic.xml"); | ||
// load the video file | // load the video file | ||
Line 40: | Line 41: | ||
DefaultMediaManager.INSTANCE.openVideo(fileName, ImageType.single(ImageFloat32.class)); | DefaultMediaManager.INSTANCE.openVideo(fileName, ImageType.single(ImageFloat32.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<ImageFloat32> detector = | ||
FactoryFiducial.calibChessboard(new ConfigChessboard(5, 4, 0.03),ImageFloat32.class); | |||
detector.setIntrinsic(intrinsic); | |||
// | // Get the 2D coordinate of calibration points for visualization purposes | ||
List<Point2D_F64> calibPts = detector.getCalibrationPoints(); | |||
// Set up visualization | // Set up visualization | ||
Line 62: | Line 57: | ||
DenseMatrix64F rotY = RotationMatrixGenerator.rotY(-Math.PI/2.0,null); | DenseMatrix64F rotY = RotationMatrixGenerator.rotY(-Math.PI/2.0,null); | ||
viewer.setWorldToCamera(new Se3_F64(rotY,new Vector3D_F64(0.75,0,1.25))); | viewer.setWorldToCamera(new Se3_F64(rotY,new Vector3D_F64(0.75,0,1.25))); | ||
ImagePanel imagePanel = new ImagePanel(width, height); | ImagePanel imagePanel = new ImagePanel(intrinsic.width, intrinsic.height); | ||
gui.add(BorderLayout.WEST, imagePanel); gui.add(BorderLayout.CENTER, viewer); | gui.add(BorderLayout.WEST, imagePanel); gui.add(BorderLayout.CENTER, viewer); | ||
ShowImages.showWindow(gui,"Calibration Target Pose"); | 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 | ||
Line 73: | Line 68: | ||
// Process each frame in the video sequence | // Process each frame in the video sequence | ||
Se3_F64 targetToCamera = new Se3_F64(); | |||
while( video.hasNext() ) { | while( video.hasNext() ) { | ||
// detect calibration points | // detect calibration points | ||
detector.detect(video.next()); | |||
if( detector.totalFound() == 0 ) | |||
continue; | |||
detector.getFiducialToCamera(0, targetToCamera); | |||
// Visualization. Show a path with green points and the calibration points in black | // Visualization. Show a path with green points and the calibration points in black | ||
Line 106: | Line 90: | ||
} | } | ||
for( int j = 0; j < | for( int j = 0; j < calibPts.size(); j++ ) { | ||
Point2D_F64 p = | Point2D_F64 p = calibPts.get(j); | ||
Point3D_F64 p3 = new Point3D_F64(p.x,p.y,0); | Point3D_F64 p3 = new Point3D_F64(p.x,p.y,0); | ||
SePointOps_F64.transform(targetToCamera,p3,p3); | SePointOps_F64.transform(targetToCamera,p3,p3); |
Revision as of 05:11, 16 September 2015
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 fidicuals. How accurate is a function of distance and orientation.
Example Code:
Concepts:
- Calibration target
- Pose estimation
Related Examples:
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
IntrinsicParameters intrinsic =
UtilIO.loadXML("../data/applet/calibration/mono/Sony_DSC-HX5V_Chess/intrinsic.xml");
// load the video file
String fileName = "../data/applet/tracking/chessboard_SonyDSC_01.mjpeg";
SimpleImageSequence<ImageFloat32> video =
DefaultMediaManager.INSTANCE.openVideo(fileName, ImageType.single(ImageFloat32.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<ImageFloat32> detector =
FactoryFiducial.calibChessboard(new ConfigChessboard(5, 4, 0.03),ImageFloat32.class);
detector.setIntrinsic(intrinsic);
// Get the 2D coordinate of calibration points for visualization purposes
List<Point2D_F64> calibPts = detector.getCalibrationPoints();
// Set up visualization
JPanel gui = new JPanel();
PointCloudViewer viewer = new PointCloudViewer(intrinsic, 0.01);
// make the view more interest. From the side.
DenseMatrix64F rotY = RotationMatrixGenerator.rotY(-Math.PI/2.0,null);
viewer.setWorldToCamera(new Se3_F64(rotY,new Vector3D_F64(0.75,0,1.25)));
ImagePanel imagePanel = new ImagePanel(intrinsic.width, intrinsic.height);
gui.add(BorderLayout.WEST, imagePanel); gui.add(BorderLayout.CENTER, viewer);
ShowImages.showWindow(gui,"Calibration Target Pose",true);
// Allows the user to click on the image and pause
MousePauseHelper pauseHelper = new MousePauseHelper(gui);
// saves the target's center location
List<Point3D_F64> path = new ArrayList<Point3D_F64>();
// Process each frame in the video sequence
Se3_F64 targetToCamera = new Se3_F64();
while( video.hasNext() ) {
// detect calibration points
detector.detect(video.next());
if( detector.totalFound() == 0 )
continue;
detector.getFiducialToCamera(0, targetToCamera);
// Visualization. Show a path with green points and the calibration points in black
viewer.reset();
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.setBufferedImage((BufferedImage) video.getGuiImage());
viewer.repaint();
imagePanel.repaint();
BoofMiscOps.pause(30);
while( pauseHelper.isPaused() ) {
BoofMiscOps.pause(30);
}
}
}
}