|  | 
|  | 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