lj_qualibration/src/qualibration/sequence/line_dotted.rs

180 lines
5.8 KiB
Rust

use crate::{
point::{Color, Point},
qualibration::{
annalyse::{
draw_histograme_bgr_tresh, get_horizontal_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},
Result,
};
opencv::opencv_branch_4! {
use opencv::imgproc::LINE_8;
}
opencv::not_opencv_branch_4! {
use opencv::core::LINE_AA;
use opencv::imgproc::LINE_8;
}
#[derive(Debug, Clone)]
pub struct LineDotted {
finished: bool,
cnt: usize,
beg: Point,
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 {
Self {
finished: false,
cnt: 0,
beg,
end,
continuous_x,
continuous_y,
factor,
nb_millis,
}
}
}
impl Sequence for LineDotted {
fn draw(&self, mem: &Param) -> Option<Vec<Point>> {
if self.finished {
return None;
}
if self.cnt == 0 {
return Some(vec![]);
}
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 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
for _ in 0..nb_all {
pl.push(Point {
color: black,
..self.beg
});
}
// 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;
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) {
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 c = if is_visible { color } else { black };
pl.push(Point {
x: if self.continuous_x { val_cont_x } else { val_x },
y: if self.continuous_y { val_cont_y } else { val_y },
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 {
self.cnt += 1;
return Ok(())
}
//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 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 histo = histogram_3d(&warped_image, mem.nb_liss)?;
draw_histograme_bgr_tresh("histo bgr", &histo, &mem.tresh)?;
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)?;
}
highgui::imshow("segemnt detector", &bord_treshed)?;
self.cnt += 1;
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
}
}