Compare commits
2 Commits
sequence_t
...
master
Author | SHA1 | Date | |
---|---|---|---|
7d5285748e | |||
fef7e1387b |
54
src/main.rs
54
src/main.rs
@ -87,24 +87,30 @@ fn run_all() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
while running.load(Ordering::SeqCst) {
|
while running.load(Ordering::SeqCst) {
|
||||||
//let _t = _framerate_handler.handle_time()?;
|
let key = highgui::wait_key(20)?;
|
||||||
/////////////////
|
let v = qualibration.draw_sequence();
|
||||||
let key = highgui::wait_key(1)?;
|
|
||||||
|
if key != -1 {
|
||||||
|
println!("key: {key}");
|
||||||
|
// 81 <- -> 83
|
||||||
|
}
|
||||||
qualibration.param.key = key;
|
qualibration.param.key = key;
|
||||||
if key == 27 {
|
if key == 27 {
|
||||||
|
if qualibration.param.capture_mode {
|
||||||
|
qualibration.param.save_image()?;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
} else if v.is_none() {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let v = qualibration.draw_sequence();
|
|
||||||
if v.is_some() {
|
|
||||||
if qualibration.param.capture_mode {
|
if qualibration.param.capture_mode {
|
||||||
let pl: Vec<(f32, f32, u32)> = v
|
let pl: Vec<(f32, f32, u32)> = v
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|pt| (pt.x, pt.y, u32::from(pt.color)))
|
.map(|pt| (pt.x, pt.y, u32::from(pt.color)))
|
||||||
.collect();
|
.collect();
|
||||||
|
con.set(
|
||||||
let _ = con.set(
|
|
||||||
format!("/pl/{}/{}", config.client_id, config.laser_id),
|
format!("/pl/{}/{}", config.client_id, config.laser_id),
|
||||||
format!("{:?}", pl),
|
format!("{:?}", pl),
|
||||||
)?;
|
)?;
|
||||||
@ -112,22 +118,6 @@ fn run_all() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
qualibration.run_step()?;
|
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(
|
let _ = con.set(
|
||||||
format!("/pl/{}/{}", config.client_id, config.laser_id),
|
format!("/pl/{}/{}", config.client_id, config.laser_id),
|
||||||
@ -135,3 +125,21 @@ fn run_all() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
)?;
|
)?;
|
||||||
Ok(())
|
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 {
|
impl Qualibration {
|
||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
|
||||||
//let v: Vec<Box<dyn Sequence>> = vec![];
|
//let v: Vec<Box<dyn Sequence>> = vec![];
|
||||||
|
|
||||||
let mut dir_name = "".to_string(); //"building.jpg".to_string(); // by default
|
let mut dir_name = "".to_string(); //"building.jpg".to_string(); // by default
|
||||||
@ -54,24 +54,22 @@ impl Qualibration {
|
|||||||
let mut frame = Mat::default();
|
let mut frame = Mat::default();
|
||||||
cam.read(&mut frame)?;
|
cam.read(&mut frame)?;
|
||||||
|
|
||||||
// 38400 -> r:150, v:0, b:0
|
// 9830400 -> r:150, v:0, b:0
|
||||||
let beg = Point::from((0., 0., 38400));
|
let beg = Point::from((0., 0., 9830400));
|
||||||
let beg2 = Point::from((4095., 0., 38400));
|
let beg2 = Point::from((0., 4095., 9830400));
|
||||||
let end = Point::from((4095., 4095., 38400));
|
let end = Point::from((4095., 4095., 9830400));
|
||||||
let seq: Vec<Box<dyn Sequence>> = vec![
|
let seq: Vec<Box<dyn Sequence>> = vec![
|
||||||
Box::new(LoadImage::new()),
|
Box::new(WaitSpace::new(beg, end, 400)),
|
||||||
Box::new(WaitSpace::new(beg, end)),
|
Box::new(InitBorder::new(beg, end, 400)),
|
||||||
Box::new(InitBorder::new(beg, end)),
|
Box::new(LineDotted::new(beg, end, 2, true, false, 400)),
|
||||||
Box::new(LineDotted::new(beg, end, true, false)),
|
//Box::new(InitIdcode::new(beg2, end, 400)),
|
||||||
Box::new(InitIdcode::new(beg2, end)),
|
|
||||||
Box::new(SaveImage::new()),
|
|
||||||
];
|
];
|
||||||
//let now = std::time::Instant::now();
|
let seq_names = get_sequence_name(&seq);
|
||||||
Ok(Qualibration {
|
let mut param = Param::new(dir_name.to_owned(), seq_names)?;
|
||||||
seq,
|
if !param.capture_mode {
|
||||||
cam,
|
param.load_image()?;
|
||||||
param: Param::new(dir_name.to_owned())?,
|
}
|
||||||
})
|
Ok(Qualibration { seq, cam, param })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_sequence(&mut self) -> Option<Vec<Point>> {
|
pub fn draw_sequence(&mut self) -> Option<Vec<Point>> {
|
||||||
@ -92,7 +90,23 @@ impl Qualibration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_step(self: &mut Self) -> Result<(), Box<dyn std::error::Error>> {
|
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();
|
let mut frame = Mat::default();
|
||||||
|
//println!("sequence: {}:{:?}", self.param.seq_id, &self.seq[self.param.seq_id]);
|
||||||
if self.param.capture_mode {
|
if self.param.capture_mode {
|
||||||
self.cam.read(&mut frame)?;
|
self.cam.read(&mut frame)?;
|
||||||
highgui::imshow("camera", &frame)?;
|
highgui::imshow("camera", &frame)?;
|
||||||
@ -109,3 +123,13 @@ impl Qualibration {
|
|||||||
Ok(())
|
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,3 +1,4 @@
|
|||||||
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
|
|
||||||
@ -67,6 +68,45 @@ pub fn draw_histograme_dbg(
|
|||||||
Ok(())
|
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)]
|
#[allow(dead_code)]
|
||||||
pub fn draw_histograme(window_name: &str, histo: &Vec<f64>) -> Result<()> {
|
pub fn draw_histograme(window_name: &str, histo: &Vec<f64>) -> Result<()> {
|
||||||
let v: VecN<f64, 4> = VecN::new(0., 0., 0., 255.);
|
let v: VecN<f64, 4> = VecN::new(0., 0., 0., 255.);
|
||||||
@ -379,6 +419,618 @@ pub fn get_horizontal_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)),
|
|||||||
Ok(segments)
|
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
|
// 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.
|
// 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)>> {
|
pub fn get_vertical_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)), f32)>> {
|
||||||
@ -463,7 +1115,7 @@ pub fn get_vertical_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)), f3
|
|||||||
}
|
}
|
||||||
center /= iland.len() as f64;
|
center /= iland.len() as f64;
|
||||||
|
|
||||||
let max_deg = 360;
|
let max_deg = 8;
|
||||||
let (mut _err_min, mut rad_min, mut x_min) = (f64::MAX, 0., f64::MAX);
|
let (mut _err_min, mut rad_min, mut x_min) = (f64::MAX, 0., f64::MAX);
|
||||||
let mut iland_min = vec![];
|
let mut iland_min = vec![];
|
||||||
for deg in 0..max_deg {
|
for deg in 0..max_deg {
|
||||||
@ -476,7 +1128,6 @@ pub fn get_vertical_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)), f3
|
|||||||
x: -y_axis.y,
|
x: -y_axis.y,
|
||||||
y: y_axis.x,
|
y: y_axis.x,
|
||||||
};
|
};
|
||||||
let mut _err = 0.;
|
|
||||||
let mut tmp_iland = vec![];
|
let mut tmp_iland = vec![];
|
||||||
let mut x_abs_max = f64::MIN;
|
let mut x_abs_max = f64::MIN;
|
||||||
for pt in iland {
|
for pt in iland {
|
||||||
@ -485,7 +1136,6 @@ pub fn get_vertical_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)), f3
|
|||||||
x: p.cross(&x_axis),
|
x: p.cross(&x_axis),
|
||||||
y: p.cross(&y_axis),
|
y: p.cross(&y_axis),
|
||||||
};
|
};
|
||||||
_err += p.x * p.x;
|
|
||||||
tmp_iland.push(p);
|
tmp_iland.push(p);
|
||||||
if x_abs_max < p.x.abs() {
|
if x_abs_max < p.x.abs() {
|
||||||
x_abs_max = p.x.abs();
|
x_abs_max = p.x.abs();
|
||||||
@ -496,11 +1146,6 @@ pub fn get_vertical_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)), f3
|
|||||||
rad_min = rad;
|
rad_min = rad;
|
||||||
iland_min = tmp_iland;
|
iland_min = tmp_iland;
|
||||||
}
|
}
|
||||||
//if _err < _err_min {
|
|
||||||
// err_min = _err;
|
|
||||||
// rad_min = rad;
|
|
||||||
// iland_min = tmp_iland;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
iland_min.sort_by(|pta, ptb| {
|
iland_min.sort_by(|pta, ptb| {
|
||||||
if pta.y < ptb.y {
|
if pta.y < ptb.y {
|
||||||
@ -819,6 +1464,7 @@ 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_all", winname, Some(&mut mem.nb_all), 400, None)?;
|
||||||
create_trackbar("nb_visible", winname, Some(&mut mem.nb_visible), 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("r", winname, Some(&mut mem.r), MAX_TRACKBAR, None)?;
|
||||||
create_trackbar("g", winname, Some(&mut mem.g), 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)?;
|
create_trackbar("b", winname, Some(&mut mem.b), MAX_TRACKBAR, None)?;
|
||||||
@ -914,7 +1560,7 @@ pub fn line_pos(mem: &mut Param, winname: &str) -> Result<()> {
|
|||||||
pub fn adding_trackbar(mem: &mut Param, _winname: &str) -> Result<()> {
|
pub fn adding_trackbar(mem: &mut Param, _winname: &str) -> Result<()> {
|
||||||
//println!("winname: {winname}");
|
//println!("winname: {winname}");
|
||||||
//line_pos(&mut mem, "Play Line")?;
|
//line_pos(&mut mem, "Play Line")?;
|
||||||
//trackbar_init_param(mem, "init_param")?;
|
trackbar_init_param(mem, "init_param")?;
|
||||||
|
|
||||||
named_window("histo bgr", WINDOW_AUTOSIZE)?;
|
named_window("histo bgr", WINDOW_AUTOSIZE)?;
|
||||||
associate_trackbar("histo bgr", &mut mem.tresh)?;
|
associate_trackbar("histo bgr", &mut mem.tresh)?;
|
||||||
|
@ -10,6 +10,7 @@ use std::time::Instant;
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Param {
|
pub struct Param {
|
||||||
pub seq_id: usize,
|
pub seq_id: usize,
|
||||||
|
pub seq_names: Vec<String>,
|
||||||
pub imgs: Vec<Vec<Mat>>,
|
pub imgs: Vec<Vec<Mat>>,
|
||||||
pub dst_size: i32,
|
pub dst_size: i32,
|
||||||
pub r: i32,
|
pub r: i32,
|
||||||
@ -35,7 +36,7 @@ pub struct Param {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Param {
|
impl Param {
|
||||||
pub fn new(dir_name: String) -> Result<Self> {
|
pub fn new(dir_name: String, seq_names: Vec<String>) -> Result<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
begin: std::time::Instant::now(),
|
begin: std::time::Instant::now(),
|
||||||
capture_mode: dir_name.len() == 0,
|
capture_mode: dir_name.len() == 0,
|
||||||
@ -43,15 +44,16 @@ impl Param {
|
|||||||
key: -1,
|
key: -1,
|
||||||
imgs: vec![vec![]],
|
imgs: vec![vec![]],
|
||||||
seq_id: 0,
|
seq_id: 0,
|
||||||
|
seq_names,
|
||||||
dst_size: 900,
|
dst_size: 900,
|
||||||
r: 150,
|
r: 150,
|
||||||
g: 0,
|
g: 0,
|
||||||
b: 0,
|
b: 0,
|
||||||
nb_all: 120,
|
nb_all: 120,
|
||||||
nb_visible: 40,
|
nb_visible: 40,
|
||||||
nb_liss: 10,
|
nb_liss: 100,
|
||||||
nb_wait: 30,
|
nb_wait: 3,
|
||||||
tresh: Treshold::new("histogram", 160, 255)?,
|
tresh: Treshold::new("histogram", 170, 255)?,
|
||||||
canny_v1: 170,
|
canny_v1: 170,
|
||||||
canny_v2: 255,
|
canny_v2: 255,
|
||||||
hough_param: HoughLine {
|
hough_param: HoughLine {
|
||||||
@ -80,11 +82,11 @@ impl Param {
|
|||||||
);
|
);
|
||||||
create_dir(&new_dir).unwrap_or(());
|
create_dir(&new_dir).unwrap_or(());
|
||||||
for (i, img_seq) in self.imgs.iter().enumerate() {
|
for (i, img_seq) in self.imgs.iter().enumerate() {
|
||||||
let seq_dir_name = format!("{new_dir}/{i}");
|
let seq_dir_name = format!("{new_dir}/seq_{i}_{}", self.seq_names[i]);
|
||||||
create_dir(&seq_dir_name).unwrap_or(());
|
create_dir(&seq_dir_name).unwrap_or(());
|
||||||
for img in img_seq {
|
for (id, img) in img_seq.iter().enumerate() {
|
||||||
let mut name_img = format!("{seq_dir_name}/");
|
let mut name_img = format!("{seq_dir_name}/");
|
||||||
name_img.push_str(&format!("img_{i}.png"));
|
name_img.push_str(&format!("img_{id}.png"));
|
||||||
imwrite(&name_img, img, &Vector::from_slice(&[6, 6, 6, 0]))?;
|
imwrite(&name_img, img, &Vector::from_slice(&[6, 6, 6, 0]))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,11 +102,16 @@ impl Param {
|
|||||||
let dir = entry?;
|
let dir = entry?;
|
||||||
let path = dir.path(); // sequence directory
|
let path = dir.path(); // sequence directory
|
||||||
let names: Vec<&str> = path.to_str().unwrap().split("/").collect();
|
let names: Vec<&str> = path.to_str().unwrap().split("/").collect();
|
||||||
let seq_id: usize = names[names.len() - 1].parse()?;
|
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()?;
|
||||||
for entry in read_dir(&path)? {
|
for entry in read_dir(&path)? {
|
||||||
let sub_path = entry?.path();
|
let sub_path = entry?.path();
|
||||||
let names: Vec<&str> = path.to_str().unwrap().split("/").collect();
|
let names: Vec<&str> = sub_path.to_str().unwrap().split("/").collect();
|
||||||
let img_name = names[names.len() - 1];
|
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_id: usize = img_name[4..img_name.len() - 4].parse()?;
|
||||||
let img: Mat = imread(
|
let img: Mat = imread(
|
||||||
&find_file(&sub_path.to_str().unwrap(), false, false)?,
|
&find_file(&sub_path.to_str().unwrap(), false, false)?,
|
||||||
|
@ -18,6 +18,8 @@ pub trait Sequence {
|
|||||||
fn draw(&self, mem: &Param) -> Option<Vec<Point>>;
|
fn draw(&self, mem: &Param) -> Option<Vec<Point>>;
|
||||||
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>>;
|
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>>;
|
||||||
fn is_capture(&self) -> bool;
|
fn is_capture(&self) -> bool;
|
||||||
|
fn sequence_name(&self) -> String;
|
||||||
|
fn wait_milis(&self) -> u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for dyn Sequence {
|
impl std::fmt::Debug for dyn Sequence {
|
||||||
|
@ -7,13 +7,14 @@ use crate::qualibration::{
|
|||||||
|
|
||||||
use crate::qualibration::annalyse::image_diff;
|
use crate::qualibration::annalyse::image_diff;
|
||||||
use crate::qualibration::borders::{
|
use crate::qualibration::borders::{
|
||||||
bord_mult, get_extermities, get_intersection, probabilistic_hough,
|
bord_mult, get_extermities, get_intersection, mix_borders, probabilistic_hough,
|
||||||
};
|
};
|
||||||
|
|
||||||
use opencv::{
|
use opencv::{
|
||||||
calib3d,
|
calib3d,
|
||||||
core::{Mat, Point as OcvPoint, Size, VecN, Vector},
|
core::{Mat, Point as OcvPoint, Scalar, Size, VecN, Vector, BORDER_CONSTANT},
|
||||||
imgproc::{canny, cvt_color, COLOR_BGR2GRAY},
|
highgui,
|
||||||
|
imgproc::{self, canny, cvt_color, line, COLOR_BGR2GRAY},
|
||||||
Result,
|
Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,10 +31,11 @@ pub struct InitBorder {
|
|||||||
finished: bool,
|
finished: bool,
|
||||||
cnt: usize,
|
cnt: usize,
|
||||||
borders: [Point; 4],
|
borders: [Point; 4],
|
||||||
|
nb_millis: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InitBorder {
|
impl InitBorder {
|
||||||
pub fn new(beg: Point, end: Point) -> Self {
|
pub fn new(beg: Point, end: Point, nb_millis: u64) -> Self {
|
||||||
InitBorder {
|
InitBorder {
|
||||||
borders: [
|
borders: [
|
||||||
Point {
|
Point {
|
||||||
@ -57,6 +59,7 @@ impl InitBorder {
|
|||||||
color: end.color,
|
color: end.color,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
nb_millis,
|
||||||
cnt: 0,
|
cnt: 0,
|
||||||
finished: false,
|
finished: false,
|
||||||
}
|
}
|
||||||
@ -67,7 +70,7 @@ impl Sequence for InitBorder {
|
|||||||
//type Obj = Self;
|
//type Obj = Self;
|
||||||
|
|
||||||
fn draw(&self, mem: &Param) -> Option<Vec<Point>> {
|
fn draw(&self, mem: &Param) -> Option<Vec<Point>> {
|
||||||
if self.cnt > self.borders.len() {
|
if self.cnt > self.borders.len() || self.finished {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if self.cnt == self.borders.len() {
|
if self.cnt == self.borders.len() {
|
||||||
@ -126,19 +129,19 @@ impl Sequence for InitBorder {
|
|||||||
let border_pt = get_intersection(&bords_pts);
|
let border_pt = get_intersection(&bords_pts);
|
||||||
mem.border_pt = bord_mult(border_pt, 1.1);
|
mem.border_pt = bord_mult(border_pt, 1.1);
|
||||||
|
|
||||||
//// on dessine le cadre
|
// on dessine le cadre
|
||||||
//let color: VecN<f64, 4> = VecN::new(255., 128., 0., 255.);
|
let color: VecN<f64, 4> = VecN::new(255., 128., 0., 255.);
|
||||||
//let mut mixed = mix_borders(&background, borders)?;
|
let mut mixed = mix_borders(&background, borders)?;
|
||||||
//let b = &mem.border_pt;
|
let b = &mem.border_pt;
|
||||||
//for i in 0..b.len() {
|
for i in 0..b.len() {
|
||||||
// let j = (i + 1) % mem.border_pt.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 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 pb = VecN::from_array([b[j].0 as i32, b[j].1 as i32]);
|
||||||
// let a = OcvPoint::from_vec2(pa);
|
let a = OcvPoint::from_vec2(pa);
|
||||||
// let b = OcvPoint::from_vec2(pb);
|
let b = OcvPoint::from_vec2(pb);
|
||||||
// line(&mut mixed, a, b, color, 1, LINE_AA, 0)?;
|
line(&mut mixed, a, b, color, 1, LINE_AA, 0)?;
|
||||||
//}
|
}
|
||||||
//highgui::imshow("mixed bored", &mixed)?;
|
highgui::imshow("mixed bored", &mixed)?;
|
||||||
|
|
||||||
// on calcule l'homography
|
// on calcule l'homography
|
||||||
let size = mem.dst_size;
|
let size = mem.dst_size;
|
||||||
@ -150,7 +153,7 @@ impl Sequence for InitBorder {
|
|||||||
.map(|(x, y)| OcvPoint::new(*x as i32, *y as i32))
|
.map(|(x, y)| OcvPoint::new(*x as i32, *y as i32))
|
||||||
.collect();
|
.collect();
|
||||||
//let dst = [(0, 0), (0, size), (size, size), (size, 0)]; // in: laser repere
|
//let dst = [(0, 0), (0, size), (size, size), (size, 0)]; // in: laser repere
|
||||||
let dst = [(0, size), (0, 0), (size, 0), (size, size)];
|
let dst = [(size, size), (size, 0), (0, 0), (0, size)];
|
||||||
let dst_corners: Vec<OcvPoint> = dst.iter().map(|(x, y)| OcvPoint::new(*x, *y)).collect();
|
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 roi_corners_mat = Mat::from_slice(&roi_corners[..])?;
|
||||||
let dst_corners_mat = Mat::from_slice(&dst_corners)?;
|
let dst_corners_mat = Mat::from_slice(&dst_corners)?;
|
||||||
@ -163,17 +166,17 @@ impl Sequence for InitBorder {
|
|||||||
)?; //get homography
|
)?; //get homography
|
||||||
mem.homography = h.clone();
|
mem.homography = h.clone();
|
||||||
mem.h_size = warped_image_size.clone();
|
mem.h_size = warped_image_size.clone();
|
||||||
//let mut warped_image = Mat::default();
|
let mut warped_image = Mat::default();
|
||||||
//imgproc::warp_perspective(
|
imgproc::warp_perspective(
|
||||||
// &mixed,
|
&mixed,
|
||||||
// &mut warped_image,
|
&mut warped_image,
|
||||||
// &h,
|
&h,
|
||||||
// warped_image_size,
|
warped_image_size,
|
||||||
// imgproc::INTER_CUBIC, // I dont see difference with INTER_CUBIC
|
imgproc::INTER_CUBIC, // I dont see difference with INTER_CUBIC
|
||||||
// core::BORDER_CONSTANT,
|
BORDER_CONSTANT,
|
||||||
// Scalar::default(),
|
Scalar::default(),
|
||||||
//)?; // do perspective transformation
|
)?; // do perspective transformation
|
||||||
//highgui::imshow("Warped Image", &warped_image)?;
|
highgui::imshow("Warped Image", &warped_image)?;
|
||||||
self.finished = true;
|
self.finished = true;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -181,6 +184,14 @@ impl Sequence for InitBorder {
|
|||||||
fn is_capture(&self) -> bool {
|
fn is_capture(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sequence_name(&self) -> String {
|
||||||
|
"Init_Border".to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wait_milis(&self) -> u64 {
|
||||||
|
self.nb_millis
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_lines(
|
pub fn get_lines(
|
||||||
|
@ -2,7 +2,7 @@ use crate::{
|
|||||||
draw::draw_line_dotted,
|
draw::draw_line_dotted,
|
||||||
point::Point,
|
point::Point,
|
||||||
qualibration::{
|
qualibration::{
|
||||||
annalyse::{get_horizontal_segment, image_diff},
|
annalyse::{get_horizontal_segment, get_vertical_segment, image_diff},
|
||||||
compute_image::{image_treshold, image_warp},
|
compute_image::{image_treshold, image_warp},
|
||||||
param::Param,
|
param::Param,
|
||||||
Sequence,
|
Sequence,
|
||||||
@ -29,15 +29,17 @@ pub struct InitIdcode {
|
|||||||
cnt: usize,
|
cnt: usize,
|
||||||
beg: Point,
|
beg: Point,
|
||||||
end: Point,
|
end: Point,
|
||||||
|
nb_millis: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InitIdcode {
|
impl InitIdcode {
|
||||||
pub fn new(beg: Point, end: Point) -> InitIdcode {
|
pub fn new(beg: Point, end: Point, nb_millis: u64) -> InitIdcode {
|
||||||
InitIdcode {
|
InitIdcode {
|
||||||
finished: false,
|
finished: false,
|
||||||
cnt: 0,
|
cnt: 0,
|
||||||
beg,
|
beg,
|
||||||
end,
|
end,
|
||||||
|
nb_millis,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,7 +101,16 @@ impl Sequence for InitIdcode {
|
|||||||
self.finished = true;
|
self.finished = true;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_capture(&self) -> bool {
|
fn is_capture(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sequence_name(&self) -> String {
|
||||||
|
"init_Id-Code".to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wait_milis(&self) -> u64 {
|
||||||
|
self.nb_millis
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
use crate::point::{Color, Point};
|
use crate::{
|
||||||
use crate::qualibration::{
|
point::{Color, Point},
|
||||||
|
qualibration::{
|
||||||
annalyse::{
|
annalyse::{
|
||||||
draw_histograme_bgr_tresh, get_horizontal_segment, get_vertical_segment, histogram_3d,
|
draw_histograme_bgr_tresh, get_horizontal_segment, get_lines, get_segment,
|
||||||
image_diff,
|
get_vertical_segment, histogram_3d, image_diff,
|
||||||
},
|
},
|
||||||
|
compute_image::{image_treshold, image_warp},
|
||||||
param::Param,
|
param::Param,
|
||||||
Sequence,
|
Sequence,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use opencv::{
|
use opencv::{
|
||||||
core::{bitwise_and, in_range, Mat, Point as OcvPoint, Scalar, VecN, BORDER_CONSTANT},
|
core::{bitwise_and, in_range, Mat, Point as OcvPoint, Scalar, VecN, BORDER_CONSTANT},
|
||||||
highgui,
|
highgui,
|
||||||
imgproc::{self, line},
|
imgproc::{self, line},
|
||||||
|
prelude::*,
|
||||||
Result,
|
Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -20,6 +23,7 @@ opencv::opencv_branch_4! {
|
|||||||
}
|
}
|
||||||
opencv::not_opencv_branch_4! {
|
opencv::not_opencv_branch_4! {
|
||||||
use opencv::core::LINE_AA;
|
use opencv::core::LINE_AA;
|
||||||
|
use opencv::imgproc::LINE_8;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -30,10 +34,19 @@ pub struct LineDotted {
|
|||||||
end: Point,
|
end: Point,
|
||||||
continuous_y: bool,
|
continuous_y: bool,
|
||||||
continuous_x: bool,
|
continuous_x: bool,
|
||||||
|
nb_millis: u64,
|
||||||
|
factor: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LineDotted {
|
impl LineDotted {
|
||||||
pub fn new(beg: Point, end: Point, continuous_y: bool, continuous_x: bool) -> Self {
|
pub fn new(
|
||||||
|
beg: Point,
|
||||||
|
end: Point,
|
||||||
|
factor: usize,
|
||||||
|
continuous_y: bool,
|
||||||
|
continuous_x: bool,
|
||||||
|
nb_millis: u64,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
finished: false,
|
finished: false,
|
||||||
cnt: 0,
|
cnt: 0,
|
||||||
@ -41,6 +54,8 @@ impl LineDotted {
|
|||||||
end,
|
end,
|
||||||
continuous_x,
|
continuous_x,
|
||||||
continuous_y,
|
continuous_y,
|
||||||
|
factor,
|
||||||
|
nb_millis,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,36 +70,47 @@ impl Sequence for LineDotted {
|
|||||||
}
|
}
|
||||||
let nb_all = mem.nb_all;
|
let nb_all = mem.nb_all;
|
||||||
let nb_wait = mem.nb_wait as usize;
|
let nb_wait = mem.nb_wait as usize;
|
||||||
let nb_visible = mem.nb_visible as usize;
|
//let nb_visible = mem.nb_visible as usize;
|
||||||
|
let len = (self.factor * mem.line_pos.len() + nb_wait) as f32;
|
||||||
let mut pl = vec![];
|
let mut pl = vec![];
|
||||||
|
let black = Color { r: 0, g: 0, b: 0 };
|
||||||
let color = Color {
|
let color = Color {
|
||||||
r: mem.r as u8,
|
r: mem.r as u8,
|
||||||
g: mem.g as u8,
|
g: mem.g as u8,
|
||||||
b: mem.b as u8,
|
b: mem.b as u8,
|
||||||
};
|
};
|
||||||
let black = Color { r: 0, g: 0, b: 0 };
|
|
||||||
|
// go to firsst point
|
||||||
for _ in 0..nb_all {
|
for _ in 0..nb_all {
|
||||||
pl.push(Point {
|
pl.push(Point {
|
||||||
color: black,
|
color: black,
|
||||||
..self.beg
|
..self.beg
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let len = (2 * mem.line_pos.len() + nb_wait) as f32;
|
|
||||||
|
// go on the continus_axes in black to gain speed
|
||||||
for i in 0..nb_wait {
|
for i in 0..nb_wait {
|
||||||
let val_x = i as f32 / len * (self.end.x - self.beg.x) + self.beg.x;
|
let val_x = self.end.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;
|
let val_y = self.end.y; //i as f32 / len * (self.end.y - self.beg.y) + self.beg.y;
|
||||||
pl.push(Point {
|
pl.push(Point {
|
||||||
x: if self.continuous_x { val_x } else { self.beg.x },
|
x: if self.continuous_x { val_x } else { self.beg.x },
|
||||||
y: if self.continuous_y { val_y } else { self.beg.y },
|
y: if self.continuous_y { val_y } else { self.beg.y },
|
||||||
color: black,
|
color: black,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for i in 0..(mem.line_pos.len() * 2) {
|
|
||||||
|
// donne each pose lavue acording to the slide bar value and the continus axes
|
||||||
|
for i in 0..(mem.line_pos.len() * self.factor) {
|
||||||
let val_cont_x = (i + nb_wait) as f32 / len * (self.end.x - self.beg.x) + self.beg.x;
|
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_cont_y = (i + nb_wait) as f32 / len * (self.end.y - self.beg.y) + self.beg.y;
|
||||||
let val_x = mem.line_pos[i / 2] as f32 + self.beg.x;
|
let val_x = mem.line_pos[i / self.factor] as f32 + self.beg.x;
|
||||||
let val_y = mem.line_pos[i / 2] as f32 + self.beg.y;
|
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 = (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 c = if is_visible { color } else { black };
|
let c = if is_visible { color } else { black };
|
||||||
pl.push(Point {
|
pl.push(Point {
|
||||||
x: if self.continuous_x { val_cont_x } else { val_x },
|
x: if self.continuous_x { val_cont_x } else { val_x },
|
||||||
@ -97,71 +123,69 @@ impl Sequence for LineDotted {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>> {
|
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if self.cnt < 1 {
|
if self.cnt <= ((self.factor * mem.line_pos.len()) as f64).log2() as usize + 2 {
|
||||||
|
println!("cnt: {}", self.cnt);
|
||||||
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 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 background = mem.imgs[ids][0].to_owned();
|
||||||
let line_dot = mem.imgs[ids][1].to_owned();
|
let line_dot = mem.imgs[ids][img_id].to_owned();
|
||||||
let diff = image_diff(&background, &line_dot)?;
|
let diff = image_diff(&line_dot, &background)?;
|
||||||
|
//highgui::imshow("lone dotted", &diff)?;
|
||||||
|
|
||||||
let mut warped_image = Mat::default();
|
let warped_image = image_warp(&diff, &mem.homography, mem.h_size)?;
|
||||||
imgproc::warp_perspective(
|
let mut seg_treshed = image_treshold(&warped_image, &mem.tresh)?;
|
||||||
&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(&warped_image, mem.nb_liss)?;
|
let histo = histogram_3d(&diff, mem.nb_liss)?;
|
||||||
draw_histograme_bgr_tresh("histo bgr", &histo, &mem.tresh)?;
|
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());
|
||||||
|
|
||||||
let (t1, s1, l1) = (
|
for seg in segs {
|
||||||
mem.tresh.min_0 as f64,
|
//println!("Falgadouf: {}", line!());
|
||||||
mem.tresh.min_1 as f64,
|
for i in 0..(seg.len() - 1) {
|
||||||
mem.tresh.min_2 as f64,
|
//println!("Falgadouf: {}", line!());
|
||||||
);
|
let ((x0, y0), (x1, y1)) = ((seg[i].x, seg[i].y), (seg[i + 1].x, seg[i + 1].y));
|
||||||
let (t2, s2, l2) = (
|
let blue = (i as f64 / seg.len() as f64) * 255.;
|
||||||
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 color: VecN<f64, 4> = VecN::new(blue, 128., 0., 255.);
|
||||||
let pa = VecN::from_array([*x0 as i32, *y0 as i32]);
|
let pa = VecN::from_array([x0 as i32, y0 as i32]);
|
||||||
let pb = VecN::from_array([*x1 as i32, *y1 as i32]);
|
let pb = VecN::from_array([x1 as i32, y1 as i32]);
|
||||||
let a = OcvPoint::from_vec2(pa);
|
let a = OcvPoint::from_vec2(pa);
|
||||||
let b = OcvPoint::from_vec2(pb);
|
let b = OcvPoint::from_vec2(pb);
|
||||||
line(&mut bord_treshed, a, b, color, 1, LINE_8, 0)?;
|
line(&mut seg_treshed, a, b, color, 1, LINE_8, 0)?;
|
||||||
}
|
}
|
||||||
highgui::imshow("segemnt detector", &bord_treshed)?;
|
}
|
||||||
self.finished = true;
|
//println!("Falgadouf: {}", line!());
|
||||||
|
highgui::imshow("Warped and treshed Image + segment", &seg_treshed)?;
|
||||||
|
//self.finished = true;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn is_capture(&self) -> bool {
|
fn is_capture(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
fn sequence_name(&self) -> String {
|
||||||
|
"line_Dotted".to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wait_milis(&self) -> u64 {
|
||||||
|
self.nb_millis
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,15 @@ use opencv::Result;
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct LoadImage {
|
pub struct LoadImage {
|
||||||
finished: bool,
|
finished: bool,
|
||||||
|
nb_millis: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LoadImage {
|
impl LoadImage {
|
||||||
pub fn new() -> LoadImage {
|
pub fn new() -> LoadImage {
|
||||||
LoadImage { finished: false }
|
LoadImage {
|
||||||
|
finished: false,
|
||||||
|
nb_millis: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,6 +24,7 @@ impl Sequence for LoadImage {
|
|||||||
}
|
}
|
||||||
Some(vec![])
|
Some(vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>> {
|
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if !mem.capture_mode {
|
if !mem.capture_mode {
|
||||||
mem.load_image()?;
|
mem.load_image()?;
|
||||||
@ -27,7 +32,16 @@ impl Sequence for LoadImage {
|
|||||||
self.finished = true;
|
self.finished = true;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_capture(&self) -> bool {
|
fn is_capture(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sequence_name(&self) -> String {
|
||||||
|
"Load_Image".to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wait_milis(&self) -> u64 {
|
||||||
|
self.nb_millis
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,15 @@ use opencv::Result;
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct SaveImage {
|
pub struct SaveImage {
|
||||||
finished: bool,
|
finished: bool,
|
||||||
|
nb_millis: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SaveImage {
|
impl SaveImage {
|
||||||
pub fn new() -> SaveImage {
|
pub fn new() -> SaveImage {
|
||||||
SaveImage { finished: false }
|
SaveImage {
|
||||||
|
finished: false,
|
||||||
|
nb_millis: 0,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,12 +24,22 @@ impl Sequence for SaveImage {
|
|||||||
}
|
}
|
||||||
Some(vec![])
|
Some(vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>> {
|
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
mem.save_image()?;
|
mem.save_image()?;
|
||||||
self.finished = true;
|
self.finished = true;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_capture(&self) -> bool {
|
fn is_capture(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sequence_name(&self) -> String {
|
||||||
|
"Save_Image".to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wait_milis(&self) -> u64 {
|
||||||
|
self.nb_millis
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,16 +9,13 @@ use opencv::Result;
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct WaitSpace {
|
pub struct WaitSpace {
|
||||||
borders: [Point; 4],
|
borders: [Point; 4],
|
||||||
red: [Point; 2],
|
mid: [Point; 2],
|
||||||
green: [Point; 2],
|
nb_millis: u64,
|
||||||
blue: [Point; 2],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WaitSpace {
|
impl WaitSpace {
|
||||||
pub fn new(beg: Point, end: Point) -> Self {
|
pub fn new(beg: Point, end: Point, nb_millis: u64) -> Self {
|
||||||
let red_y = (end.y - beg.y) * 1./5. + beg.y;
|
let mid = (end.y - beg.y) * 0.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 {
|
Self {
|
||||||
borders: [
|
borders: [
|
||||||
Point {
|
Point {
|
||||||
@ -42,42 +39,19 @@ impl WaitSpace {
|
|||||||
color: end.color,
|
color: end.color,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
red: [
|
mid: [
|
||||||
Point {
|
Point {
|
||||||
x: beg.x,
|
x: beg.x,
|
||||||
y: red_y,
|
y: mid,
|
||||||
color: end.color,
|
color: end.color,
|
||||||
},
|
},
|
||||||
Point {
|
Point {
|
||||||
x: end.x,
|
x: end.x,
|
||||||
y: red_y,
|
y: mid,
|
||||||
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,
|
color: end.color,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
nb_millis,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,21 +68,6 @@ impl Sequence for WaitSpace {
|
|||||||
g: mem.g as u8,
|
g: mem.g as u8,
|
||||||
b: mem.b 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() {
|
for i in 0..self.borders.len() {
|
||||||
let id1 = (i + 1) % self.borders.len();
|
let id1 = (i + 1) % self.borders.len();
|
||||||
let p0 = Point {
|
let p0 = Point {
|
||||||
@ -126,39 +85,13 @@ impl Sequence for WaitSpace {
|
|||||||
mem.nb_visible as usize,
|
mem.nb_visible as usize,
|
||||||
));
|
));
|
||||||
pl.extend(draw_line_dotted(
|
pl.extend(draw_line_dotted(
|
||||||
&Point{
|
&Point {
|
||||||
color: blue,
|
color,
|
||||||
..self.blue[0]
|
..self.mid[0]
|
||||||
},
|
},
|
||||||
&Point{
|
&Point {
|
||||||
color: blue,
|
color,
|
||||||
..self.blue[1]
|
..self.mid[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_all as usize,
|
||||||
mem.nb_visible as usize,
|
mem.nb_visible as usize,
|
||||||
@ -173,4 +106,12 @@ impl Sequence for WaitSpace {
|
|||||||
fn is_capture(&self) -> bool {
|
fn is_capture(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sequence_name(&self) -> String {
|
||||||
|
"Wait_Space".to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wait_milis(&self) -> u64 {
|
||||||
|
self.nb_millis
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,12 @@ 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 {
|
impl From<&(f64, f64)> for Pt {
|
||||||
fn from((x, y): &(f64, f64)) -> Self {
|
fn from((x, y): &(f64, f64)) -> Self {
|
||||||
Pt { x: *x, y: *y }
|
Pt { x: *x, y: *y }
|
||||||
|
Loading…
Reference in New Issue
Block a user