168 lines
5.3 KiB
Rust
168 lines
5.3 KiB
Rust
use crate::point::{Color, Point};
|
|
use crate::qualibration::{
|
|
annalyse::{
|
|
draw_histograme_bgr_tresh, get_horizontal_segment, get_vertical_segment, histogram_3d,
|
|
image_diff,
|
|
},
|
|
param::Param,
|
|
Sequence,
|
|
};
|
|
|
|
use opencv::{
|
|
core::{bitwise_and, in_range, Mat, Point as OcvPoint, Scalar, VecN, BORDER_CONSTANT},
|
|
highgui,
|
|
imgproc::{self, line},
|
|
Result,
|
|
};
|
|
|
|
opencv::opencv_branch_4! {
|
|
use opencv::imgproc::LINE_8;
|
|
}
|
|
opencv::not_opencv_branch_4! {
|
|
use opencv::core::LINE_AA;
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct LineDotted {
|
|
finished: bool,
|
|
cnt: usize,
|
|
beg: Point,
|
|
end: Point,
|
|
continuous_y: bool,
|
|
continuous_x: bool,
|
|
}
|
|
|
|
impl LineDotted {
|
|
pub fn new(beg: Point, end: Point, continuous_y: bool, continuous_x: bool) -> Self {
|
|
Self {
|
|
finished: false,
|
|
cnt: 0,
|
|
beg,
|
|
end,
|
|
continuous_x,
|
|
continuous_y,
|
|
}
|
|
}
|
|
}
|
|
|
|
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 mut pl = vec![];
|
|
let color = Color {
|
|
r: mem.r as u8,
|
|
g: mem.g as u8,
|
|
b: mem.b as u8,
|
|
};
|
|
let black = Color { r: 0, g: 0, b: 0 };
|
|
for _ in 0..nb_all {
|
|
pl.push(Point {
|
|
color: black,
|
|
..self.beg
|
|
});
|
|
}
|
|
let len = (2 * mem.line_pos.len() + nb_wait) as f32;
|
|
for i in 0..nb_wait {
|
|
let val_x = i as f32 / len * (self.end.x - self.beg.x) + self.beg.x;
|
|
let val_y = i as f32 / len * (self.end.y - self.beg.y) + self.beg.y;
|
|
pl.push(Point {
|
|
x: if self.continuous_x { val_x } else { self.beg.x },
|
|
y: if self.continuous_y { val_y } else { self.beg.y },
|
|
color: black,
|
|
});
|
|
}
|
|
for i in 0..(mem.line_pos.len() * 2) {
|
|
let val_cont_x = (i + nb_wait) as f32 / len * (self.end.x - self.beg.x) + self.beg.x;
|
|
let val_cont_y = (i + nb_wait) as f32 / len * (self.end.y - self.beg.y) + self.beg.y;
|
|
let val_x = mem.line_pos[i / 2] as f32 + self.beg.x;
|
|
let val_y = mem.line_pos[i / 2] as f32 + self.beg.y;
|
|
let is_visible = (i + nb_wait) % 2 == 0 && i < nb_visible;
|
|
let c = if is_visible { color } else { black };
|
|
pl.push(Point {
|
|
x: if self.continuous_x { val_cont_x } else { val_x },
|
|
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 < 1 {
|
|
self.cnt += 1;
|
|
}
|
|
let ids = mem.seq_id;
|
|
let background = mem.imgs[ids][0].to_owned();
|
|
let line_dot = mem.imgs[ids][1].to_owned();
|
|
let diff = image_diff(&background, &line_dot)?;
|
|
|
|
let mut warped_image = Mat::default();
|
|
imgproc::warp_perspective(
|
|
&diff,
|
|
&mut warped_image,
|
|
&mem.homography,
|
|
mem.h_size,
|
|
imgproc::INTER_CUBIC, // I dont see difference with INTER_CUBIC
|
|
BORDER_CONSTANT,
|
|
Scalar::default(),
|
|
)?;
|
|
//highgui::imshow("Warped Image", &warped_image)?;
|
|
|
|
let histo = histogram_3d(&warped_image, mem.nb_liss)?;
|
|
draw_histograme_bgr_tresh("histo bgr", &histo, &mem.tresh)?;
|
|
|
|
let (t1, s1, l1) = (
|
|
mem.tresh.min_0 as f64,
|
|
mem.tresh.min_1 as f64,
|
|
mem.tresh.min_2 as f64,
|
|
);
|
|
let (t2, s2, l2) = (
|
|
mem.tresh.max_0 as f64,
|
|
mem.tresh.max_1 as f64,
|
|
mem.tresh.max_2 as f64,
|
|
);
|
|
let min = Mat::from_slice(&[t1, s1, l1])?;
|
|
let max = Mat::from_slice(&[t2, s2, l2])?;
|
|
let mut color_selected = Mat::default();
|
|
let _ = in_range(&warped_image, &min, &max, &mut color_selected);
|
|
let mut bord_treshed = Mat::default();
|
|
bitwise_and(
|
|
&warped_image,
|
|
&warped_image,
|
|
&mut bord_treshed,
|
|
&color_selected,
|
|
)?;
|
|
//highgui::imshow(format!("warped_image & mask").as_str(), &bord_treshed)?;
|
|
|
|
let segments = if self.continuous_y {
|
|
get_vertical_segment(&bord_treshed)?
|
|
} else {
|
|
get_horizontal_segment(&bord_treshed)?
|
|
};
|
|
for (i, (((x0, y0), (x1, y1)), _size)) in segments.iter().enumerate() {
|
|
let blue = (i as f64 / segments.len() as f64) * 255.;
|
|
let color: VecN<f64, 4> = VecN::new(blue, 128., 0., 255.);
|
|
let pa = VecN::from_array([*x0 as i32, *y0 as i32]);
|
|
let pb = VecN::from_array([*x1 as i32, *y1 as i32]);
|
|
let a = OcvPoint::from_vec2(pa);
|
|
let b = OcvPoint::from_vec2(pb);
|
|
line(&mut bord_treshed, a, b, color, 1, LINE_8, 0)?;
|
|
}
|
|
highgui::imshow("segemnt detector", &bord_treshed)?;
|
|
self.finished = true;
|
|
Ok(())
|
|
}
|
|
fn is_capture(&self) -> bool {
|
|
true
|
|
}
|
|
}
|