//use opencv::Result; //use opencv::core::{self, Mat}; static DEBUG: bool = true; pub mod annalyse; pub mod borders; pub mod compute_image; use std::env::args; use std::time::Instant; use crate::draw::{draw_line, draw_line_dotted}; use crate::point::{Color, Point}; use enum_iterator::{next, Sequence as Seq}; use opencv::core::Mat; use opencv::Result; use std::f64::consts::PI; use opencv::core::{bitwise_and, find_file, in_range, Point as OcvPoint, Scalar, Size, Size_}; use opencv::core::{VecN, Vector}; use opencv::imgcodecs::imwrite; use opencv::imgcodecs::{imread, IMREAD_COLOR}; use opencv::imgproc::{canny, cvt_color, line, COLOR_BGR2GRAY}; use opencv::prelude::*; use opencv::{ highgui, videoio::{self, VideoCapture}, }; use std::fs::create_dir; use std::fs::read_dir; mod init_border; mod load_image; mod save_image; mod wait_space; use init_border::InitBorder; use load_image::LoadImage; use save_image::SaveImage; use wait_space::WaitSpace; //impl Clone for dyn Sequence { // fn clone() { // } //} #[derive(Debug, Clone)] pub struct HoughLine { pub rho: i32, pub theta: i32, pub treshold: i32, pub min_length: i32, pub max_line_gap: i32, } // ca c'est les donner qu'on envoie a la fonction pub struct HoughLineValue { pub rho: f64, pub theta: f64, pub treshold: i32, pub min_length: f64, pub max_line_gap: f64, } impl HoughLine { pub fn get_param(&self) -> HoughLineValue { HoughLineValue { rho: self.rho as f64 / 100., theta: self.theta as f64 / 100. * PI / 180., treshold: self.treshold, min_length: self.min_length as f64 / 100., max_line_gap: self.max_line_gap as f64 / 100., } } } #[derive(Clone, Debug)] pub struct Treshold { pub win_name: String, pub min_0: i32, pub min_1: i32, pub min_2: i32, pub max_0: i32, pub max_1: i32, pub max_2: i32, } impl Treshold { pub fn new(name: &str, min: i32, max: i32) -> Result { let tresh = Treshold { win_name: name.to_owned(), min_0: min, min_1: min, min_2: min, max_0: max, max_1: max, max_2: max, }; Ok(tresh) } } //impl //#[derive(Copy)] pub trait Sequence { fn draw(&self, mem: &Param) -> Option>; fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box>; fn is_capture(&self) -> bool; } impl std::fmt::Debug for dyn Sequence { fn fmt(self: &Self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{self:?}") } } #[derive(Clone, Debug)] pub struct Param { seq_id: usize, imgs: Vec>, dst_size: i32, r: i32, g: i32, b: i32, nb_all: i32, nb_visible: i32, nb_liss: i32, tresh: Treshold, canny_v1: i32, canny_v2: i32, hough_param: HoughLine, border_pt: Vec<(f64, f64)>, homography: Mat, h_size: Size_, line_pos: Vec, multiple: u16, // le nombre de fois qu'une photo est prise pour certaine sequence pub key: i32, dir_name: String, begin: Instant, pub capture_mode: bool, } impl Param { fn save_image(&self) -> Result<()> { let now = self.begin; let img_root = format!("image"); create_dir(&img_root).unwrap_or(()); let new_dir = format!( "{img_root}/{:0>6?}_{:0>9?}", now.elapsed().as_millis(), now.elapsed().as_nanos() ); create_dir(&new_dir).unwrap_or(()); for (i, img_seq) in self.imgs.iter().enumerate() { let seq_dir_name = format!("{new_dir}/{i}"); create_dir(&seq_dir_name).unwrap_or(()); for img in img_seq { let mut name_img = format!("{seq_dir_name}/"); name_img.push_str(&format!("img_{i}.png")); imwrite(&name_img, img, &Vector::from_slice(&[6, 6, 6, 0]))?; } } Ok(()) } fn load_image(&mut self) -> Result<(), Box> { let mut imgs = vec![]; let paths = read_dir(&self.dir_name)?; for entry in paths { let mut seq_img = vec![]; let dir = entry?; let path = dir.path(); // sequence directory let names: Vec<&str> = path.to_str().unwrap().split("/").collect(); let seq_id: usize = names[names.len() - 1].parse()?; for entry in read_dir(&path)? { let sub_path = entry?.path(); let names: Vec<&str> = path.to_str().unwrap().split("/").collect(); let img_name = names[names.len() - 1]; let img_id: usize = img_name[4..img_name.len() - 4].parse()?; let img: Mat = imread( &find_file(&sub_path.to_str().unwrap(), false, false)?, IMREAD_COLOR, )?; seq_img.push((img_id, img)); } imgs.push((seq_id, seq_img)); } self.imgs = vec![vec![]; imgs.len()]; for (seq_id, seq_img) in imgs { self.imgs[seq_id] = vec![Mat::default(); seq_img.len()]; for (img_id, img) in seq_img { self.imgs[seq_id][img_id] = img; } } Ok(()) } } #[derive(Debug)] pub struct Qualibration { seq: Vec>, cam: VideoCapture, cnt: usize, pub param: Param, } impl Qualibration { pub fn new() -> Result { //let v: Vec> = vec![]; let mut dir_name = "".to_string(); //"building.jpg".to_string(); // by default if let Some(dir_name_arg) = args().nth(1) { dir_name = dir_name_arg; } let mut cam = videoio::VideoCapture::new(0, videoio::CAP_ANY)?; // 0 is the default camera ; let opened_cam = videoio::VideoCapture::is_opened(&cam)?; if !opened_cam { panic!("Unable to open default camera!"); } let mut frame = Mat::default(); cam.read(&mut frame)?; let beg = Point::from((0., 0., 38400)); // r:150, v:0, b:0 let end = Point::from((4095., 4095., 38400)); // r:150, v:0, b:0 let seq: Vec> = vec![ Box::new(LoadImage::new()), Box::new(WaitSpace::new()), Box::new(InitBorder::new(beg, end)), Box::new(SaveImage::new()), ]; //let now = std::time::Instant::now(); Ok(Qualibration { seq, cam, cnt: 0, param: Param { begin: std::time::Instant::now(), dir_name: dir_name.clone(), capture_mode: dir_name.len() == 0, key: -1, imgs: vec![vec![]], seq_id: 0, dst_size: 900, r: 150, g: 0, b: 0, nb_all: 120, nb_visible: 40, nb_liss: 10, tresh: Treshold::new("histogram", 160, 255)?, canny_v1: 170, canny_v2: 255, hough_param: HoughLine { rho: 100, theta: 100, treshold: 30, min_length: 0, max_line_gap: 50000, }, border_pt: vec![], homography: Mat::default(), h_size: Size::default(), line_pos: vec![4095; 34], multiple: 20, }, }) } pub fn draw_sequence(&mut self) -> Option> { if self.param.seq_id >= self.seq.len() { return None; } let pl = self.seq[self.param.seq_id].draw(&self.param); if pl.is_none() { self.param.seq_id += 1; if self.param.capture_mode { self.param.imgs.push(vec![]); } } pl } pub fn run_step(self: &mut Self) -> Result<(), Box> { let mut frame = Mat::default(); if self.param.capture_mode { self.cam.read(&mut frame)?; highgui::imshow("camera", &frame)?; if frame.size()?.width > 0 && self.seq[self.param.seq_id].is_capture() { self.param.imgs[self.param.seq_id].push(frame.clone()); } } if frame.size()?.width > 0 || !self.param.capture_mode { self.seq[self.param.seq_id].compute_sequence(&mut self.param)?; } self.cnt += 1; Ok(()) } }