Compare commits
	
		
			No commits in common. "master" and "sequence_trait_refactoring" have entirely different histories.
		
	
	
		
			master
			...
			sequence_t
		
	
		
							
								
								
									
										76
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								src/main.rs
									
									
									
									
									
								
							| @ -87,36 +87,46 @@ fn run_all() -> Result<(), Box<dyn std::error::Error>> { | ||||
|     )?; | ||||
| 
 | ||||
|     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<dyn std::error::Error>> { | ||||
|     )?; | ||||
|     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);
 | ||||
| //}
 | ||||
|  | ||||
| @ -37,7 +37,7 @@ pub struct Qualibration { | ||||
| } | ||||
| 
 | ||||
| impl Qualibration { | ||||
|     pub fn new() -> Result<Self, Box<dyn std::error::Error>> { | ||||
|     pub fn new() -> Result<Self> { | ||||
|         //let v: Vec<Box<dyn Sequence>> = 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<Box<dyn Sequence>> = 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<Vec<Point>> { | ||||
| @ -90,23 +92,7 @@ impl Qualibration { | ||||
|     } | ||||
| 
 | ||||
|     pub fn run_step(self: &mut Self) -> Result<(), Box<dyn std::error::Error>> { | ||||
|         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<Box<dyn Sequence>>) -> Vec<String> { | ||||
|     let mut v = vec![]; | ||||
| 
 | ||||
|     for i in 0..seq.len() { | ||||
|         v.push(seq[i].sequence_name()); | ||||
|     } | ||||
| 
 | ||||
|     v | ||||
| } | ||||
|  | ||||
| @ -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<f64>, is_log: bool) -> Result<()> { | ||||
|     let v: VecN<f64, 4> = VecN::new(0., 0., 0., 255.); | ||||
|     let color: VecN<f64, 4> = 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<f64>) -> Result<()> { | ||||
|     let v: VecN<f64, 4> = VecN::new(0., 0., 0., 255.); | ||||
| @ -419,618 +379,6 @@ pub fn get_horizontal_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)), | ||||
|     Ok(segments) | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
| struct Line { | ||||
|     h_lst: HashSet<(i32, i32)>, | ||||
|     v_lst: Vec<Pt>, | ||||
|     line: Vec<Pt>, | ||||
|     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<Pt> = 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<Pt> = 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<Pt> = 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<Pt> = 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<Vec<Vec<Pt>>> { | ||||
|     // 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_<u8> = 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<Pt>, | ||||
|     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<Pt> = 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<Pt> = 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<Pt> = 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<Vec<((f64, f64), (f64, f64))>> { | ||||
|     // 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_<u8> = 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<Vec<(((f32, f32), (f32, f32)), f32)>> { | ||||
| @ -1115,7 +463,7 @@ pub fn get_vertical_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)), f3 | ||||
|         } | ||||
|         center /= iland.len() as f64; | ||||
| 
 | ||||
|         let max_deg = 8; | ||||
|         let max_deg = 360; | ||||
|         let (mut _err_min, mut rad_min, mut x_min) = (f64::MAX, 0., f64::MAX); | ||||
|         let mut iland_min = vec![]; | ||||
|         for deg in 0..max_deg { | ||||
| @ -1128,6 +476,7 @@ pub fn get_vertical_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)), f3 | ||||
|                 x: -y_axis.y, | ||||
|                 y: y_axis.x, | ||||
|             }; | ||||
|             let mut _err = 0.; | ||||
|             let mut tmp_iland = vec![]; | ||||
|             let mut x_abs_max = f64::MIN; | ||||
|             for pt in iland { | ||||
| @ -1136,6 +485,7 @@ pub fn get_vertical_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)), f3 | ||||
|                     x: p.cross(&x_axis), | ||||
|                     y: p.cross(&y_axis), | ||||
|                 }; | ||||
|                 _err += p.x * p.x; | ||||
|                 tmp_iland.push(p); | ||||
|                 if x_abs_max < p.x.abs() { | ||||
|                     x_abs_max = p.x.abs(); | ||||
| @ -1146,6 +496,11 @@ pub fn get_vertical_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)), f3 | ||||
|                 rad_min = rad; | ||||
|                 iland_min = tmp_iland; | ||||
|             } | ||||
|             //if _err < _err_min {
 | ||||
|             //    err_min = _err;
 | ||||
|             //    rad_min = rad;
 | ||||
|             //    iland_min = tmp_iland;
 | ||||
|             //}
 | ||||
|         } | ||||
|         iland_min.sort_by(|pta, ptb| { | ||||
|             if pta.y < ptb.y { | ||||
| @ -1464,7 +819,6 @@ pub fn trackbar_init_param(mem: &mut Param, winname: &str) -> 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)?; | ||||
|  | ||||
| @ -10,7 +10,6 @@ use std::time::Instant; | ||||
| #[derive(Clone, Debug)] | ||||
| pub struct Param { | ||||
|     pub seq_id: usize, | ||||
|     pub seq_names: Vec<String>, | ||||
|     pub imgs: Vec<Vec<Mat>>, | ||||
|     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<String>) -> Result<Self> { | ||||
|     pub fn new(dir_name: String) -> Result<Self> { | ||||
|         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)?, | ||||
|  | ||||
| @ -18,8 +18,6 @@ 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; | ||||
|     fn sequence_name(&self) -> String; | ||||
|     fn wait_milis(&self) -> u64; | ||||
| } | ||||
| 
 | ||||
| impl std::fmt::Debug for dyn Sequence { | ||||
|  | ||||
| @ -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<Vec<Point>> { | ||||
|         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<f64, 4> = 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<f64, 4> = 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<OcvPoint> = 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( | ||||
|  | ||||
| @ -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 | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -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<dyn std::error::Error>> { | ||||
|         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<f64, 4> = 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<f64, 4> = 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 | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -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<dyn std::error::Error>> { | ||||
|         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 | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -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<dyn std::error::Error>> { | ||||
|         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 | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -87,12 +87,6 @@ impl From<(f64, f64)> for Pt { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| //impl From<Pt> 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 } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user