just saving in middle of nowher`

This commit is contained in:
Lapin Raving 2023-11-14 17:35:09 +01:00
parent fef7e1387b
commit 7d5285748e
9 changed files with 723 additions and 55 deletions

View File

@ -92,7 +92,7 @@ fn run_all() -> Result<(), Box<dyn std::error::Error>> {
if key != -1 {
println!("key: {key}");
// 81 <- -> 83
// 81 <- -> 83
}
qualibration.param.key = key;
if key == 27 {

View File

@ -62,18 +62,14 @@ impl Qualibration {
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(InitIdcode::new(beg2, end, 400)),
];
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,
})
Ok(Qualibration { seq, cam, param })
}
pub fn draw_sequence(&mut self) -> Option<Vec<Point>> {
@ -96,6 +92,11 @@ 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 {
@ -103,7 +104,7 @@ impl Qualibration {
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 {
@ -121,7 +122,6 @@ impl Qualibration {
Ok(())
}
}
pub fn get_sequence_name(seq: &Vec<Box<dyn Sequence>>) -> Vec<String> {
@ -133,4 +133,3 @@ pub fn get_sequence_name(seq: &Vec<Box<dyn Sequence>>) -> Vec<String> {
v
}

View File

@ -1,3 +1,4 @@
use std::cmp::Ordering;
use std::collections::HashSet;
use std::f64::consts::PI;
@ -67,6 +68,45 @@ 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.);
@ -379,6 +419,618 @@ 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)>> {
@ -463,7 +1115,7 @@ pub fn get_vertical_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)), f3
}
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 iland_min = vec![];
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,
y: y_axis.x,
};
let mut _err = 0.;
let mut tmp_iland = vec![];
let mut x_abs_max = f64::MIN;
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),
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();
@ -496,11 +1146,6 @@ 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 {

View File

@ -51,9 +51,9 @@ impl Param {
b: 0,
nb_all: 120,
nb_visible: 40,
nb_liss: 10,
nb_liss: 100,
nb_wait: 3,
tresh: Treshold::new("histogram", 160, 255)?,
tresh: Treshold::new("histogram", 170, 255)?,
canny_v1: 170,
canny_v2: 255,
hough_param: HoughLine {

View File

@ -7,15 +7,15 @@ use crate::qualibration::{
use crate::qualibration::annalyse::image_diff;
use crate::qualibration::borders::{
bord_mult, get_extermities, get_intersection, probabilistic_hough, mix_borders,
bord_mult, get_extermities, get_intersection, mix_borders, probabilistic_hough,
};
use opencv::{
calib3d,
core::{Mat, Point as OcvPoint, Size, VecN, Vector, Scalar, BORDER_CONSTANT},
imgproc::{self, canny, cvt_color, COLOR_BGR2GRAY, line},
Result,
core::{Mat, Point as OcvPoint, Scalar, Size, VecN, Vector, BORDER_CONSTANT},
highgui,
imgproc::{self, canny, cvt_color, line, COLOR_BGR2GRAY},
Result,
};
opencv::opencv_branch_4! {

View File

@ -2,19 +2,19 @@ use crate::{
point::{Color, Point},
qualibration::{
annalyse::{
draw_histograme_bgr_tresh, get_horizontal_segment, get_vertical_segment, histogram_3d,
image_diff,
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 opencv::{
core::{bitwise_and, in_range, Mat, Point as OcvPoint, Scalar, VecN, BORDER_CONSTANT},
highgui,
imgproc::{self, line},
prelude::*,
Result,
};
@ -39,7 +39,14 @@ pub struct LineDotted {
}
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,
factor: usize,
continuous_y: bool,
continuous_x: bool,
nb_millis: u64,
) -> Self {
Self {
finished: false,
cnt: 0,
@ -83,8 +90,8 @@ impl Sequence for LineDotted {
// go on the continus_axes in black to gain speed
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 = 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;
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 },
@ -111,16 +118,18 @@ 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);
self.cnt += 1;
return Ok(())
return Ok(());
}
//let len = ((self.factor * mem.line_pos.len()) as f64).log2() as usize + 1;
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 {
@ -133,7 +142,7 @@ impl Sequence for LineDotted {
//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 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();
@ -141,29 +150,32 @@ impl Sequence for LineDotted {
//highgui::imshow("lone dotted", &diff)?;
let warped_image = image_warp(&diff, &mem.homography, mem.h_size)?;
let mut bord_treshed = image_treshold(&warped_image, &mem.tresh)?;
highgui::imshow("Warped and treshed Image", &bord_treshed)?;
let mut seg_treshed = image_treshold(&warped_image, &mem.tresh)?;
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)?;
//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 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)?;
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)?;
}
}
highgui::imshow("segemnt detector", &bord_treshed)?;
self.cnt += 1;
self.finished = true;
//println!("Falgadouf: {}", line!());
highgui::imshow("Warped and treshed Image + segment", &seg_treshed)?;
//self.finished = true;
Ok(())
}
fn is_capture(&self) -> bool {

View File

@ -10,7 +10,10 @@ pub struct LoadImage {
impl LoadImage {
pub fn new() -> LoadImage {
LoadImage { finished: false, nb_millis: 0 }
LoadImage {
finished: false,
nb_millis: 0,
}
}
}

View File

@ -10,7 +10,10 @@ pub struct SaveImage {
impl SaveImage {
pub fn new() -> SaveImage {
SaveImage { finished: false, nb_millis: 0}
SaveImage {
finished: false,
nb_millis: 0,
}
}
}

View File

@ -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 {
fn from((x, y): &(f64, f64)) -> Self {
Pt { x: *x, y: *y }