Skip to content

Commit 8213bd9

Browse files
committed
Add camera_calibration example
1 parent 6938fb4 commit 8213bd9

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

ci/script.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ fi
7373
# remove tests and examples that require the latest OpenCV version so that they don't fail due to missing modules
7474
if [[ "${OPENCV_VERSION:-}" != "4.10.0" ]]; then
7575
rm -vf tests/*_only_latest_opencv.rs
76-
rm -vf examples/dnn_face_detect.rs examples/text_detection.rs
76+
rm -vf examples/dnn_face_detect.rs examples/text_detection.rs examples/camera_calibration.rs
7777
fi
7878

7979
echo "=== Current directory: $(pwd)"

examples/camera_calibration.rs

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//! Port of code from the tutorial at: https://docs.opencv.org/4.x/dc/dbb/tutorial_py_calibration.html
2+
3+
use std::error::Error;
4+
use std::fs;
5+
6+
use opencv::core::{no_array, Point2f, Point3f, Size, TermCriteria, TermCriteria_EPS, TermCriteria_MAX_ITER, Vector};
7+
use opencv::prelude::*;
8+
use opencv::{calib3d, highgui, imgcodecs, imgproc};
9+
10+
fn main() -> Result<(), Box<dyn Error>> {
11+
// termination criteria
12+
let criteria = TermCriteria {
13+
typ: TermCriteria_EPS + TermCriteria_MAX_ITER,
14+
max_count: 30,
15+
epsilon: 0.001,
16+
};
17+
18+
// prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
19+
let objp_len = 6 * 7;
20+
let objp = Vector::from_iter((0..objp_len).map(|i| Point3f::new((i % 7) as f32, (i / 7) as f32, 0.)));
21+
22+
let images = fs::read_dir(".")?
23+
.into_iter()
24+
.flatten()
25+
.filter(|entry| entry.path().extension().map_or(false, |ext| ext == "jpg"));
26+
27+
for image in images {
28+
// Arrays to store object points and image points from all the images.
29+
let mut objpoints = Vector::<Vector<Point3f>>::new(); // 3d point in real world space
30+
let mut imgpoints = Vector::<Vector<Point2f>>::new(); // 2d points in image plane.
31+
32+
let mut img = imgcodecs::imread_def(image.path().to_string_lossy().as_ref())?;
33+
let mut gray = Mat::default();
34+
imgproc::cvt_color_def(&img, &mut gray, imgproc::COLOR_BGR2GRAY)?;
35+
36+
let mut corners = Vector::<Point2f>::default();
37+
let ret = calib3d::find_chessboard_corners_def(&gray, Size::new(7, 6), &mut corners)?;
38+
if ret {
39+
objpoints.push(objp.clone());
40+
41+
imgproc::corner_sub_pix(&gray, &mut corners, Size::new(11, 11), Size::new(-1, -1), criteria)?;
42+
43+
// Draw and display the corners
44+
calib3d::draw_chessboard_corners(&mut img, Size::new(7, 6), &corners, ret)?;
45+
highgui::imshow("Source", &img)?;
46+
47+
imgpoints.push(corners);
48+
49+
// Calibration
50+
let mut mtx = Mat::default();
51+
let mut dist = Mat::default();
52+
let mut rvecs = Vector::<Mat>::new();
53+
let mut tvecs = Vector::<Mat>::new();
54+
calib3d::calibrate_camera_def(
55+
&objpoints,
56+
&imgpoints,
57+
gray.size()?,
58+
&mut mtx,
59+
&mut dist,
60+
&mut rvecs,
61+
&mut tvecs,
62+
)?;
63+
64+
// Using cv.undistort()
65+
let mut dst_undistort = Mat::default();
66+
calib3d::undistort_def(&img, &mut dst_undistort, &mtx, &dist)?;
67+
highgui::imshow("Result using undistort", &dst_undistort)?;
68+
69+
// Using remapping
70+
let mut mapx = Mat::default();
71+
let mut mapy = Mat::default();
72+
calib3d::init_undistort_rectify_map(
73+
&mtx,
74+
&dist,
75+
&no_array(),
76+
&no_array(),
77+
img.size()?,
78+
f32::opencv_type(),
79+
&mut mapx,
80+
&mut mapy,
81+
)?;
82+
let mut dst_remap = Mat::default();
83+
imgproc::remap_def(&img, &mut dst_remap, &mapx, &mapy, imgproc::INTER_LINEAR)?;
84+
highgui::imshow("Result using remap", &dst_undistort)?;
85+
86+
highgui::wait_key_def()?;
87+
}
88+
}
89+
highgui::destroy_all_windows()?;
90+
Ok(())
91+
}

0 commit comments

Comments
 (0)