Difference between revisions of "Example Calibration Target Pose"
From BoofCV
Jump to navigationJump to searchm |
m |
||
(15 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
[[file:Example_calibration_pose.jpg|frame|center|Left: Last image in video sequence. Right: Side view in 3D. Green dots is the target's trajectory and black dots are calibration points in the last frame.]] | [[file:Example_calibration_pose.jpg|frame|center|Left: Last image in video sequence. Right: Side view in 3D. Green dots is the target's trajectory and black dots are calibration points in the last frame.]] | ||
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 | 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: | 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 13: | Line 12: | ||
Related Examples: | Related Examples: | ||
* [[Example_Detect_Calibration_Target| Detecting Calibration Target]] | * [[Example_Detect_Calibration_Target| Detecting Calibration Target]] | ||
Videos | |||
* [https://youtu.be/qJWDK_FrgHE Fiducial Overview] | |||
= Example Code = | = Example Code = | ||
Line 18: | Line 20: | ||
<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 | ||
*/ | */ | ||
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 = | |||
UtilIO. | CalibrationIO.load(UtilIO.pathExample("calibration/mono/Sony_DSC-HX5V_Chess/intrinsic.yaml")); | ||
LensDistortionNarrowFOV lensDistortion = new LensDistortionBrown(intrinsic); | |||
// load the video file | // load the video file | ||
String fileName = " | String fileName = UtilIO.pathExample("tracking/chessboard_SonyDSC_01.mjpeg"); | ||
SimpleImageSequence< | SimpleImageSequence<GrayF32> video = | ||
DefaultMediaManager.INSTANCE.openVideo(fileName, ImageType.single( | 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 | // Set up visualization | ||
PointCloudViewer viewer = VisualizeData.createPointCloudViewer(); | |||
viewer.setCameraHFov(PerspectiveOps.computeHFov(intrinsic)); | |||
// make the view more interest. | viewer.setTranslationStep(0.01); | ||
viewer.setBackgroundColor(0xFFFFFF); // white background | |||
viewer. | // 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)); | |||
ShowImages.showWindow(gui,"Calibration Target Pose"); | 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 | // 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 | ||
while( video.hasNext() ) { | var targetToCamera = new Se3_F64(); | ||
while (video.hasNext()) { | |||
// detect calibration points | // 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. | imagePanel.setImage((BufferedImage)video.getGuiImage()); | ||
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);
}
}
}
}