diff --git a/src/main.rs b/src/main.rs index 6ff052a..c9e6f12 100644 --- a/src/main.rs +++ b/src/main.rs @@ -87,36 +87,46 @@ fn run_all() -> Result<(), Box> { )?; while running.load(Ordering::SeqCst) { - let key = highgui::wait_key(20)?; - let v = qualibration.draw_sequence(); - - if key != -1 { - println!("key: {key}"); - // 81 <- -> 83 - } + //let _t = _framerate_handler.handle_time()?; + ///////////////// + let key = highgui::wait_key(1)?; qualibration.param.key = key; if key == 27 { - if qualibration.param.capture_mode { - qualibration.param.save_image()?; - } break; - } else if v.is_none() { - continue; } - if qualibration.param.capture_mode { - let pl: Vec<(f32, f32, u32)> = v - .unwrap() - .iter() - .map(|pt| (pt.x, pt.y, u32::from(pt.color))) - .collect(); - con.set( - format!("/pl/{}/{}", config.client_id, config.laser_id), - format!("{:?}", pl), - )?; - } + let v = qualibration.draw_sequence(); + if v.is_some() { + if qualibration.param.capture_mode { + let pl: Vec<(f32, f32, u32)> = v + .unwrap() + .iter() + .map(|pt| (pt.x, pt.y, u32::from(pt.color))) + .collect(); - qualibration.run_step()?; + let _ = con.set( + format!("/pl/{}/{}", config.client_id, config.laser_id), + format!("{:?}", pl), + )?; + } + + qualibration.run_step()?; + } + //qualibration.id = next_id; + + //let q_id = qualibration.id.clone(); + //let mut n = 65534; + //if let Sequence::TakeMultiple(m) = q_id.clone().unwrap_or(Sequence::Finish) { + // n = m; + //}; + //if qualibration.capture_mode + // && (q_id != Some(Sequence::WaitSpace) + // || q_id != Some(Sequence::PlayLineDotted) + // || n != 65534) + //{ + // let millis = std::time::Duration::from_millis(400); // TODO: find solution to know when change has been done + // std::thread::sleep(millis); + //} } let _ = con.set( @@ -125,21 +135,3 @@ fn run_all() -> Result<(), Box> { )?; Ok(()) } - -//let _t = _framerate_handler.handle_time()?; -///////////////// -//qualibration.id = next_id; - -//let q_id = qualibration.id.clone(); -//let mut n = 65534; -//if let Sequence::TakeMultiple(m) = q_id.clone().unwrap_or(Sequence::Finish) { -// n = m; -//}; -//if qualibration.capture_mode -// && (q_id != Some(Sequence::WaitSpace) -// || q_id != Some(Sequence::PlayLineDotted) -// || n != 65534) -//{ -// let millis = std::time::Duration::from_millis(400); // TODO: find solution to know when change has been done -// std::thread::sleep(millis); -//} diff --git a/src/qualibration.rs b/src/qualibration.rs index 2641e82..1737b67 100644 --- a/src/qualibration.rs +++ b/src/qualibration.rs @@ -37,7 +37,7 @@ pub struct Qualibration { } impl Qualibration { - pub fn new() -> Result> { + pub fn new() -> Result { //let v: Vec> = vec![]; let mut dir_name = "".to_string(); //"building.jpg".to_string(); // by default @@ -54,22 +54,24 @@ impl Qualibration { let mut frame = Mat::default(); cam.read(&mut frame)?; - // 9830400 -> r:150, v:0, b:0 - let beg = Point::from((0., 0., 9830400)); - let beg2 = Point::from((0., 4095., 9830400)); - let end = Point::from((4095., 4095., 9830400)); + // 38400 -> r:150, v:0, b:0 + let beg = Point::from((0., 0., 38400)); + let beg2 = Point::from((4095., 0., 38400)); + let end = Point::from((4095., 4095., 38400)); let seq: Vec> = vec![ - Box::new(WaitSpace::new(beg, end, 400)), - Box::new(InitBorder::new(beg, end, 400)), - Box::new(LineDotted::new(beg, end, 2, true, false, 400)), - //Box::new(InitIdcode::new(beg2, end, 400)), + Box::new(LoadImage::new()), + Box::new(WaitSpace::new(beg, end)), + Box::new(InitBorder::new(beg, end)), + Box::new(LineDotted::new(beg, end, true, false)), + Box::new(InitIdcode::new(beg2, end)), + Box::new(SaveImage::new()), ]; - let seq_names = get_sequence_name(&seq); - let mut param = Param::new(dir_name.to_owned(), seq_names)?; - if !param.capture_mode { - param.load_image()?; - } - Ok(Qualibration { seq, cam, param }) + //let now = std::time::Instant::now(); + Ok(Qualibration { + seq, + cam, + param: Param::new(dir_name.to_owned())?, + }) } pub fn draw_sequence(&mut self) -> Option> { @@ -90,23 +92,7 @@ impl Qualibration { } pub fn run_step(self: &mut Self) -> Result<(), Box> { - let seq_id = self.param.seq_id; - let seq_name = self.seq[seq_id].sequence_name(); - println!("\n\n\n\n\n\n\n\n"); - println!("\t\t=================================================================="); - println!("\t\t=================================================================="); - println!("\t\t=================================================================="); - println!("\n\n\n\n\n\n\n\n"); - println!("seq[{seq_id}]: {seq_name}"); - - if self.param.capture_mode { - let millis_nb = self.seq[self.param.seq_id].wait_milis(); - let millis = std::time::Duration::from_millis(millis_nb); // TODO: find solution to know when change has been done - std::thread::sleep(millis); - } - let mut frame = Mat::default(); - //println!("sequence: {}:{:?}", self.param.seq_id, &self.seq[self.param.seq_id]); if self.param.capture_mode { self.cam.read(&mut frame)?; highgui::imshow("camera", &frame)?; @@ -123,13 +109,3 @@ impl Qualibration { Ok(()) } } - -pub fn get_sequence_name(seq: &Vec>) -> Vec { - let mut v = vec![]; - - for i in 0..seq.len() { - v.push(seq[i].sequence_name()); - } - - v -} diff --git a/src/qualibration/annalyse.rs b/src/qualibration/annalyse.rs index 2c98cec..05e2e37 100644 --- a/src/qualibration/annalyse.rs +++ b/src/qualibration/annalyse.rs @@ -1,4 +1,3 @@ -use std::cmp::Ordering; use std::collections::HashSet; use std::f64::consts::PI; @@ -68,45 +67,6 @@ pub fn draw_histograme_dbg( Ok(()) } -#[allow(dead_code)] -pub fn draw_histograme_log(window_name: &str, histo: &Vec, is_log: bool) -> Result<()> { - let v: VecN = VecN::new(0., 0., 0., 255.); - let color: VecN = VecN::new(210., 210., 255., 255.); - let mut img = Mat::new_rows_cols_with_default( - histo.len() as i32 * 2, - histo.len() as i32 * 2, - CV_8UC3, - v, - )?; - - let mut max = f64::MIN; - for i in 0..histo.len() { - if histo[i] > max { - max = histo[i]; - } - } - - for i in 0..(histo.len() - 1) { - let x1 = ((i + 0) * 2) as i32; - let x2 = ((i + 1) * 2) as i32; - let (y1, y2); - if is_log { - y1 = ((1.-((histo[i + 0] as f64 + 1.).log10() / (max as f64).log10())) * 512.) as i32; - y2 = ((1.-((histo[i + 1] as f64 + 1.).log10() / (max as f64).log10())) * 512.) as i32; - } else { - y1 = ((1. - ((histo[i + 0] as f64) / (max as f64))) * 512.) as i32; - y2 = ((1. - ((histo[i + 1] as f64) / (max as f64))) * 512.) as i32; - } - let pt1 = OcvPoint::new(x1, y1); - let pt2 = OcvPoint::new(x2, y2); - line(&mut img, pt1, pt2, color, 1, LINE_AA, 0)?; - } - - highgui::imshow(window_name, &img)?; - - Ok(()) -} - #[allow(dead_code)] pub fn draw_histograme(window_name: &str, histo: &Vec) -> Result<()> { let v: VecN = VecN::new(0., 0., 0., 255.); @@ -419,618 +379,6 @@ pub fn get_horizontal_segment(m: &Mat) -> Result, - v_lst: Vec, - line: Vec, - nb_liss: i32, -} - -impl Line { - pub fn new( - pt_all: &mut HashSet<(i32, i32)>, - y_ordering: bool, - beg_lowest: bool, - nb_liss: i32, - ) -> Self { - let mut illand = Line { - h_lst: HashSet::new(), - v_lst: vec![], - line: vec![], - nb_liss, - }; - if pt_all.len() <= 0 { - return illand; - } - //dbg!(&pt_all); - illand.populate_hlst(pt_all); - - illand.define_line(); - //println!(""); - //illand.define_beg_end(false, beg_lowest); - //dbg!(&illand); - illand - } - - //fn define_beg_end(&mut self, y_ordering: bool, beg_lowest: bool) { - // // on a tout les point ordonner - // // on peut les re-ordonner selon un axes interne - //} - fn define_line(&mut self) { - // la ca va etre marant. - // - let mut last_id = 0; - let to_look = [ - (-1, -1), - (0, -1), - (1, -1), - (1, 0), - (1, 1), - (0, 1), - (-1, 1), - (-1, 0), - ]; - - if self.h_lst.len() == 0 { - return; - } - - // search botom-left point. - let mut first = (i32::MAX / 2, 0); - self.h_lst.iter().for_each(|(x, y)| { - if *y > first.1 || (*y == first.1 && *x < first.0) { - first = (*x, *y); - } - }); - - println!("\nfirst: {first:?}\n"); - - let mut ll = self.h_lst.clone(); - let mut l = vec![first]; - let (mut px, mut py) = first; - ll.remove(&first); - - // adding all borders point to a line - 'line: loop { - for k in 0..to_look.len() { - //let id = (k + last_id) % to_look.len(); - let (i, j) = to_look[(k + last_id) % to_look.len()]; - if ll.get(&(i + px, j + py)).is_some() { - l.push((i + px, j + py)); - ll.remove(&(i + px, j + py)); - (px, py) = (i + px, j + py); - last_id = (k + last_id + to_look.len() - 2) % to_look.len(); - continue 'line; - } - } - break; - } - - let (mut min_y, mut max_y) = (f64::MAX, f64::MIN); - let mut l_tmp: Vec = l - .iter() - .map(|(x, y)| { - min_y = (*y as f64).min(min_y); - max_y = (*y as f64).max(max_y); - Pt { - x: *x as f64, - y: *y as f64, - } - }) - .collect(); - - // lissage des point - let raw_pt = l_tmp.clone(); - //println!("[1]raw_pt:{:?}", &raw_pt); - let nb_liss = self.nb_liss * 2; - let (c1, c2) = (1., 48.); - for i in 0..nb_liss { - let mut nl = vec![]; - for i in 0..l_tmp.len() { - let (id_prev, id_next) = - ((i + l_tmp.len() - 1) % l_tmp.len(), (i + 1) % l_tmp.len()); - let (prev, pt, next) = (l_tmp[id_prev], l_tmp[i], l_tmp[id_next]); - - nl.push((prev * c1 + pt * c2 + next * c1) / (2. * c1 + c2)); - } - l_tmp = nl; - } - - let mut histo_ang = vec![0.; 256]; - let mut length_max = 0.; - for i in 0..l_tmp.len() { - let next = l_tmp[(i + 1) % l_tmp.len()]; - let diff = next - l_tmp[i]; - let ang = diff.y.atan2(diff.x); - let id = ((((ang + PI) / (2. * PI)) * 255.) as usize) % 256; - let length = (diff.x * diff.x + diff.y * diff.y).sqrt(); - length_max = length.max(length_max); - histo_ang[id] += 1.; - } - let _ = draw_histograme_log("histo ang", &histo_ang, false); - - let mut histo_ang_diff = vec![0.; 256]; - let mirange = 3; - let mut id_out = vec![0]; - for i in 0..l_tmp.len() { - let next = l_tmp[(i + 1) % l_tmp.len()]; - let next2 = l_tmp[(i + 2) % l_tmp.len()]; - let diff1 = next - l_tmp[i]; - let diff2 = next2 - next; - let ang1 = diff1.y.atan2(diff1.x); - let ang2 = diff2.y.atan2(diff2.x); - - let id = (((((ang2 - ang1) + PI) / (2. * PI)) * 255.) as usize) % 256; - if !(id >= 128 - mirange && id <= 128 + mirange) { - id_out.push(i); - //println!("id:{i}"); - } - histo_ang_diff[id] += 1.; - } - let _ = draw_histograme_log("histo ang diff", &histo_ang_diff, true); - - //let mut histo_lenght = vec![0.; 256]; - //for i in 0..l_tmp.len() { - // let next = l_tmp[(i + 1) % l_tmp.len()]; - // let diff = next - l_tmp[i]; - // //let ang = diff.y.atan2(diff.x); - // //let ang_id = ((ang / (2. * PI) * 256.) as usize) % 256; - // let length = (diff.x * diff.x + diff.y * diff.y).sqrt(); - // let id = (length / length_max * 255.) as usize % 256; - // histo_lenght[id] += 1.; - //} - // draw histo ang - // draw histo dst - //let _ = draw_histograme_log("histo length", &histo_lenght, false); - - // opposite side - // Le but c'est de trouver le point le plus proche mais pas un point voisin - // On va le dessiner pour une partie des point seulement - - - let mut diff = vec![]; - for i in 0..id_out.len()-1 { - let d = id_out[i+1] - id_out[i]; - diff.push((d, id_out[i], id_out[i+1])); - } - diff.sort_by(|a, b| { - match (a.0, b.0) { - (a, b) if a < b => Ordering::Greater, - (a, b) if a == b => Ordering::Equal, - _ => Ordering::Less, - } - }); - - if diff.len() < 2 { - return ; - } - let mut dio = vec![diff[0], diff[1]]; - dio.sort_by(|a, b| { - match (a.1, b.1) { - (a, b) if a > b => Ordering::Greater, - (a, b) if a == b => Ordering::Equal, - _ => Ordering::Less, - } - }); - - - //dbg!("diff:", &diff[..3]); - //dbg!(&id_out); - dbg!(&dio); - - //* - - ////println!("[2]raw_pt:{:?}", &raw_pt); - //let left: Vec = raw_pt[dio[0].1..=dio[0].2].into(); - //let mut right = vec![]; - //for i in (dio[1].1..=dio[1].2).rev() { - ////for i in (id_out[1]..=id_out[2]).rev() { - // right.push(raw_pt[i]); - //} - //println!("[2]raw_pt:{:?}", &raw_pt); - let left: Vec = l_tmp[dio[0].1..=dio[0].2].into(); - let mut right = vec![]; - for i in (dio[1].1..=dio[1].2).rev() { - //for i in (id_out[1]..=id_out[2]).rev() { - right.push(l_tmp[i]); - } - - let mut couple = vec!(); - let nb_jump = 10; - let mut id_last = 0; - let range_id = 20; - for i in 0..left.len() { - //if i % nb_jump == 0 { - let mut dist = vec![]; - let from = (id_last as i32 - range_id as i32).max(0) as usize; - let to = (id_last + range_id).min(right.len()-1); - for id in from..=to { - let df = right[id] - left[i]; - let dst = (df.cross(&df)).sqrt(); - dist.push((id, dst)); - } - dist.sort_by(|a, b| { - if a.1 > b.1 { - Ordering::Greater - } else if a.1 == b.1 { - Ordering::Equal - } else { - Ordering::Less - } - }); - //println!("closest: {:?}", &dist[0]); - id_last = dist[0].0; //dbg!(dist); - couple.push((left[i], right[id_last])); - //} - } - - let l3: Vec = couple.iter().map(|(l, r)| (*l+*r)/2.).collect(); - //*/ - - // - - //let space = 100; - //let dst = 30; - //for i in 0..l_tmp.len() { - // if i % space == 0 { - // // - // } - //} - - self.line = l3; - println!("rest:{}\t", ll.len()); - } - - /// the function also set: self.v_lst - fn populate_hlst(&mut self, pt_all: &mut HashSet<(i32, i32)>) { - let first = pt_all.iter().next().unwrap(); - let mut added = HashSet::from([(first.0, first.1)]); - let to_look = [ - (-1, 0), - (0, -1), - (1, 0), - (0, 1), - (-1, -1), - (-1, 1), - (1, 1), - (1, -1), - ]; - self.h_lst.extend(&added); - while added.len() > 0 { - let mut tmp = HashSet::new(); - for (x, y) in added { - for (i, j) in to_look { - if let Some(pt_new) = pt_all.get(&(x + i, y + j)) { - tmp.insert(*pt_new); - } - } - } - - self.h_lst.extend(tmp.clone()); - tmp.iter().for_each(|pt| { - pt_all.remove(pt); - }); - added = tmp; - } - - let mut tmp = HashSet::new(); - self.h_lst.iter().for_each(|(x, y)| { - for (i, j) in to_look[..4].iter() { - if self.h_lst.get(&(x + i, y + j)).is_none() { - tmp.insert((*x, *y)); - } - } - }); - self.h_lst = tmp; - - println!("\t\t\t\tfinal selecteted:{}", self.h_lst.len()); - - //dbg!(a); - //println!(I); - } -} - -pub fn get_lines( - m: &Mat, - y_ordering: bool, - beg_lowest: bool, - nb_liss: i32, -) -> Result>> { - // donc on va refaire un algo de detection de segement - // * on va chercher des illot: - // * chaque illo on lui definie des limit (min, max) sur x et y - // * on calcule le centre - let mut pt_inside = HashSet::new(); - let (cols, rows) = (m.cols(), m.rows()); - for j in 0..rows { - for i in 0..cols { - let v: &Point3_ = m.at_2d(j, i)?; - if v.x != 0 && v.y != 0 && v.z != 0 { - pt_inside.insert((i, j)); - } - } - } - - println!("\tFlifou: {}\t\tpt_inserted:{}", line!(), pt_inside.len()); - - let mut lines = vec![]; - while pt_inside.len() > 0 { - lines.push(Line::new(&mut pt_inside, y_ordering, beg_lowest, nb_liss)); - } - - println!("\tFlifou: {}\t\tnb_line:{}", line!(), lines.len()); - - // pour chaque ligne - Ok(lines.iter().map(|line| line.line.clone()).collect()) -} - -#[derive(Debug)] -struct Seg { - h_lst: HashSet<(i32, i32)>, - v_lst: Vec, - min: Pt, - max: Pt, - center: Pt, - beg: Pt, - end: Pt, -} - -impl Seg { - pub fn new(pt_all: &mut HashSet<(i32, i32)>, y_ordering: bool, beg_lowest: bool) -> Self { - let mut illand = Seg { - min: Pt::from((f64::MAX, f64::MAX)), - max: Pt::from((f64::MIN, f64::MIN)), - center: Pt::from((0., 0.)), - beg: Pt::from((0., 0.)), - end: Pt::from((0., 0.)), - h_lst: HashSet::new(), - v_lst: vec![], - }; - if pt_all.len() <= 0 { - return illand; - } - //dbg!(&pt_all); - illand.populate_hlst(pt_all); - //println!(""); - illand.define_beg_end(false, beg_lowest); - //dbg!(&illand); - illand - } - - //fn define_beg_end(&mut self, y_ordering: bool, beg_lowest: bool) { - // // on a tout les point ordonner - // // on peut les re-ordonner selon un axes interne - //} - - /// the function also set: self.v_lst - fn populate_hlst(&mut self, pt_all: &mut HashSet<(i32, i32)>) { - let first = pt_all.iter().next().unwrap(); - let mut added = HashSet::from([(first.0, first.1)]); - let to_look = [ - (-1, 0), - (0, -1), - (1, 0), - (0, 1), - (-1, -1), - (-1, 1), - (1, 1), - (1, -1), - ]; - self.h_lst.extend(&added); - while added.len() > 0 { - let mut tmp = HashSet::new(); - for (x, y) in added { - for (i, j) in to_look { - if let Some(pt_new) = pt_all.get(&(x + i, y + j)) { - tmp.insert(*pt_new); - } - } - } - - self.h_lst.extend(tmp.clone()); - tmp.iter().for_each(|pt| { - pt_all.remove(pt); - }); - added = tmp; - } - - // calcule min, max, center - self.h_lst.iter().for_each(|(x, y)| { - self.min.x = (*x as f64).min(self.min.x); - self.max.x = (*x as f64).max(self.max.x); - self.min.y = (*y as f64).min(self.min.y); - self.max.y = (*y as f64).max(self.max.y); - - self.center.x += *x as f64; - self.center.y += *y as f64; - }); - - self.center /= self.h_lst.len() as f64; - - self.v_lst = self - .h_lst - .iter() - .map(|(x, y)| Pt { - x: (*x as f64), - y: (*y as f64), - }) - .collect(); - } - - /// y_ordering: means we ordering vertically. Else we ordering horizontay - /// beg_lowest: means first value are the lowset. Else first value are the biggest - fn define_beg_end(&mut self, y_ordering: bool, beg_lowest: bool) { - let pts: Vec = self - .h_lst - .iter() - .map(|(x, y)| { - Pt { - x: (*x as f64), - y: (*y as f64), - } - self.center - }) - .collect(); - - let y_cmp = |pt_a: &Pt, pt_b: &Pt| { - if (pt_a.y > pt_b.y) == beg_lowest { - Ordering::Greater - } else if pt_a.y == pt_b.y { - if pt_a.x.abs() > pt_b.x.abs() { - Ordering::Greater - } else if pt_a.x.abs() == pt_b.x.abs() { - Ordering::Equal - } else { - Ordering::Less - } - } else { - Ordering::Less - } - }; - let x_cmp = |pt_a: &Pt, pt_b: &Pt| { - if (pt_a.x > pt_b.x) == beg_lowest { - Ordering::Greater - } else if pt_a.x == pt_b.x { - if pt_a.y.abs() > pt_b.y.abs() { - Ordering::Greater - } else if pt_a.y.abs() == pt_b.y.abs() { - Ordering::Equal - } else { - Ordering::Less - } - } else { - Ordering::Less - } - }; - - //println!("\n\nserching axes:"); - // finding by dichotomie - // finding best central axes. - let mut begin = 0.; - let mut len = 8.; - let nb_deg = 8; - let nb_iter = 20; - let mut id_min = 0; - let mut v_max_x = vec![]; - for _iter in 0..nb_iter { - //println!("iter:{_iter}"); - v_max_x = vec![]; - for i in 0..(nb_deg + 2) { - let rad = (i as f64 - 1.) / len * PI + begin; - let axes_x = Pt::from((rad.cos(), rad.sin())); - let axes_y = Pt::from((-rad.sin(), rad.cos())); - let new_base: Vec = pts - .iter() - .map(|pt| Pt::from((pt.cross(&axes_x), pt.cross(&axes_y)))) - .collect(); - - let mut max_x = 0.; - new_base.iter().for_each(|pt| { - if pt.x.abs() > max_x { - max_x = pt.x.abs(); - } - }); - //println!("\t[i:{i}]rad:{rad:32.26}\tval: {max_x}"); - v_max_x.push((rad, max_x)); - } - - id_min = 0; - for i in 1..=nb_deg { - let (p, n, a) = (v_max_x[i - 1].1, v_max_x[i].1, v_max_x[i + 1].1); - let cnd = (y_ordering && n <= p && n <= a) || (!y_ordering && n >= p && n >= a); - id_min = if cnd { i - 1 } else { id_min }; - } - - begin = v_max_x[id_min].0; - len *= 4.; - } - - let rad = v_max_x[id_min + 1].0; - let axes_x = Pt::from((rad.cos(), rad.sin())); - let axes_y = Pt::from((-rad.sin(), rad.cos())); - let mut npts: Vec = pts - .iter() - .map(|pt| Pt::from((pt.cross(&axes_x), pt.cross(&axes_y)))) - .collect(); - - if y_ordering { - npts.sort_by(y_cmp); - } else { - npts.sort_by(x_cmp); - } - - let mut beg = Pt::from((0., 0.)); - for pt in npts[..(npts.len() / 2)].iter() { - beg += *pt; - } - beg /= (npts.len() / 2) as f64; - - let mut end = Pt::from((0., 0.)); - for pt in npts[(npts.len() / 2)..].iter() { - end += *pt; - } - end /= (npts.len() - (npts.len() / 2)) as f64; - - let beg_tmp = axes_x * beg.x + axes_y * beg.y + self.center; - let end_tmp = axes_x * end.x + axes_y * end.y + self.center; - - self.beg = (beg_tmp - end_tmp) * 1.5 + end_tmp; - self.end = (end_tmp - beg_tmp) * 1.5 + beg_tmp; - } -} - -pub fn get_segment( - m: &Mat, - y_ordering: bool, - beg_lowest: bool, -) -> Result> { - // donc on va refaire un algo de detection de segement - // * on va chercher des illot: - // * chaque illo on lui definie des limit (min, max) sur x et y - // * on calcule le centre - let mut pt_inside = HashSet::new(); - let (cols, rows) = (m.cols(), m.rows()); - for j in 0..rows { - for i in 0..cols { - let v: &Point3_ = m.at_2d(j, i)?; - if v.x != 0 && v.y != 0 && v.z != 0 { - pt_inside.insert((i, j)); - } - } - } - - let mut illands = vec![]; - while pt_inside.len() > 0 { - illands.push(Seg::new(&mut pt_inside, y_ordering, beg_lowest)); - } - //todo!(); - if y_ordering { - illands.sort_by(|a, b| { - if beg_lowest && a.center.y > b.center.y || !beg_lowest && a.center.y < b.center.y { - Ordering::Greater - } else if a.center.y == b.center.y { - Ordering::Equal - } else { - Ordering::Less - } - }); - } else { - illands.sort_by(|a, b| { - if beg_lowest && a.center.x > b.center.x || !beg_lowest && a.center.x < b.center.x { - Ordering::Greater - } else if a.center.x == b.center.x { - Ordering::Equal - } else { - Ordering::Less - } - }); - } - let segments = illands - .iter() - .map(|illand| ((illand.beg.x, illand.beg.y), (illand.end.x, illand.end.y))) - .collect(); - Ok(segments) -} // On cherche des segment regourper par ilot de point. chaque illot a une plage de valeur en y qui // lui est propre, aucun autre ilot aura des point dans une plage de valeurs d'un autre illot. pub fn get_vertical_segment(m: &Mat) -> Result> { @@ -1115,7 +463,7 @@ pub fn get_vertical_segment(m: &Mat) -> Result Result Result Result Result<()> { create_trackbar("nb_all", winname, Some(&mut mem.nb_all), 400, None)?; create_trackbar("nb_visible", winname, Some(&mut mem.nb_visible), 400, None)?; - create_trackbar("nb_wait", winname, Some(&mut mem.nb_wait), 40, None)?; create_trackbar("r", winname, Some(&mut mem.r), MAX_TRACKBAR, None)?; create_trackbar("g", winname, Some(&mut mem.g), MAX_TRACKBAR, None)?; create_trackbar("b", winname, Some(&mut mem.b), MAX_TRACKBAR, None)?; @@ -1560,7 +914,7 @@ pub fn line_pos(mem: &mut Param, winname: &str) -> Result<()> { pub fn adding_trackbar(mem: &mut Param, _winname: &str) -> Result<()> { //println!("winname: {winname}"); //line_pos(&mut mem, "Play Line")?; - trackbar_init_param(mem, "init_param")?; + //trackbar_init_param(mem, "init_param")?; named_window("histo bgr", WINDOW_AUTOSIZE)?; associate_trackbar("histo bgr", &mut mem.tresh)?; diff --git a/src/qualibration/param.rs b/src/qualibration/param.rs index 10d4b01..52f4487 100644 --- a/src/qualibration/param.rs +++ b/src/qualibration/param.rs @@ -10,7 +10,6 @@ use std::time::Instant; #[derive(Clone, Debug)] pub struct Param { pub seq_id: usize, - pub seq_names: Vec, pub imgs: Vec>, pub dst_size: i32, pub r: i32, @@ -36,7 +35,7 @@ pub struct Param { } impl Param { - pub fn new(dir_name: String, seq_names: Vec) -> Result { + pub fn new(dir_name: String) -> Result { Ok(Self { begin: std::time::Instant::now(), capture_mode: dir_name.len() == 0, @@ -44,16 +43,15 @@ impl Param { key: -1, imgs: vec![vec![]], seq_id: 0, - seq_names, dst_size: 900, r: 150, g: 0, b: 0, nb_all: 120, nb_visible: 40, - nb_liss: 100, - nb_wait: 3, - tresh: Treshold::new("histogram", 170, 255)?, + nb_liss: 10, + nb_wait: 30, + tresh: Treshold::new("histogram", 160, 255)?, canny_v1: 170, canny_v2: 255, hough_param: HoughLine { @@ -82,11 +80,11 @@ impl Param { ); create_dir(&new_dir).unwrap_or(()); for (i, img_seq) in self.imgs.iter().enumerate() { - let seq_dir_name = format!("{new_dir}/seq_{i}_{}", self.seq_names[i]); + let seq_dir_name = format!("{new_dir}/{i}"); create_dir(&seq_dir_name).unwrap_or(()); - for (id, img) in img_seq.iter().enumerate() { + for img in img_seq { let mut name_img = format!("{seq_dir_name}/"); - name_img.push_str(&format!("img_{id}.png")); + name_img.push_str(&format!("img_{i}.png")); imwrite(&name_img, img, &Vector::from_slice(&[6, 6, 6, 0]))?; } } @@ -102,16 +100,11 @@ impl Param { let dir = entry?; let path = dir.path(); // sequence directory let names: Vec<&str> = path.to_str().unwrap().split("/").collect(); - let parts: Vec<&str> = names[names.len() - 1].split("_").collect(); - let nbr = parts[1]; - //println!("\t\t=> '{}'", names[names.len() - 1]); - let seq_id: usize = parts[1].parse()?; + let seq_id: usize = names[names.len() - 1].parse()?; for entry in read_dir(&path)? { let sub_path = entry?.path(); - let names: Vec<&str> = sub_path.to_str().unwrap().split("/").collect(); + let names: Vec<&str> = path.to_str().unwrap().split("/").collect(); let img_name = names[names.len() - 1]; - //println!("all_names: {:?}", &names); - //println!("img_name: {}", img_name); 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)?, diff --git a/src/qualibration/sequence.rs b/src/qualibration/sequence.rs index 75c6dec..4d543be 100644 --- a/src/qualibration/sequence.rs +++ b/src/qualibration/sequence.rs @@ -18,8 +18,6 @@ pub trait Sequence { fn draw(&self, mem: &Param) -> Option>; fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box>; fn is_capture(&self) -> bool; - fn sequence_name(&self) -> String; - fn wait_milis(&self) -> u64; } impl std::fmt::Debug for dyn Sequence { diff --git a/src/qualibration/sequence/init_border.rs b/src/qualibration/sequence/init_border.rs index 23348be..bcdd4e6 100644 --- a/src/qualibration/sequence/init_border.rs +++ b/src/qualibration/sequence/init_border.rs @@ -7,14 +7,13 @@ use crate::qualibration::{ use crate::qualibration::annalyse::image_diff; use crate::qualibration::borders::{ - bord_mult, get_extermities, get_intersection, mix_borders, probabilistic_hough, + bord_mult, get_extermities, get_intersection, probabilistic_hough, }; use opencv::{ calib3d, - core::{Mat, Point as OcvPoint, Scalar, Size, VecN, Vector, BORDER_CONSTANT}, - highgui, - imgproc::{self, canny, cvt_color, line, COLOR_BGR2GRAY}, + core::{Mat, Point as OcvPoint, Size, VecN, Vector}, + imgproc::{canny, cvt_color, COLOR_BGR2GRAY}, Result, }; @@ -31,11 +30,10 @@ pub struct InitBorder { finished: bool, cnt: usize, borders: [Point; 4], - nb_millis: u64, } impl InitBorder { - pub fn new(beg: Point, end: Point, nb_millis: u64) -> Self { + pub fn new(beg: Point, end: Point) -> Self { InitBorder { borders: [ Point { @@ -59,7 +57,6 @@ impl InitBorder { color: end.color, }, ], - nb_millis, cnt: 0, finished: false, } @@ -70,7 +67,7 @@ impl Sequence for InitBorder { //type Obj = Self; fn draw(&self, mem: &Param) -> Option> { - if self.cnt > self.borders.len() || self.finished { + if self.cnt > self.borders.len() { return None; } if self.cnt == self.borders.len() { @@ -129,19 +126,19 @@ impl Sequence for InitBorder { let border_pt = get_intersection(&bords_pts); mem.border_pt = bord_mult(border_pt, 1.1); - // on dessine le cadre - let color: VecN = VecN::new(255., 128., 0., 255.); - let mut mixed = mix_borders(&background, borders)?; - let b = &mem.border_pt; - for i in 0..b.len() { - let j = (i + 1) % mem.border_pt.len(); - let pa = VecN::from_array([b[i].0 as i32, b[i].1 as i32]); - let pb = VecN::from_array([b[j].0 as i32, b[j].1 as i32]); - let a = OcvPoint::from_vec2(pa); - let b = OcvPoint::from_vec2(pb); - line(&mut mixed, a, b, color, 1, LINE_AA, 0)?; - } - highgui::imshow("mixed bored", &mixed)?; + //// on dessine le cadre + //let color: VecN = VecN::new(255., 128., 0., 255.); + //let mut mixed = mix_borders(&background, borders)?; + //let b = &mem.border_pt; + //for i in 0..b.len() { + // let j = (i + 1) % mem.border_pt.len(); + // let pa = VecN::from_array([b[i].0 as i32, b[i].1 as i32]); + // let pb = VecN::from_array([b[j].0 as i32, b[j].1 as i32]); + // let a = OcvPoint::from_vec2(pa); + // let b = OcvPoint::from_vec2(pb); + // line(&mut mixed, a, b, color, 1, LINE_AA, 0)?; + //} + //highgui::imshow("mixed bored", &mixed)?; // on calcule l'homography let size = mem.dst_size; @@ -153,7 +150,7 @@ impl Sequence for InitBorder { .map(|(x, y)| OcvPoint::new(*x as i32, *y as i32)) .collect(); //let dst = [(0, 0), (0, size), (size, size), (size, 0)]; // in: laser repere - let dst = [(size, size), (size, 0), (0, 0), (0, size)]; + let dst = [(0, size), (0, 0), (size, 0), (size, size)]; let dst_corners: Vec = dst.iter().map(|(x, y)| OcvPoint::new(*x, *y)).collect(); let roi_corners_mat = Mat::from_slice(&roi_corners[..])?; let dst_corners_mat = Mat::from_slice(&dst_corners)?; @@ -166,17 +163,17 @@ impl Sequence for InitBorder { )?; //get homography mem.homography = h.clone(); mem.h_size = warped_image_size.clone(); - let mut warped_image = Mat::default(); - imgproc::warp_perspective( - &mixed, - &mut warped_image, - &h, - warped_image_size, - imgproc::INTER_CUBIC, // I dont see difference with INTER_CUBIC - BORDER_CONSTANT, - Scalar::default(), - )?; // do perspective transformation - highgui::imshow("Warped Image", &warped_image)?; + //let mut warped_image = Mat::default(); + //imgproc::warp_perspective( + // &mixed, + // &mut warped_image, + // &h, + // warped_image_size, + // imgproc::INTER_CUBIC, // I dont see difference with INTER_CUBIC + // core::BORDER_CONSTANT, + // Scalar::default(), + //)?; // do perspective transformation + //highgui::imshow("Warped Image", &warped_image)?; self.finished = true; Ok(()) } @@ -184,14 +181,6 @@ impl Sequence for InitBorder { fn is_capture(&self) -> bool { true } - - fn sequence_name(&self) -> String { - "Init_Border".to_owned() - } - - fn wait_milis(&self) -> u64 { - self.nb_millis - } } pub fn get_lines( diff --git a/src/qualibration/sequence/init_idcode.rs b/src/qualibration/sequence/init_idcode.rs index fd2ab97..1fbd900 100644 --- a/src/qualibration/sequence/init_idcode.rs +++ b/src/qualibration/sequence/init_idcode.rs @@ -2,7 +2,7 @@ use crate::{ draw::draw_line_dotted, point::Point, qualibration::{ - annalyse::{get_horizontal_segment, get_vertical_segment, image_diff}, + annalyse::{get_horizontal_segment, image_diff}, compute_image::{image_treshold, image_warp}, param::Param, Sequence, @@ -29,17 +29,15 @@ pub struct InitIdcode { cnt: usize, beg: Point, end: Point, - nb_millis: u64, } impl InitIdcode { - pub fn new(beg: Point, end: Point, nb_millis: u64) -> InitIdcode { + pub fn new(beg: Point, end: Point) -> InitIdcode { InitIdcode { finished: false, cnt: 0, beg, end, - nb_millis, } } } @@ -101,16 +99,7 @@ impl Sequence for InitIdcode { self.finished = true; Ok(()) } - fn is_capture(&self) -> bool { true } - - fn sequence_name(&self) -> String { - "init_Id-Code".to_owned() - } - - fn wait_milis(&self) -> u64 { - self.nb_millis - } } diff --git a/src/qualibration/sequence/line_dotted.rs b/src/qualibration/sequence/line_dotted.rs index d14608d..b35a403 100644 --- a/src/qualibration/sequence/line_dotted.rs +++ b/src/qualibration/sequence/line_dotted.rs @@ -1,20 +1,17 @@ -use crate::{ - point::{Color, Point}, - qualibration::{ - annalyse::{ - draw_histograme_bgr_tresh, get_horizontal_segment, get_lines, get_segment, - get_vertical_segment, histogram_3d, image_diff, - }, - compute_image::{image_treshold, image_warp}, - param::Param, - Sequence, +use crate::point::{Color, Point}; +use crate::qualibration::{ + annalyse::{ + draw_histograme_bgr_tresh, get_horizontal_segment, get_vertical_segment, histogram_3d, + image_diff, }, + param::Param, + Sequence, }; + use opencv::{ core::{bitwise_and, in_range, Mat, Point as OcvPoint, Scalar, VecN, BORDER_CONSTANT}, highgui, imgproc::{self, line}, - prelude::*, Result, }; @@ -23,7 +20,6 @@ opencv::opencv_branch_4! { } opencv::not_opencv_branch_4! { use opencv::core::LINE_AA; - use opencv::imgproc::LINE_8; } #[derive(Debug, Clone)] @@ -34,19 +30,10 @@ pub struct LineDotted { end: Point, continuous_y: bool, continuous_x: bool, - nb_millis: u64, - factor: usize, } impl LineDotted { - pub fn new( - beg: Point, - end: Point, - factor: usize, - continuous_y: bool, - continuous_x: bool, - nb_millis: u64, - ) -> Self { + pub fn new(beg: Point, end: Point, continuous_y: bool, continuous_x: bool) -> Self { Self { finished: false, cnt: 0, @@ -54,8 +41,6 @@ impl LineDotted { end, continuous_x, continuous_y, - factor, - nb_millis, } } } @@ -70,47 +55,36 @@ impl Sequence for LineDotted { } let nb_all = mem.nb_all; let nb_wait = mem.nb_wait as usize; - //let nb_visible = mem.nb_visible as usize; - let len = (self.factor * mem.line_pos.len() + nb_wait) as f32; + let nb_visible = mem.nb_visible as usize; let mut pl = vec![]; - let black = Color { r: 0, g: 0, b: 0 }; let color = Color { r: mem.r as u8, g: mem.g as u8, b: mem.b as u8, }; - - // go to firsst point + let black = Color { r: 0, g: 0, b: 0 }; for _ in 0..nb_all { pl.push(Point { color: black, ..self.beg }); } - - // go on the continus_axes in black to gain speed + let len = (2 * mem.line_pos.len() + nb_wait) as f32; for i in 0..nb_wait { - let val_x = self.end.x; //i as f32 / len * (self.end.x - self.beg.x) + self.beg.x; - let val_y = self.end.y; //i as f32 / len * (self.end.y - self.beg.y) + self.beg.y; + let val_x = i as f32 / len * (self.end.x - self.beg.x) + self.beg.x; + let val_y = i as f32 / len * (self.end.y - self.beg.y) + self.beg.y; pl.push(Point { x: if self.continuous_x { val_x } else { self.beg.x }, y: if self.continuous_y { val_y } else { self.beg.y }, color: black, }); } - - // donne each pose lavue acording to the slide bar value and the continus axes - for i in 0..(mem.line_pos.len() * self.factor) { + for i in 0..(mem.line_pos.len() * 2) { let val_cont_x = (i + nb_wait) as f32 / len * (self.end.x - self.beg.x) + self.beg.x; let val_cont_y = (i + nb_wait) as f32 / len * (self.end.y - self.beg.y) + self.beg.y; - let val_x = mem.line_pos[i / self.factor] as f32 + self.beg.x; - let val_y = mem.line_pos[i / self.factor] as f32 + self.beg.y; - //let is_visible = (i + nb_wait) % 2 == 0;// && i < nb_visible; - let is_visible = match (self.cnt, i) { - (1, _) => true, - (2, i) => i & 1 == 0, - (cnt, i) => i & (1 << (cnt - 3)) != 0, - }; + let val_x = mem.line_pos[i / 2] as f32 + self.beg.x; + let val_y = mem.line_pos[i / 2] as f32 + self.beg.y; + let is_visible = (i + nb_wait) % 2 == 0 && i < nb_visible; let c = if is_visible { color } else { black }; pl.push(Point { x: if self.continuous_x { val_cont_x } else { val_x }, @@ -118,74 +92,76 @@ impl Sequence for LineDotted { color: c, }); } - + Some(pl) } fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box> { - if self.cnt <= ((self.factor * mem.line_pos.len()) as f64).log2() as usize + 2 { - println!("cnt: {}", self.cnt); + if self.cnt < 1 { self.cnt += 1; - return Ok(()); } - println!("Falgadouf :{} cnt:{}", line!(), self.cnt); - //let len = ((self.factor * mem.line_pos.len()) as f64).log2() as usize + 1; - - //if self.cnt > ((self.factor * mem.line_pos.len()) as f64).log2() as usize + 1 { - // if mem.capture_mode { - // self.finished = true; - // } else { - // self.cnt = 0; - // } - // return Ok(()) - //} - //println!("Groboulli: {}", line!()); let ids = mem.seq_id; - let img_len = mem.imgs[ids].len(); - let img_id = 2; //(img_len-1).min(self.cnt); - let background = mem.imgs[ids][0].to_owned(); - let line_dot = mem.imgs[ids][img_id].to_owned(); - let diff = image_diff(&line_dot, &background)?; - //highgui::imshow("lone dotted", &diff)?; + let line_dot = mem.imgs[ids][1].to_owned(); + let diff = image_diff(&background, &line_dot)?; - let warped_image = image_warp(&diff, &mem.homography, mem.h_size)?; - let mut seg_treshed = image_treshold(&warped_image, &mem.tresh)?; + let mut warped_image = Mat::default(); + imgproc::warp_perspective( + &diff, + &mut warped_image, + &mem.homography, + mem.h_size, + imgproc::INTER_CUBIC, // I dont see difference with INTER_CUBIC + BORDER_CONSTANT, + Scalar::default(), + )?; + //highgui::imshow("Warped Image", &warped_image)?; - let histo = histogram_3d(&diff, mem.nb_liss)?; + let histo = histogram_3d(&warped_image, mem.nb_liss)?; draw_histograme_bgr_tresh("histo bgr", &histo, &mem.tresh)?; - //let segs = get_segment(&seg_treshed, true, true)?; - //println!("Falgadouf: {} BEFORE", line!()); - let segs = get_lines(&seg_treshed, true, true, mem.nb_liss)?; - ////println!("Falgadouf: {} nb_seg:{}", line!(), segs.len()); - for seg in segs { - //println!("Falgadouf: {}", line!()); - for i in 0..(seg.len() - 1) { - //println!("Falgadouf: {}", line!()); - let ((x0, y0), (x1, y1)) = ((seg[i].x, seg[i].y), (seg[i + 1].x, seg[i + 1].y)); - let blue = (i as f64 / seg.len() as f64) * 255.; - let color: VecN = VecN::new(blue, 128., 0., 255.); - let pa = VecN::from_array([x0 as i32, y0 as i32]); - let pb = VecN::from_array([x1 as i32, y1 as i32]); - let a = OcvPoint::from_vec2(pa); - let b = OcvPoint::from_vec2(pb); - line(&mut seg_treshed, a, b, color, 1, LINE_8, 0)?; - } + let (t1, s1, l1) = ( + mem.tresh.min_0 as f64, + mem.tresh.min_1 as f64, + mem.tresh.min_2 as f64, + ); + let (t2, s2, l2) = ( + mem.tresh.max_0 as f64, + mem.tresh.max_1 as f64, + mem.tresh.max_2 as f64, + ); + let min = Mat::from_slice(&[t1, s1, l1])?; + let max = Mat::from_slice(&[t2, s2, l2])?; + let mut color_selected = Mat::default(); + let _ = in_range(&warped_image, &min, &max, &mut color_selected); + let mut bord_treshed = Mat::default(); + bitwise_and( + &warped_image, + &warped_image, + &mut bord_treshed, + &color_selected, + )?; + //highgui::imshow(format!("warped_image & mask").as_str(), &bord_treshed)?; + + let segments = if self.continuous_y { + get_vertical_segment(&bord_treshed)? + } else { + get_horizontal_segment(&bord_treshed)? + }; + for (i, (((x0, y0), (x1, y1)), _size)) in segments.iter().enumerate() { + let blue = (i as f64 / segments.len() as f64) * 255.; + let color: VecN = VecN::new(blue, 128., 0., 255.); + let pa = VecN::from_array([*x0 as i32, *y0 as i32]); + let pb = VecN::from_array([*x1 as i32, *y1 as i32]); + let a = OcvPoint::from_vec2(pa); + let b = OcvPoint::from_vec2(pb); + line(&mut bord_treshed, a, b, color, 1, LINE_8, 0)?; } - //println!("Falgadouf: {}", line!()); - highgui::imshow("Warped and treshed Image + segment", &seg_treshed)?; - //self.finished = true; + highgui::imshow("segemnt detector", &bord_treshed)?; + self.finished = true; Ok(()) } fn is_capture(&self) -> bool { true } - fn sequence_name(&self) -> String { - "line_Dotted".to_owned() - } - - fn wait_milis(&self) -> u64 { - self.nb_millis - } } diff --git a/src/qualibration/sequence/load_image.rs b/src/qualibration/sequence/load_image.rs index d2bacfd..c723241 100644 --- a/src/qualibration/sequence/load_image.rs +++ b/src/qualibration/sequence/load_image.rs @@ -5,15 +5,11 @@ use opencv::Result; #[derive(Debug, Clone, Copy)] pub struct LoadImage { finished: bool, - nb_millis: u64, } impl LoadImage { pub fn new() -> LoadImage { - LoadImage { - finished: false, - nb_millis: 0, - } + LoadImage { finished: false } } } @@ -24,7 +20,6 @@ impl Sequence for LoadImage { } Some(vec![]) } - fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box> { if !mem.capture_mode { mem.load_image()?; @@ -32,16 +27,7 @@ impl Sequence for LoadImage { self.finished = true; Ok(()) } - fn is_capture(&self) -> bool { false } - - fn sequence_name(&self) -> String { - "Load_Image".to_owned() - } - - fn wait_milis(&self) -> u64 { - self.nb_millis - } } diff --git a/src/qualibration/sequence/save_image.rs b/src/qualibration/sequence/save_image.rs index 322795c..1ddfec3 100644 --- a/src/qualibration/sequence/save_image.rs +++ b/src/qualibration/sequence/save_image.rs @@ -5,15 +5,11 @@ use opencv::Result; #[derive(Debug, Clone, Copy)] pub struct SaveImage { finished: bool, - nb_millis: u64, } impl SaveImage { pub fn new() -> SaveImage { - SaveImage { - finished: false, - nb_millis: 0, - } + SaveImage { finished: false } } } @@ -24,22 +20,12 @@ impl Sequence for SaveImage { } Some(vec![]) } - fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box> { mem.save_image()?; self.finished = true; Ok(()) } - fn is_capture(&self) -> bool { false } - - fn sequence_name(&self) -> String { - "Save_Image".to_owned() - } - - fn wait_milis(&self) -> u64 { - self.nb_millis - } } diff --git a/src/qualibration/sequence/wait_space.rs b/src/qualibration/sequence/wait_space.rs index c1d84e4..db26bcf 100644 --- a/src/qualibration/sequence/wait_space.rs +++ b/src/qualibration/sequence/wait_space.rs @@ -9,13 +9,16 @@ use opencv::Result; #[derive(Debug, Clone, Copy)] pub struct WaitSpace { borders: [Point; 4], - mid: [Point; 2], - nb_millis: u64, + red: [Point; 2], + green: [Point; 2], + blue: [Point; 2], } impl WaitSpace { - pub fn new(beg: Point, end: Point, nb_millis: u64) -> Self { - let mid = (end.y - beg.y) * 0.5 + beg.y; + pub fn new(beg: Point, end: Point) -> Self { + let red_y = (end.y - beg.y) * 1./5. + beg.y; + let green_y = (end.y - beg.y) * 2./5. + beg.y; + let blue_y = (end.y - beg.y) * 3./5. + beg.y; Self { borders: [ Point { @@ -39,19 +42,42 @@ impl WaitSpace { color: end.color, }, ], - mid: [ + red: [ Point { x: beg.x, - y: mid, + y: red_y, color: end.color, }, Point { x: end.x, - y: mid, + y: red_y, + color: end.color, + }, + ], + blue: [ + Point { + x: beg.x, + y: blue_y, + color: end.color, + }, + Point { + x: end.x, + y: blue_y, + color: end.color, + }, + ], + green: [ + Point { + x: beg.x, + y: green_y, + color: end.color, + }, + Point { + x: end.x, + y: green_y, color: end.color, }, ], - nb_millis, } } } @@ -68,6 +94,21 @@ impl Sequence for WaitSpace { g: mem.g as u8, b: mem.b as u8, }; + let red = Color { + r: mem.r as u8, + g: 0, + b: 0, + }; + let green = Color { + r: 0, + g: mem.g as u8, + b: 0, + }; + let blue = Color { + r: 0, + g: 0, + b: mem.b as u8, + }; for i in 0..self.borders.len() { let id1 = (i + 1) % self.borders.len(); let p0 = Point { @@ -85,18 +126,44 @@ impl Sequence for WaitSpace { mem.nb_visible as usize, )); pl.extend(draw_line_dotted( - &Point { - color, - ..self.mid[0] + &Point{ + color: blue, + ..self.blue[0] }, - &Point { - color, - ..self.mid[1] + &Point{ + color: blue, + ..self.blue[1] }, mem.nb_all as usize, mem.nb_visible as usize, true, - )); + )); + pl.extend(draw_line_dotted( + &Point{ + color: green, + ..self.green[0] + }, + &Point{ + color: green, + ..self.green[1] + }, + mem.nb_all as usize, + mem.nb_visible as usize, + true, + )); + pl.extend(draw_line_dotted( + &Point{ + color: red, + ..self.red[0] + }, + &Point{ + color: red, + ..self.red[1] + }, + mem.nb_all as usize, + mem.nb_visible as usize, + true, + )); } Some(pl) } @@ -106,12 +173,4 @@ impl Sequence for WaitSpace { fn is_capture(&self) -> bool { false } - - fn sequence_name(&self) -> String { - "Wait_Space".to_owned() - } - - fn wait_milis(&self) -> u64 { - self.nb_millis - } } diff --git a/src/utils.rs b/src/utils.rs index dc0b5bc..1223c49 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -87,12 +87,6 @@ impl From<(f64, f64)> for Pt { } } -//impl From for (f64, f64) { -// fn from(pt: Pt) -> Self { -// (pt.x, pt.y) -// } -//} - impl From<&(f64, f64)> for Pt { fn from((x, y): &(f64, f64)) -> Self { Pt { x: *x, y: *y }