lj_qualibration/src/qualib_refacto.rs

314 lines
8.5 KiB
Rust

//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<Self> {
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<Vec<Point>>;
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>>;
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<Vec<Mat>>,
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_<i32>,
line_pos: Vec<i32>,
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<dyn std::error::Error>> {
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<Box<dyn Sequence>>,
cam: VideoCapture,
cnt: usize,
pub param: Param,
}
impl Qualibration {
pub fn new() -> Result<Self> {
//let v: Vec<Box<dyn Sequence>> = 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<Box<dyn Sequence>> = 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<Vec<Point>> {
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<dyn std::error::Error>> {
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(())
}
}