use std::error::Error;
use std::fs;
use opencv::core::{
no_array, Point2f, Point3f, Size, TermCriteria, TermCriteria_EPS, TermCriteria_MAX_ITER, TermCriteria_Type, Vector,
};
use opencv::prelude::*;
use opencv::{highgui, imgcodecs, imgproc, opencv_branch_34, opencv_branch_4, opencv_branch_5};
opencv_branch_5! {
use opencv::calib::{find_chessboard_corners_def, draw_chessboard_corners, calibrate_camera};
use opencv::mod_3d::{undistort, init_undistort_rectify_map};
}
opencv_branch_4! {
use opencv::calib3d::{find_chessboard_corners_def, draw_chessboard_corners, calibrate_camera, undistort, init_undistort_rectify_map};
}
opencv_branch_34! {
use opencv::calib3d::{find_chessboard_corners_def, draw_chessboard_corners, calibrate_camera};
use opencv::imgproc::{undistort, init_undistort_rectify_map};
}
fn main() -> Result<(), Box<dyn Error>> {
let criteria = TermCriteria {
typ: TermCriteria_EPS + TermCriteria_MAX_ITER,
max_count: 30,
epsilon: 0.001,
};
let objp_len = 6 * 7;
let objp = Vector::from_iter((0..objp_len).map(|i| Point3f::new((i % 7) as f32, (i / 7) as f32, 0.)));
let images = fs::read_dir(".")?
.flatten()
.filter(|entry| entry.path().extension().is_some_and(|ext| ext == "jpg"));
for image in images {
let mut objpoints = Vector::<Vector<Point3f>>::new(); let mut imgpoints = Vector::<Vector<Point2f>>::new();
let mut img = imgcodecs::imread_def(image.path().to_string_lossy().as_ref())?;
let mut gray = Mat::default();
imgproc::cvt_color_def(&img, &mut gray, imgproc::COLOR_BGR2GRAY)?;
let mut corners = Vector::<Point2f>::default();
let ret = find_chessboard_corners_def(&gray, Size::new(7, 6), &mut corners)?;
if ret {
objpoints.push(objp.clone());
imgproc::corner_sub_pix(&gray, &mut corners, Size::new(11, 11), Size::new(-1, -1), criteria)?;
draw_chessboard_corners(&mut img, Size::new(7, 6), &corners, ret)?;
highgui::imshow("Source", &img)?;
imgpoints.push(corners);
let mut mtx = Mat::default();
let mut dist = Mat::default();
let mut rvecs = Vector::<Mat>::new();
let mut tvecs = Vector::<Mat>::new();
calibrate_camera(
&objpoints,
&imgpoints,
gray.size()?,
&mut mtx,
&mut dist,
&mut rvecs,
&mut tvecs,
0,
TermCriteria::new(
i32::from(TermCriteria_Type::COUNT) + i32::from(TermCriteria_Type::EPS),
30,
f64::EPSILON,
)?,
)?;
let mut dst_undistort = Mat::default();
undistort(&img, &mut dst_undistort, &mtx, &dist, &no_array())?;
highgui::imshow("Result using undistort", &dst_undistort)?;
let mut mapx = Mat::default();
let mut mapy = Mat::default();
init_undistort_rectify_map(
&mtx,
&dist,
&no_array(),
&no_array(),
img.size()?,
f32::opencv_type(),
&mut mapx,
&mut mapy,
)?;
let mut dst_remap = Mat::default();
imgproc::remap_def(&img, &mut dst_remap, &mapx, &mapy, imgproc::INTER_LINEAR)?;
highgui::imshow("Result using remap", &dst_undistort)?;
highgui::wait_key_def()?;
}
}
highgui::destroy_all_windows()?;
Ok(())
}