Compare commits
No commits in common. "7460b74c154ce930b4f41f2273dac0959a98dbf3" and "910e340ec87467dbf1bd6ca742fd77751ed0f46f" have entirely different histories.
7460b74c15
...
910e340ec8
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,3 @@
|
|||||||
*.png
|
*.png
|
||||||
image
|
image
|
||||||
target
|
target
|
||||||
settings.toml
|
|
||||||
|
37
src/draw.rs
37
src/draw.rs
@ -7,12 +7,12 @@ const X_CENTER: f32 = 2047.0;
|
|||||||
const Y_CENTER: f32 = 2047.0;
|
const Y_CENTER: f32 = 2047.0;
|
||||||
|
|
||||||
pub fn draw_line_dotted(
|
pub fn draw_line_dotted(
|
||||||
p0: &Point,
|
|
||||||
p1: &Point,
|
p1: &Point,
|
||||||
|
p2: &Point,
|
||||||
nb_all: usize,
|
nb_all: usize,
|
||||||
nb_visible: usize,
|
nb_visible: usize,
|
||||||
first_on: bool,
|
first_on: bool,
|
||||||
) -> Vec<Point> {
|
) -> Result<Vec<Point>, Box<dyn std::error::Error>> {
|
||||||
let mut pl = vec![];
|
let mut pl = vec![];
|
||||||
let black = Color { r: 0, g: 0, b: 0 };
|
let black = Color { r: 0, g: 0, b: 0 };
|
||||||
|
|
||||||
@ -21,56 +21,61 @@ pub fn draw_line_dotted(
|
|||||||
for _ in 0..nb_all {
|
for _ in 0..nb_all {
|
||||||
pl.push(Point {
|
pl.push(Point {
|
||||||
color: black,
|
color: black,
|
||||||
..*p0
|
..*p1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for i in 0..nb_visible {
|
for i in 0..nb_visible {
|
||||||
pl.push(Point {
|
pl.push(Point {
|
||||||
color: if i % 2 == cmp { p1.color } else { black },
|
color: if i % 2 == cmp { p2.color } else { black },
|
||||||
..*p1
|
..*p2
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if nb_visible > nb_all {
|
if nb_visible > nb_all {
|
||||||
return pl;
|
return Ok(pl);
|
||||||
}
|
}
|
||||||
for _ in 0..(nb_all - nb_visible) {
|
for _ in 0..(nb_all - nb_visible) {
|
||||||
pl.push(Point {
|
pl.push(Point {
|
||||||
color: black,
|
color: black,
|
||||||
..*p1
|
..*p2
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pl
|
Ok(pl)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_line(p0: &Point, p1: &Point, nb_all: usize, nb_visible: usize) -> Vec<Point> {
|
pub fn draw_line(
|
||||||
|
p1: &Point,
|
||||||
|
p2: &Point,
|
||||||
|
nb_all: usize,
|
||||||
|
nb_visible: usize,
|
||||||
|
) -> Result<Vec<Point>, Box<dyn std::error::Error>> {
|
||||||
let mut pl = vec![];
|
let mut pl = vec![];
|
||||||
let black = Color { r: 0, g: 0, b: 0 };
|
let black = Color { r: 0, g: 0, b: 0 };
|
||||||
|
|
||||||
for _ in 0..nb_all {
|
for _ in 0..nb_all {
|
||||||
pl.push(Point {
|
pl.push(Point {
|
||||||
color: black,
|
color: black,
|
||||||
..*p0
|
..*p1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for _ in 0..nb_visible {
|
for _ in 0..nb_visible {
|
||||||
pl.push(*p1);
|
pl.push(*p2);
|
||||||
}
|
}
|
||||||
if nb_visible > nb_all {
|
if nb_visible > nb_all {
|
||||||
return pl;
|
return Ok(pl);
|
||||||
}
|
}
|
||||||
for _ in 0..(nb_all - nb_visible) {
|
for _ in 0..(nb_all - nb_visible) {
|
||||||
pl.push(Point {
|
pl.push(Point {
|
||||||
color: black,
|
color: black,
|
||||||
..*p1
|
..*p2
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pl
|
Ok(pl)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn draw(_time: f64) -> Vec<Point> {
|
pub fn draw(_time: f64) -> Result<Vec<Point>, Box<dyn std::error::Error>> {
|
||||||
let mut v: Vec<Point> = vec![];
|
let mut v: Vec<Point> = vec![];
|
||||||
for i in 0..128 {
|
for i in 0..128 {
|
||||||
let a = i as f32 / 128.0 * std::f32::consts::PI * 2.0;
|
let a = i as f32 / 128.0 * std::f32::consts::PI * 2.0;
|
||||||
@ -84,5 +89,5 @@ pub fn draw(_time: f64) -> Vec<Point> {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
v
|
Ok(v)
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
#[allow(unused)]
|
|
||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
/// Converts helios Geometry to Helios
|
/// Converts helios Geometry to Helios
|
||||||
#[allow(dead_code)]
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Framerate {
|
pub struct Framerate {
|
||||||
start: Instant,
|
start: Instant,
|
||||||
@ -12,7 +10,6 @@ pub struct Framerate {
|
|||||||
framerate: u8,
|
framerate: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
impl Framerate {
|
impl Framerate {
|
||||||
pub fn new(framerate: u8) -> Result<Self, Box<dyn std::error::Error>> {
|
pub fn new(framerate: u8) -> Result<Self, Box<dyn std::error::Error>> {
|
||||||
Ok(Framerate {
|
Ok(Framerate {
|
||||||
@ -21,7 +18,7 @@ impl Framerate {
|
|||||||
framerate,
|
framerate,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn handle_time(&mut self) -> Result<f64, Box<dyn std::error::Error>> {
|
pub fn handle_time(&mut self) -> Result<(f64), Box<dyn std::error::Error>> {
|
||||||
let frame_time = 1000000000 / self.framerate as u128;
|
let frame_time = 1000000000 / self.framerate as u128;
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
// How long since last loop ?
|
// How long since last loop ?
|
||||||
|
54
src/main.rs
54
src/main.rs
@ -11,7 +11,7 @@ mod point;
|
|||||||
mod qualibration;
|
mod qualibration;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use qualibration::{annalyse::adding_trackbar, Qualibration};
|
use qualibration::{annalyse::adding_trackbar, Qualibration, Sequence};
|
||||||
|
|
||||||
use conf::Conf;
|
use conf::Conf;
|
||||||
use log::{/*debug, warn, */ error, info};
|
use log::{/*debug, warn, */ error, info};
|
||||||
@ -57,7 +57,7 @@ fn run_all() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let client = Client::open(config.redis_url.clone())?;
|
let client = Client::open(config.redis_url.clone())?;
|
||||||
let mut con: Connection = client.get_connection()?;
|
let mut con: Connection = client.get_connection()?;
|
||||||
|
|
||||||
let mut _framerate_handler = framerate::Framerate::new(config.framerate)?;
|
let mut framerate_handler = framerate::Framerate::new(config.framerate)?;
|
||||||
|
|
||||||
// Setup handler for interrupt Signals
|
// Setup handler for interrupt Signals
|
||||||
let running = Arc::new(AtomicBool::new(true));
|
let running = Arc::new(AtomicBool::new(true));
|
||||||
@ -78,7 +78,7 @@ fn run_all() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
info!("{:?}", config);
|
info!("{:?}", config);
|
||||||
|
|
||||||
let mut qualibration = Qualibration::new()?;
|
let mut qualibration = Qualibration::new()?;
|
||||||
adding_trackbar(&mut qualibration.param, "histogram: 0")?;
|
adding_trackbar(&mut qualibration, "histogram: 0")?;
|
||||||
|
|
||||||
let _a: () = con.set(format!("/kpps/{}", conf2.laser_id), 65535)?;
|
let _a: () = con.set(format!("/kpps/{}", conf2.laser_id), 65535)?;
|
||||||
let _a: () = con.set(
|
let _a: () = con.set(
|
||||||
@ -87,46 +87,44 @@ 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 _t = framerate_handler.handle_time()?;
|
||||||
/////////////////
|
/////////////////
|
||||||
let key = highgui::wait_key(1)?;
|
let key = highgui::wait_key(1)?;
|
||||||
qualibration.param.key = key;
|
//if key != -1 {
|
||||||
|
qualibration.key = key;
|
||||||
|
//}
|
||||||
if key == 27 {
|
if key == 27 {
|
||||||
|
// esc in my case
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let v = qualibration.draw_sequence();
|
//qualibration.id = next_id;
|
||||||
if v.is_some() {
|
let v: Vec<(f32, f32, u32)> = qualibration
|
||||||
if qualibration.param.capture_mode {
|
.draw_sequence()?
|
||||||
let pl: Vec<(f32, f32, u32)> = v
|
|
||||||
.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();
|
||||||
|
// println!("{:?}", v);
|
||||||
let _ = con.set(
|
let _ = con.set(
|
||||||
format!("/pl/{}/{}", config.client_id, config.laser_id),
|
format!("/pl/{}/{}", config.client_id, config.laser_id),
|
||||||
format!("{:?}", pl),
|
format!("{:?}", v),
|
||||||
)?;
|
)?;
|
||||||
}
|
|
||||||
|
|
||||||
qualibration.run_step()?;
|
qualibration.run_step()?;
|
||||||
}
|
|
||||||
//qualibration.id = next_id;
|
|
||||||
|
|
||||||
//let q_id = qualibration.id.clone();
|
let q_id = qualibration.id.clone();
|
||||||
//let mut n = 65534;
|
let mut n = 65534;
|
||||||
//if let Sequence::TakeMultiple(m) = q_id.clone().unwrap_or(Sequence::Finish) {
|
if let Sequence::TakeMultiple(m) = q_id.clone().unwrap_or(Sequence::Finish) {
|
||||||
// n = m;
|
n = m;
|
||||||
//};
|
};
|
||||||
//if qualibration.capture_mode
|
if qualibration.capture_mode
|
||||||
// && (q_id != Some(Sequence::WaitSpace)
|
&& (q_id != Some(Sequence::WaitSpace)
|
||||||
// || q_id != Some(Sequence::PlayLineDotted)
|
|| q_id != Some(Sequence::PlayLineDotted)
|
||||||
// || n != 65534)
|
|| n != 65534)
|
||||||
//{
|
{
|
||||||
// let millis = std::time::Duration::from_millis(400); // TODO: find solution to know when change has been done
|
let millis = std::time::Duration::from_millis(400); // TODO: find solution to know when change has been done
|
||||||
// std::thread::sleep(millis);
|
std::thread::sleep(millis);
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = con.set(
|
let _ = con.set(
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#[allow(dead_code)]
|
|
||||||
pub type Line = Vec<(f32, f32, u32)>;
|
pub type Line = Vec<(f32, f32, u32)>;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq)]
|
#[derive(Debug, Clone, Copy, Default, PartialEq)]
|
||||||
|
@ -1,45 +1,121 @@
|
|||||||
//use opencv::Result;
|
|
||||||
//use opencv::core::{self, Mat};
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
static DEBUG: bool = true;
|
|
||||||
|
|
||||||
pub mod annalyse;
|
pub mod annalyse;
|
||||||
pub mod borders;
|
pub mod borders;
|
||||||
pub mod compute_image;
|
pub mod compute_image;
|
||||||
|
|
||||||
|
use annalyse::{
|
||||||
|
draw_histograme_bgr_tresh, get_horizontal_segment, get_vertical_segment, histogram_3d,
|
||||||
|
image_diff, image_mean,
|
||||||
|
}; // mean dans le sans moyenne des image
|
||||||
|
use borders::{bord_mult, get_extermities, get_intersection, mix_borders, probabilistic_hough};
|
||||||
|
use compute_image::{image_treshold, image_warp, image_warp_treshold};
|
||||||
use std::env::args;
|
use std::env::args;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
use crate::point::Point;
|
use crate::draw::{draw_line, draw_line_dotted};
|
||||||
|
use crate::point::{Color, Point};
|
||||||
|
|
||||||
|
use enum_iterator::{next, Sequence as Seq};
|
||||||
use opencv::core::Mat;
|
use opencv::core::Mat;
|
||||||
use opencv::Result;
|
use opencv::Result;
|
||||||
//use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
|
|
||||||
|
use opencv::core::{bitwise_and, find_file, in_range, Point as OcvPoint, Scalar, Size_};
|
||||||
|
use opencv::core::{VecN, Vector};
|
||||||
|
use opencv::imgcodecs::imwrite;
|
||||||
|
use opencv::imgcodecs::{imread, IMREAD_COLOR};
|
||||||
|
use opencv::imgproc::{canny, cvt_color, line, COLOR_BGR2GRAY};
|
||||||
use opencv::prelude::*;
|
use opencv::prelude::*;
|
||||||
use opencv::{
|
use opencv::{
|
||||||
highgui,
|
highgui,
|
||||||
videoio::{self, VideoCapture},
|
videoio::{self, VideoCapture},
|
||||||
};
|
};
|
||||||
|
use std::fs::create_dir;
|
||||||
|
use std::fs::read_dir;
|
||||||
|
|
||||||
mod param;
|
use opencv::{
|
||||||
use param::Param;
|
calib3d,
|
||||||
|
core::{self, Size},
|
||||||
|
imgproc,
|
||||||
|
};
|
||||||
|
|
||||||
mod sequence;
|
opencv::opencv_branch_4! {
|
||||||
pub use sequence::{InitBorder, InitIdcode, LineDotted, LoadImage, SaveImage, Sequence, WaitSpace};
|
use opencv::imgproc::LINE_AA;
|
||||||
|
use opencv::imgproc::LINE_8;
|
||||||
|
}
|
||||||
|
opencv::not_opencv_branch_4! {
|
||||||
|
use opencv::core::LINE_AA;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEBUG: bool = true;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Seq, Copy, Clone)]
|
||||||
|
pub enum Sequence {
|
||||||
|
//TODO: avoir le meme nombre d'image en mode capture ET en mode replay
|
||||||
|
FirstState,
|
||||||
|
WaitSpace,
|
||||||
|
BackGround,
|
||||||
|
UpBorder,
|
||||||
|
LeftBorder,
|
||||||
|
DownBorder,
|
||||||
|
RightBorder,
|
||||||
|
ReadDir,
|
||||||
|
ComputeArea,
|
||||||
|
IdCode1,
|
||||||
|
IdCode2,
|
||||||
|
Finish,
|
||||||
|
|
||||||
|
PlayLineDotted,
|
||||||
|
EmptyFrame,
|
||||||
|
ComputeLineDotted,
|
||||||
|
|
||||||
|
LinearConstSpeed, // [multiple test]
|
||||||
|
JumpFromTo,
|
||||||
|
|
||||||
|
AdaptLineSeg(u16), // [multiple test] find the correct distense
|
||||||
|
AdaptLineLum, // [multiple test] try minimu, medium, maximum.
|
||||||
|
//
|
||||||
|
SelectSpeedestColor, // on pourait mettre a jour les valeur a chaque passage
|
||||||
|
|
||||||
|
Vertical(u16),
|
||||||
|
Horizontal(u16),
|
||||||
|
SelectNbAll(u16),
|
||||||
|
ComputeSelectNbAll,
|
||||||
|
TakeMultiple(u16),
|
||||||
|
TakeMultipleEmpty(u16),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Qualibration {
|
pub struct Qualibration {
|
||||||
seq: Vec<Box<dyn Sequence>>,
|
pub begin: Instant,
|
||||||
cam: VideoCapture,
|
pub dst_size: i32,
|
||||||
|
pub cam: VideoCapture,
|
||||||
pub param: Param,
|
pub r: i32,
|
||||||
|
pub g: i32,
|
||||||
|
pub b: i32,
|
||||||
|
pub capture_mode: bool,
|
||||||
|
pub frame: Mat,
|
||||||
|
pub frame_prev: Mat,
|
||||||
|
pub img: Vec<Mat>,
|
||||||
|
pub id: Option<Sequence>,
|
||||||
|
pub nb_all: i32,
|
||||||
|
pub nb_visible: i32,
|
||||||
|
pub nb_liss: i32,
|
||||||
|
pub tresh: Treshold,
|
||||||
|
pub dir_name: String,
|
||||||
|
pub key: i32,
|
||||||
|
pub canny_v1: i32,
|
||||||
|
pub canny_v2: i32,
|
||||||
|
pub hough_param: HoughLine,
|
||||||
|
pub border_pt: Vec<(f64, f64)>,
|
||||||
|
pub homography: Mat,
|
||||||
|
pub h_size: Size_<i32>,
|
||||||
|
pub line_pos: Vec<i32>,
|
||||||
|
pub multiple: u16, // le nombre de fois qu'une photo est prise pour certaine sequence
|
||||||
|
pub cnt: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Qualibration {
|
impl Qualibration {
|
||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self> {
|
||||||
//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
|
||||||
if let Some(dir_name_arg) = args().nth(1) {
|
if let Some(dir_name_arg) = args().nth(1) {
|
||||||
dir_name = dir_name_arg;
|
dir_name = dir_name_arg;
|
||||||
@ -54,58 +130,816 @@ 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
|
|
||||||
let beg = Point::from((0., 0., 38400));
|
|
||||||
let beg2 = Point::from((4095., 0., 38400));
|
|
||||||
let end = Point::from((4095., 4095., 38400));
|
|
||||||
let seq: Vec<Box<dyn Sequence>> = vec![
|
|
||||||
Box::new(LoadImage::new()),
|
|
||||||
Box::new(WaitSpace::new(beg, end)),
|
|
||||||
Box::new(InitBorder::new(beg, end)),
|
|
||||||
Box::new(LineDotted::new(beg, end, true, false)),
|
|
||||||
Box::new(InitIdcode::new(beg2, end)),
|
|
||||||
Box::new(SaveImage::new()),
|
|
||||||
];
|
|
||||||
//let now = std::time::Instant::now();
|
//let now = std::time::Instant::now();
|
||||||
Ok(Qualibration {
|
Ok(Qualibration {
|
||||||
seq,
|
begin: std::time::Instant::now(),
|
||||||
|
dst_size: 900,
|
||||||
cam,
|
cam,
|
||||||
param: Param::new(dir_name.to_owned())?,
|
r: 150,
|
||||||
|
g: 0,
|
||||||
|
b: 0,
|
||||||
|
capture_mode: dir_name.len() == 0,
|
||||||
|
img: vec![],
|
||||||
|
frame: Mat::default(), // TODO: init with frame from cam
|
||||||
|
frame_prev: Mat::default(),
|
||||||
|
id: Some(Sequence::FirstState),
|
||||||
|
nb_all: 120,
|
||||||
|
nb_visible: 40,
|
||||||
|
nb_liss: 10,
|
||||||
|
tresh: Treshold::new("histogram: 0", 150, 255)?,
|
||||||
|
dir_name: dir_name.clone(),
|
||||||
|
key: 10,
|
||||||
|
canny_v1: 170,
|
||||||
|
canny_v2: 255,
|
||||||
|
hough_param: HoughLine {
|
||||||
|
rho: 100,
|
||||||
|
theta: 100,
|
||||||
|
treshold: 30,
|
||||||
|
min_length: 0,
|
||||||
|
max_line_gap: 50000,
|
||||||
|
},
|
||||||
|
border_pt: vec![],
|
||||||
|
homography: Mat::default(),
|
||||||
|
h_size: Size::default(),
|
||||||
|
line_pos: vec![4095; 34],
|
||||||
|
multiple: 20,
|
||||||
|
cnt: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_sequence(&mut self) -> Option<Vec<Point>> {
|
pub fn run_step(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if self.param.seq_id >= self.seq.len() {
|
if self.capture_mode && self.id != Some(Sequence::PlayLineDotted) {
|
||||||
|
//println!("capture");
|
||||||
|
self.cam.read(&mut self.frame)?;
|
||||||
|
highgui::imshow("camera", &self.frame)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.frame.size()?.width > 0 && self.frame_prev.size()?.width > 0 || !self.capture_mode {
|
||||||
|
if self.id.is_some() {
|
||||||
|
self.id = if true {
|
||||||
|
//self.capture_mode || self.id == Some(Sequence::WaitSpace) || is_same_frame(&self.frame, &self.frame_prev)? {
|
||||||
|
if self.id != Some(Sequence::WaitSpace)
|
||||||
|
&& self.id != Some(Sequence::FirstState)
|
||||||
|
&& self.id != Some(Sequence::PlayLineDotted)
|
||||||
|
&& self.capture_mode
|
||||||
|
{
|
||||||
|
self.img.push(self.frame.clone());
|
||||||
|
}
|
||||||
|
self.compute_sequence()?;
|
||||||
|
self.get_next_id_seq()
|
||||||
|
} else {
|
||||||
|
self.id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//println!("sequence: {:?}", self.id);
|
||||||
|
self.frame_prev = self.frame.clone();
|
||||||
|
self.cnt += 1;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_sequence(&self) -> Result<Vec<Point>, Box<dyn std::error::Error>> {
|
||||||
|
if !self.capture_mode {
|
||||||
|
return Ok(vec![]);
|
||||||
|
}
|
||||||
|
let seq = self.id;
|
||||||
|
let mut pl = vec![];
|
||||||
|
//let color = Color { r: 0, g: 30, b: 0 };
|
||||||
|
let color = Color {
|
||||||
|
r: self.r as u8,
|
||||||
|
g: self.g as u8,
|
||||||
|
b: self.b as u8,
|
||||||
|
};
|
||||||
|
//let color = Color { r: 0, g: 0, b: 50 };
|
||||||
|
let (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa, pb) =
|
||||||
|
get_point_to_draw(self.r as u8, self.g as u8, self.b as u8, color.clone());
|
||||||
|
let nb_all = self.nb_all as usize;
|
||||||
|
let nb_visible = self.nb_visible as usize;
|
||||||
|
let nb_wait = 30; // ca permet de prendre de la vitess en y. Et donc ca permet de
|
||||||
|
// mieux voir les segment qui bouge peut au debut.
|
||||||
|
|
||||||
|
if seq.is_some() {
|
||||||
|
match seq.unwrap() {
|
||||||
|
Sequence::IdCode1 => {
|
||||||
|
// on va en haut a gauche
|
||||||
|
// on va a droite en clognotant sur les nombre pair
|
||||||
|
pl.extend(draw_line_dotted(&pa, &pb, nb_all, nb_visible, true)?);
|
||||||
|
}
|
||||||
|
Sequence::IdCode2 => {
|
||||||
|
// on va en haut a gauche
|
||||||
|
// on va a droite en clognotant sur les nombre impair
|
||||||
|
pl.extend(draw_line_dotted(&pa, &pb, nb_all, nb_visible, false)?);
|
||||||
|
}
|
||||||
|
Sequence::PlayLineDotted
|
||||||
|
| Sequence::TakeMultiple(_)
|
||||||
|
| Sequence::ComputeLineDotted => {
|
||||||
|
// la on va faire une ligne qu'on peut observer
|
||||||
|
let black = Color { r: 0, g: 0, b: 0 };
|
||||||
|
for _ in 0..nb_all {
|
||||||
|
pl.push(Point {
|
||||||
|
x: 0.,
|
||||||
|
y: 0.,
|
||||||
|
color: black,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let len = (2 * self.line_pos.len() + nb_wait) as f32;
|
||||||
|
for i in 0..nb_wait {
|
||||||
|
let y = i as f32 * 4095. / len;
|
||||||
|
pl.push(Point {
|
||||||
|
x: 0.,
|
||||||
|
y,
|
||||||
|
color: black,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for i in 0..(self.line_pos.len() * 2) {
|
||||||
|
let y = (i + nb_wait) as f32 * 4095. / len;
|
||||||
|
let c = if (i + nb_wait) % 2 == 0 && i < nb_visible {
|
||||||
|
color
|
||||||
|
} else {
|
||||||
|
black
|
||||||
|
};
|
||||||
|
pl.push(Point {
|
||||||
|
x: self.line_pos[i / 2] as f32,
|
||||||
|
y,
|
||||||
|
color: c,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sequence::WaitSpace => {
|
||||||
|
pl = draw_line(&p0, &p1, nb_all, nb_visible)?;
|
||||||
|
pl.extend(draw_line(&p1, &p2, nb_all, nb_visible)?);
|
||||||
|
pl.extend(draw_line(&p3, &p0, nb_all, nb_visible)?);
|
||||||
|
pl.extend(draw_line(&p2, &p3, nb_all, nb_visible)?);
|
||||||
|
|
||||||
|
pl.extend(draw_line_dotted(&p4, &p5, nb_all, nb_visible, true)?);
|
||||||
|
pl.extend(draw_line_dotted(&p6, &p7, nb_all, nb_visible, true)?);
|
||||||
|
pl.extend(draw_line_dotted(&p8, &p9, nb_all, nb_visible, true)?);
|
||||||
|
}
|
||||||
|
Sequence::SelectNbAll(n) => {
|
||||||
|
pl = draw_line(&p0, &p1, n as usize, n as usize)?;
|
||||||
|
pl.extend(draw_line(&p1, &p2, n as usize, n as usize)?);
|
||||||
|
pl.extend(draw_line(&p3, &p0, n as usize, n as usize)?);
|
||||||
|
pl.extend(draw_line(&p2, &p3, n as usize, n as usize)?);
|
||||||
|
}
|
||||||
|
Sequence::UpBorder => {
|
||||||
|
pl = draw_line(&p0, &p1, nb_all, nb_visible)?;
|
||||||
|
}
|
||||||
|
Sequence::RightBorder => {
|
||||||
|
pl = draw_line(&p1, &p2, nb_all, nb_visible)?;
|
||||||
|
}
|
||||||
|
Sequence::DownBorder => {
|
||||||
|
pl = draw_line(&p2, &p3, nb_all, nb_visible)?;
|
||||||
|
}
|
||||||
|
Sequence::LeftBorder => {
|
||||||
|
pl = draw_line(&p3, &p0, nb_all, nb_visible)?;
|
||||||
|
}
|
||||||
|
Sequence::Vertical(n) => {
|
||||||
|
let p1 = Point {
|
||||||
|
x: n as f32,
|
||||||
|
y: 0.,
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
let p2 = Point {
|
||||||
|
x: n as f32,
|
||||||
|
y: 4095.,
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
pl = draw_line(&p1, &p2, nb_all, nb_visible)?;
|
||||||
|
}
|
||||||
|
Sequence::Horizontal(n) => {
|
||||||
|
let p1 = Point {
|
||||||
|
x: 0.,
|
||||||
|
y: n as f32,
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
let p2 = Point {
|
||||||
|
x: 4095.,
|
||||||
|
y: n as f32,
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
pl = draw_line(&p1, &p2, nb_all, nb_visible)?;
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(pl)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_next_id_seq(&self) -> Option<Sequence> {
|
||||||
|
let line_max = 4095;
|
||||||
|
let line_add = 100;
|
||||||
|
|
||||||
|
if self.id.is_none() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pl = self.seq[self.param.seq_id].draw(&self.param);
|
//println!("Hey");
|
||||||
|
match self.id.unwrap() {
|
||||||
if pl.is_none() {
|
//Sequence::Finish => Some(Sequence::Finish),
|
||||||
self.param.seq_id += 1;
|
Sequence::Finish => None,
|
||||||
if self.param.capture_mode {
|
Sequence::ComputeLineDotted => Some(Sequence::ComputeLineDotted),
|
||||||
self.param.imgs.push(vec![]);
|
Sequence::TakeMultiple(n) => {
|
||||||
|
if n > self.multiple {
|
||||||
|
next(&Sequence::TakeMultiple(u16::MAX))
|
||||||
|
} else {
|
||||||
|
next(&Sequence::TakeMultiple(n))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sequence::TakeMultipleEmpty(n) => {
|
||||||
|
if n > self.multiple {
|
||||||
|
next(&Sequence::TakeMultipleEmpty(u16::MAX))
|
||||||
|
} else {
|
||||||
|
next(&Sequence::TakeMultipleEmpty(n))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sequence::SelectNbAll(n) => {
|
||||||
|
if n == 0 {
|
||||||
|
Some(Sequence::SelectNbAll(2 - 1))
|
||||||
|
} else if (2 * n) > line_max as u16 {
|
||||||
|
next(&Sequence::SelectNbAll(u16::MAX))
|
||||||
|
} else {
|
||||||
|
next(&Sequence::SelectNbAll(n * 2 - 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sequence::WaitSpace => {
|
||||||
|
//println!("key: {}", self.key);
|
||||||
|
if self.key == 32 || !self.capture_mode {
|
||||||
|
next(&Sequence::WaitSpace)
|
||||||
|
} else {
|
||||||
|
Some(Sequence::WaitSpace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sequence::PlayLineDotted => {
|
||||||
|
//println!("key: {}", self.key);
|
||||||
|
if self.key == 32 || !self.capture_mode {
|
||||||
|
next(&Sequence::PlayLineDotted)
|
||||||
|
} else {
|
||||||
|
Some(Sequence::PlayLineDotted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sequence::Vertical(n) => {
|
||||||
|
let after = if n > line_max { u16::MAX } else { n + line_add };
|
||||||
|
next(&Sequence::Vertical(after))
|
||||||
|
}
|
||||||
|
Sequence::Horizontal(n) => {
|
||||||
|
let after = if n > line_max { u16::MAX } else { n + line_add };
|
||||||
|
next(&Sequence::Horizontal(after))
|
||||||
|
}
|
||||||
|
//Sequence::ComputeArea => Some(Sequence::ComputeArea), //
|
||||||
|
id => next(&id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pl
|
pub fn compute_sequence(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
if self.id.is_none() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
match self.id.unwrap() {
|
||||||
|
Sequence::IdCode2 => {
|
||||||
|
let mut id_code_1 = image_diff(&self.img[8], &self.img[1])?;
|
||||||
|
|
||||||
|
id_code_1 = image_warp(&id_code_1, &self.homography, self.h_size)?;
|
||||||
|
id_code_1 = image_treshold(&id_code_1, &self.tresh)?;
|
||||||
|
|
||||||
|
let code_seg_1 = get_horizontal_segment(&id_code_1)?;
|
||||||
|
let code_seg_1 = code_seg_1[1..(code_seg_1.len() - 1)].to_owned();
|
||||||
|
//let l = code_seg_1.len();
|
||||||
|
//let code_seg_1 = code_seg_1[(l-16)..(l-1)].to_owned();
|
||||||
|
|
||||||
|
//let blue = (i as f64 / code_seg_1.len() as f64) * 255.;
|
||||||
|
let color_1: VecN<f64, 4> = VecN::new(255., 0., 0., 255.);
|
||||||
|
// on dessine
|
||||||
|
for i in 0..code_seg_1.len() {
|
||||||
|
let (((x0, y0), (x1, y1)), size) = code_seg_1[i];
|
||||||
|
//line(&mut id_code_1, );
|
||||||
|
let s = size as i32;
|
||||||
|
let x = ((x0 + x1) / 2.) as i32;
|
||||||
|
let y = ((y0 + y1) / 2.) as i32;
|
||||||
|
let a = OcvPoint::from_vec2(VecN::from_array([x, y - s]));
|
||||||
|
let b = OcvPoint::from_vec2(VecN::from_array([x, y + s]));
|
||||||
|
line(&mut id_code_1, a, b, color_1, 1, LINE_8, 0)?;
|
||||||
|
//if i < (code_seg_1.len() - 1) {
|
||||||
|
// let (((x2, y2), _), size) = code_seg_1[i + 1];
|
||||||
|
// let x = ((x1 + x2) / 2.) as i32;
|
||||||
|
// let y = ((y0 + y1) / 2.) as i32;
|
||||||
|
// let a = OcvPoint::from_vec2(VecN::from_array([x, y - s]));
|
||||||
|
// let b = OcvPoint::from_vec2(VecN::from_array([x, y + s]));
|
||||||
|
// line(&mut id_code_1, a, b, color_1, 1, LINE_8, 0)?;
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_step(self: &mut Self) -> Result<(), Box<dyn std::error::Error>> {
|
let mut id_code_2 = image_diff(&self.img[9], &self.img[1])?;
|
||||||
let mut frame = Mat::default();
|
id_code_2 = image_warp(&id_code_2, &self.homography, self.h_size)?;
|
||||||
if self.param.capture_mode {
|
id_code_2 = image_treshold(&id_code_2, &self.tresh)?;
|
||||||
self.cam.read(&mut frame)?;
|
let code_seg_2 = get_horizontal_segment(&id_code_2)?;
|
||||||
highgui::imshow("camera", &frame)?;
|
let l = code_seg_2.len();
|
||||||
|
let code_seg_2 = code_seg_2[(l - 16)..(l - 1)].to_owned();
|
||||||
if frame.size()?.width > 0 && self.seq[self.param.seq_id].is_capture() {
|
//highgui::imshow("code 2", &id_code_2)?;
|
||||||
self.param.imgs[self.param.seq_id].push(frame.clone());
|
let color_2: VecN<f64, 4> = VecN::new(0., 255., 0., 255.);
|
||||||
}
|
// on dessine
|
||||||
|
for i in 0..code_seg_2.len() {
|
||||||
|
let (((x0, y0), (x1, y1)), size) = code_seg_2[i];
|
||||||
|
//line(&mut id_code_2, );
|
||||||
|
let s = size as i32;
|
||||||
|
let x = ((x0 + x1) / 2.) as i32;
|
||||||
|
let y = ((y0 + y1) / 2.) as i32;
|
||||||
|
let a = OcvPoint::from_vec2(VecN::from_array([x, y - s]));
|
||||||
|
let b = OcvPoint::from_vec2(VecN::from_array([x, y + s]));
|
||||||
|
line(&mut id_code_1, a, b, color_2, 1, LINE_8, 0)?;
|
||||||
|
//if i < (code_seg_2.len() - 1) {
|
||||||
|
// let (((x2, y2), _), size) = code_seg_2[i + 1];
|
||||||
|
// let x = ((x1 + x2) / 2.) as i32;
|
||||||
|
// let y = ((y0 + y1) / 2.) as i32;
|
||||||
|
// let a = OcvPoint::from_vec2(VecN::from_array([x, y - s]));
|
||||||
|
// let b = OcvPoint::from_vec2(VecN::from_array([x, y + s]));
|
||||||
|
// line(&mut id_code_2, a, b, color_2, 1, LINE_8, 0)?;
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
if frame.size()?.width > 0 || !self.param.capture_mode {
|
// on va faire des ligne sur les endroit de scanne
|
||||||
self.seq[self.param.seq_id].compute_sequence(&mut self.param)?;
|
|
||||||
|
highgui::imshow("code 1", &id_code_1)?;
|
||||||
|
|
||||||
|
// si on garde les [(len-16)..(len-1)]
|
||||||
|
|
||||||
|
//let mean = image_mean(&[id_code_1, id_code_2])?;
|
||||||
|
//highgui::imshow("image mean", &mean)?;
|
||||||
|
|
||||||
|
// la on pourrait aussi mettre les segment
|
||||||
|
|
||||||
|
// On va regarder au milieux de code_2 pour voir si on voi un truc sur code_1
|
||||||
|
|
||||||
|
// fonction warp image
|
||||||
|
// fonction select thresh
|
||||||
|
// BOUUUUUH !!! ... t'as eut peur?
|
||||||
|
//
|
||||||
|
//let mut id_code_2 = image_diff(&self.img[9], &self.img[1])?;
|
||||||
|
//id_code_2 = image_warp(&id_code_2, &self.homography, self.h_size)?;
|
||||||
|
//id_code_2 = image_treshold(&id_code_2, &self.tresh)?;
|
||||||
|
//highgui::imshow("code 2", &id_code_2)?;
|
||||||
|
}
|
||||||
|
Sequence::ComputeLineDotted => {
|
||||||
|
let id1 = 7 + (self.cnt % 22);
|
||||||
|
let id2 = 30 + (self.cnt % 22);
|
||||||
|
//let backgrounds = self.img[7..30].to_owned();
|
||||||
|
//let lines_dots = self.img[30..52].to_owned();
|
||||||
|
let backgrounds = self.img[id1..(id1 + 1)].to_owned();
|
||||||
|
let lines_dots = self.img[id2..(id2 + 1)].to_owned();
|
||||||
|
|
||||||
|
let background = image_mean(&backgrounds)?;
|
||||||
|
let line_dot = image_mean(&lines_dots)?;
|
||||||
|
let diff = image_diff(&background, &line_dot)?;
|
||||||
|
|
||||||
|
let mut warped_image = Mat::default();
|
||||||
|
imgproc::warp_perspective(
|
||||||
|
&diff,
|
||||||
|
&mut warped_image,
|
||||||
|
&self.homography,
|
||||||
|
self.h_size,
|
||||||
|
imgproc::INTER_CUBIC, // I dont see difference with INTER_CUBIC
|
||||||
|
core::BORDER_CONSTANT,
|
||||||
|
Scalar::default(),
|
||||||
|
)?;
|
||||||
|
//highgui::imshow("Warped Image", &warped_image)?;
|
||||||
|
|
||||||
|
let histo = histogram_3d(&warped_image, self.nb_liss)?;
|
||||||
|
draw_histograme_bgr_tresh("histo bgr", &histo, &self.tresh)?;
|
||||||
|
|
||||||
|
let (t1, s1, l1) = (
|
||||||
|
self.tresh.min_0 as f64,
|
||||||
|
self.tresh.min_1 as f64,
|
||||||
|
self.tresh.min_2 as f64,
|
||||||
|
);
|
||||||
|
let (t2, s2, l2) = (
|
||||||
|
self.tresh.max_0 as f64,
|
||||||
|
self.tresh.max_1 as f64,
|
||||||
|
self.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 = get_vertical_segment(&bord_treshed)?;
|
||||||
|
for (i, ((x0, y0), (x1, y1))) 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)?;
|
||||||
|
}
|
||||||
|
Sequence::ComputeSelectNbAll => {
|
||||||
|
let background: Mat;
|
||||||
|
let steps: Vec<Mat>;
|
||||||
|
|
||||||
|
background = self.img[1].clone();
|
||||||
|
steps = self.img[2..6].into();
|
||||||
|
|
||||||
|
let mut angles: Vec<f64> = vec![];
|
||||||
|
for (id, step) in steps.iter().enumerate() {
|
||||||
|
let lines = get_lines(
|
||||||
|
&background,
|
||||||
|
step,
|
||||||
|
id,
|
||||||
|
self.canny_v1,
|
||||||
|
self.canny_v2,
|
||||||
|
&self.hough_param,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
for l in lines {
|
||||||
|
let (x0, y0, x1, y1) = (l[0] as f64, l[1] as f64, l[2] as f64, l[3] as f64);
|
||||||
|
|
||||||
|
let ang = (y1 - y0).atan2(x1 - x0);
|
||||||
|
angles.push(ang);
|
||||||
|
}
|
||||||
|
println!("ang: {angles:?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// on compare ce qui doit l'etre
|
||||||
|
}
|
||||||
|
Sequence::ComputeArea => {
|
||||||
|
let background: Mat;
|
||||||
|
let borders: Vec<Mat>;
|
||||||
|
|
||||||
|
background = self.img[1].clone();
|
||||||
|
borders = self.img[2..6].into();
|
||||||
|
|
||||||
|
// on recupere chaqu'un des 4 bord
|
||||||
|
let mut bords_pts = vec![];
|
||||||
|
for (i, bord) in borders.iter().enumerate() {
|
||||||
|
let bord_pt = self.get_one_border(&background, &bord, i)?;
|
||||||
|
bords_pts.push(bord_pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
//for (i, m) in self.img.iter().enumerate() {
|
||||||
|
// highgui::imshow(format!("img[{i}]").as_str(), m)?;
|
||||||
|
//}
|
||||||
|
|
||||||
|
// on calcul le cadre
|
||||||
|
let border_pt = get_intersection(&bords_pts);
|
||||||
|
self.border_pt = bord_mult(border_pt, 1.1);
|
||||||
|
let color: VecN<f64, 4> = VecN::new(255., 128., 0., 255.);
|
||||||
|
let mut mixed = mix_borders(&background, borders)?;
|
||||||
|
let b = &self.border_pt;
|
||||||
|
for i in 0..b.len() {
|
||||||
|
let j = (i + 1) % self.border_pt.len();
|
||||||
|
let pa = VecN::from_array([b[i].0 as i32, b[i].1 as i32]);
|
||||||
|
let pb = VecN::from_array([b[j].0 as i32, b[j].1 as i32]);
|
||||||
|
let a = OcvPoint::from_vec2(pa);
|
||||||
|
let b = OcvPoint::from_vec2(pb);
|
||||||
|
line(&mut mixed, a, b, color, 1, LINE_AA, 0)?;
|
||||||
|
}
|
||||||
|
//highgui::imshow("mixed bored", &mixed)?;
|
||||||
|
|
||||||
|
let size = self.dst_size;
|
||||||
|
// ici on va requadrer la partie de la projection laser de l'image
|
||||||
|
let warped_image_size = Size::new(size, size);
|
||||||
|
let roi_corners: Vec<OcvPoint> = self
|
||||||
|
.border_pt
|
||||||
|
.iter()
|
||||||
|
.map(|(x, y)| OcvPoint::new(*x as i32, *y as i32))
|
||||||
|
.collect();
|
||||||
|
//let dst = [(0, 0), (0, size), (size, size), (size, 0)]; // in: laser repere
|
||||||
|
let dst = [(0, size), (0, 0), (size, 0), (size, size)];
|
||||||
|
let dst_corners: Vec<OcvPoint> =
|
||||||
|
dst.iter().map(|(x, y)| OcvPoint::new(*x, *y)).collect();
|
||||||
|
let roi_corners_mat = Mat::from_slice(&roi_corners[..])?;
|
||||||
|
let dst_corners_mat = Mat::from_slice(&dst_corners)?;
|
||||||
|
let h = calib3d::find_homography(
|
||||||
|
&roi_corners_mat,
|
||||||
|
&dst_corners_mat,
|
||||||
|
&mut Mat::default(),
|
||||||
|
0,
|
||||||
|
3.,
|
||||||
|
)?; //get homography
|
||||||
|
let mut warped_image = Mat::default();
|
||||||
|
self.homography = h.clone();
|
||||||
|
self.h_size = warped_image_size.clone();
|
||||||
|
imgproc::warp_perspective(
|
||||||
|
&mixed,
|
||||||
|
&mut warped_image,
|
||||||
|
&h,
|
||||||
|
warped_image_size,
|
||||||
|
imgproc::INTER_CUBIC, // I dont see difference with INTER_CUBIC
|
||||||
|
core::BORDER_CONSTANT,
|
||||||
|
Scalar::default(),
|
||||||
|
)?; // do perspective transformation
|
||||||
|
//highgui::imshow("Warped Image", &warped_image)?;
|
||||||
|
}
|
||||||
|
Sequence::ReadDir => {
|
||||||
|
if !self.capture_mode {
|
||||||
|
self.load_image()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sequence::Finish => {
|
||||||
|
if self.capture_mode {
|
||||||
|
self.save_image()?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save_image(&self) -> Result<()> {
|
||||||
|
// on fait le nom de dossier general au cas ou
|
||||||
|
// on fait un nom de dossier avec le temps
|
||||||
|
// on sauvgarde toutes les image
|
||||||
|
let now = self.begin;
|
||||||
|
let name = format!("image/");
|
||||||
|
create_dir(&name).unwrap_or(());
|
||||||
|
let name = format!(
|
||||||
|
"image/{:0>6?}_{:0>9?}/",
|
||||||
|
now.elapsed().as_secs(),
|
||||||
|
now.elapsed().as_nanos()
|
||||||
|
);
|
||||||
|
create_dir(&name).unwrap_or(());
|
||||||
|
//name.push_str(format!("image/{}_{}/", now.elapsed().as_secs(), now.elapsed().as_nanos()).as_str());
|
||||||
|
//let name = format!("image/{now:?}/");
|
||||||
|
|
||||||
|
//
|
||||||
|
for (i, img) in self.img.iter().enumerate() {
|
||||||
|
let mut name_img = name.clone();
|
||||||
|
name_img.push_str(&format!("img_{i}.png"));
|
||||||
|
imwrite(&name_img, img, &Vector::from_slice(&[6, 6, 6, 0]))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//use std::cmp::Ordering;
|
||||||
|
fn load_image(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut imgs = vec![];
|
||||||
|
let paths = read_dir(&self.dir_name)?;
|
||||||
|
//let len = paths.size_hint();
|
||||||
|
for entry in paths {
|
||||||
|
let dir = entry?;
|
||||||
|
let path = dir.path();
|
||||||
|
let c: Vec<&str> = path.to_str().unwrap().split("/").collect();
|
||||||
|
let d: Vec<_> = c[c.len() - 1].chars().collect();
|
||||||
|
let e: String = d[4..d.len() - 4].iter().collect();
|
||||||
|
let img_id: i32 = e.parse()?;
|
||||||
|
//println!("c: {c:?}");
|
||||||
|
//let a: Vec<_> = path.to_str().unwrap().to_string().chars().collect();
|
||||||
|
//let b: String = a[27..(a.len() - 4)].iter().collect();
|
||||||
|
//let img_id: i32 = b.parse()?;
|
||||||
|
let path = format!("{path:?}");
|
||||||
|
let path = path[1..(path.len() - 1)].to_owned();
|
||||||
|
let img: Mat = imread(&find_file(&path, false, false)?, IMREAD_COLOR)?;
|
||||||
|
// highgui::imshow(&path, &img)?;
|
||||||
|
imgs.push((img_id, img));
|
||||||
|
}
|
||||||
|
|
||||||
|
imgs.sort_by(|v1, v2| {
|
||||||
|
if v1.0 > v2.0 {
|
||||||
|
std::cmp::Ordering::Greater
|
||||||
|
} else if v1.0 == v2.0 {
|
||||||
|
std::cmp::Ordering::Equal
|
||||||
|
} else {
|
||||||
|
std::cmp::Ordering::Less
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//println!("Youpi");
|
||||||
|
|
||||||
|
for (i, m) in imgs.iter().enumerate() {
|
||||||
|
self.img.push(m.1.clone());
|
||||||
|
//highgui::imshow(format!("img: {i}").as_str(), &m.1)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
//loop {}
|
||||||
|
|
||||||
|
//prointln!("");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_one_border(
|
||||||
|
&self,
|
||||||
|
background: &Mat,
|
||||||
|
bord: &Mat,
|
||||||
|
id: usize,
|
||||||
|
) -> Result<((f64, f64), (f64, f64))> {
|
||||||
|
let diff: Mat = image_diff(bord, background)?;
|
||||||
|
|
||||||
|
//let (t1, s1, l1) = (
|
||||||
|
// self.tresh.min_0 as f64,
|
||||||
|
// self.tresh.min_1 as f64,
|
||||||
|
// self.tresh.min_2 as f64,
|
||||||
|
//);
|
||||||
|
//let (t2, s2, l2) = (
|
||||||
|
// self.tresh.max_0 as f64,
|
||||||
|
// self.tresh.max_1 as f64,
|
||||||
|
// self.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(&diff, &min, &max, &mut color_selected);
|
||||||
|
////highgui::imshow(format!("mask: {id}").as_str(), &color_selected)?;
|
||||||
|
//let mut bord_treshed = Mat::default();
|
||||||
|
//bitwise_and(&diff, &diff, &mut bord_treshed, &color_selected)?;
|
||||||
|
////highgui::imshow(format!("diff & mask: {id}").as_str(), &bord_treshed)?;
|
||||||
|
|
||||||
|
// Pass the image to gray
|
||||||
|
let mut diff_gray = Mat::default();
|
||||||
|
cvt_color(&diff, &mut diff_gray, COLOR_BGR2GRAY, 0)?;
|
||||||
|
//cvt_color(&bord_treshed, &mut diff_gray, COLOR_BGR2GRAY, 0)?;
|
||||||
|
|
||||||
|
// Apply Canny edge detector
|
||||||
|
let mut edges = Mat::default();
|
||||||
|
canny(
|
||||||
|
&diff_gray,
|
||||||
|
&mut edges,
|
||||||
|
self.canny_v1 as f64,
|
||||||
|
self.canny_v2 as f64,
|
||||||
|
3,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
let lines = probabilistic_hough(&edges, &self.hough_param, id)?;
|
||||||
|
//let ((x1, y1), (x2, y2)) = get_extermities(&lines, id);
|
||||||
|
Ok(get_extermities(&lines, id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_point_to_draw(
|
||||||
|
r: u8,
|
||||||
|
g: u8,
|
||||||
|
b: u8,
|
||||||
|
color: Color,
|
||||||
|
) -> (
|
||||||
|
Point,
|
||||||
|
Point,
|
||||||
|
Point,
|
||||||
|
Point,
|
||||||
|
Point,
|
||||||
|
Point,
|
||||||
|
Point,
|
||||||
|
Point,
|
||||||
|
Point,
|
||||||
|
Point,
|
||||||
|
Point,
|
||||||
|
Point,
|
||||||
|
) {
|
||||||
|
let p0 = Point {
|
||||||
|
x: 0.,
|
||||||
|
y: 0.,
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
let p1 = Point {
|
||||||
|
x: 4095.,
|
||||||
|
y: 0.,
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
let p2 = Point {
|
||||||
|
x: 4095.,
|
||||||
|
y: 4095.,
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
let p3 = Point {
|
||||||
|
x: 0.,
|
||||||
|
y: 4095.,
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
let p4 = Point {
|
||||||
|
x: 0.,
|
||||||
|
y: 1000.,
|
||||||
|
color: Color { r, g: 0, b: 0 },
|
||||||
|
};
|
||||||
|
let p5 = Point {
|
||||||
|
x: 4095.,
|
||||||
|
y: 1000.,
|
||||||
|
color: Color { r, g: 0, b: 0 },
|
||||||
|
};
|
||||||
|
let p6 = Point {
|
||||||
|
x: 0.,
|
||||||
|
y: 2000.,
|
||||||
|
color: Color { r: 0, g, b: 0 },
|
||||||
|
};
|
||||||
|
let p7 = Point {
|
||||||
|
x: 4095.,
|
||||||
|
y: 2000.,
|
||||||
|
color: Color { r: 0, g, b: 0 },
|
||||||
|
};
|
||||||
|
let p8 = Point {
|
||||||
|
x: 0.,
|
||||||
|
y: 3000.,
|
||||||
|
color: Color { r: 0, g: 0, b },
|
||||||
|
};
|
||||||
|
let p9 = Point {
|
||||||
|
x: 4095.,
|
||||||
|
y: 3000.,
|
||||||
|
color: Color { r: 0, g: 0, b },
|
||||||
|
};
|
||||||
|
|
||||||
|
let pa = Point {
|
||||||
|
x: 0.,
|
||||||
|
y: 4095.,
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
let pb = Point {
|
||||||
|
x: 4095.,
|
||||||
|
y: 4095.,
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, pa, pb)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ca c'est les donner manipuler par les slider
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct HoughLine {
|
||||||
|
pub rho: i32,
|
||||||
|
pub theta: i32,
|
||||||
|
pub treshold: i32,
|
||||||
|
pub min_length: i32,
|
||||||
|
pub max_line_gap: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ca c'est les donner qu'on envoie a la fonction
|
||||||
|
pub struct HoughLineValue {
|
||||||
|
pub rho: f64,
|
||||||
|
pub theta: f64,
|
||||||
|
pub treshold: i32,
|
||||||
|
pub min_length: f64,
|
||||||
|
pub max_line_gap: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HoughLine {
|
||||||
|
pub fn get_param(&self) -> HoughLineValue {
|
||||||
|
HoughLineValue {
|
||||||
|
rho: self.rho as f64 / 100.,
|
||||||
|
theta: self.theta as f64 / 100. * PI / 180.,
|
||||||
|
treshold: self.treshold,
|
||||||
|
min_length: self.min_length as f64 / 100.,
|
||||||
|
max_line_gap: self.max_line_gap as f64 / 100.,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Treshold {
|
||||||
|
pub win_name: String,
|
||||||
|
pub min_0: i32,
|
||||||
|
pub min_1: i32,
|
||||||
|
pub min_2: i32,
|
||||||
|
pub max_0: i32,
|
||||||
|
pub max_1: i32,
|
||||||
|
pub max_2: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Treshold {
|
||||||
|
pub fn new(name: &str, min: i32, max: i32) -> Result<Self> {
|
||||||
|
let tresh = Treshold {
|
||||||
|
win_name: name.to_owned(),
|
||||||
|
min_0: min,
|
||||||
|
min_1: min,
|
||||||
|
min_2: min,
|
||||||
|
max_0: max,
|
||||||
|
max_1: max,
|
||||||
|
max_2: max,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(tresh)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_lines(
|
||||||
|
background: &Mat,
|
||||||
|
bord: &Mat,
|
||||||
|
id: usize,
|
||||||
|
canny_v1: i32,
|
||||||
|
canny_v2: i32,
|
||||||
|
hough_param: &HoughLine,
|
||||||
|
) -> Result<Vector<VecN<i32, 4>>> {
|
||||||
|
let diff: Mat = image_diff(bord, background)?;
|
||||||
|
|
||||||
|
// Pass the image to gray
|
||||||
|
let mut diff_gray = Mat::default();
|
||||||
|
cvt_color(&diff, &mut diff_gray, COLOR_BGR2GRAY, 0)?;
|
||||||
|
// Apply Canny edge detector
|
||||||
|
let mut edges = Mat::default();
|
||||||
|
canny(
|
||||||
|
&diff_gray,
|
||||||
|
&mut edges,
|
||||||
|
canny_v1 as f64,
|
||||||
|
canny_v2 as f64,
|
||||||
|
3,
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
let lines = probabilistic_hough(&edges, hough_param, id)?;
|
||||||
|
//let ((x1, y1), (x2, y2)) = get_extermities(&lines, id);
|
||||||
|
Ok(lines)
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
|
|
||||||
use super::Param;
|
use super::Qualibration;
|
||||||
use super::DEBUG;
|
use super::DEBUG;
|
||||||
use crate::utils::Pt;
|
use crate::utils::Pt;
|
||||||
//use opencv::prelude::MatTraitConst;
|
//use opencv::prelude::MatTraitConst;
|
||||||
@ -25,10 +25,9 @@ opencv::not_opencv_branch_4! {
|
|||||||
use opencv::core::LINE_AA;
|
use opencv::core::LINE_AA;
|
||||||
}
|
}
|
||||||
|
|
||||||
use super::param::Treshold;
|
use super::Treshold;
|
||||||
const MAX_TRACKBAR: i32 = 255;
|
const MAX_TRACKBAR: i32 = 255;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn draw_histograme_dbg(
|
pub fn draw_histograme_dbg(
|
||||||
window_name: &str,
|
window_name: &str,
|
||||||
histo: &Vec<f64>,
|
histo: &Vec<f64>,
|
||||||
@ -67,7 +66,6 @@ pub fn draw_histograme_dbg(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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.);
|
||||||
let color: VecN<f64, 4> = VecN::new(255., 255., 255., 255.);
|
let color: VecN<f64, 4> = VecN::new(255., 255., 255., 255.);
|
||||||
@ -106,7 +104,6 @@ pub fn draw_histograme(window_name: &str, histo: &Vec<f64>) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn draw_histograme_bgr(window_name: &str, histo: &Vec<Vec<f64>>) -> Result<()> {
|
pub fn draw_histograme_bgr(window_name: &str, histo: &Vec<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.);
|
||||||
let b: VecN<f64, 4> = VecN::new(255., 0., 0., 255.);
|
let b: VecN<f64, 4> = VecN::new(255., 0., 0., 255.);
|
||||||
@ -199,7 +196,6 @@ pub fn draw_histograme_bgr_tresh(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// limit = 0.35 c'est bien
|
// limit = 0.35 c'est bien
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn is_same_frame(frame: &Mat, frame_prev: &Mat) -> Result<bool> {
|
pub fn is_same_frame(frame: &Mat, frame_prev: &Mat) -> Result<bool> {
|
||||||
let nb_liss: i32 = 50; // plus on lisse la courbe plus on attein la limite facilement
|
let nb_liss: i32 = 50; // plus on lisse la courbe plus on attein la limite facilement
|
||||||
let limit = 0.45; // plus c'est haut, plus on tolere de changement entre 2 image
|
let limit = 0.45; // plus c'est haut, plus on tolere de changement entre 2 image
|
||||||
@ -293,7 +289,7 @@ pub fn get_horizontal_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)),
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut segments = vec![];
|
let mut segments = vec![];
|
||||||
for (_i, iland) in segment_iland_pt.iter().enumerate() {
|
for (i, iland) in segment_iland_pt.iter().enumerate() {
|
||||||
let mut center = Pt { x: 0., y: 0. };
|
let mut center = Pt { x: 0., y: 0. };
|
||||||
for p in iland {
|
for p in iland {
|
||||||
center += *p;
|
center += *p;
|
||||||
@ -381,7 +377,7 @@ pub fn get_horizontal_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)),
|
|||||||
|
|
||||||
// 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))>> {
|
||||||
// on va faire un histogram des point selon leur position en y
|
// on va faire un histogram des point selon leur position en y
|
||||||
// ca permetera des les differencier
|
// ca permetera des les differencier
|
||||||
// on fait cette histo gramme pour connaitre ces plage de valeur en y
|
// on fait cette histo gramme pour connaitre ces plage de valeur en y
|
||||||
@ -456,7 +452,7 @@ pub fn get_vertical_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)), f3
|
|||||||
// TODO: La selection des pixel pour chaque illot pourrait etre ameliorer
|
// TODO: La selection des pixel pour chaque illot pourrait etre ameliorer
|
||||||
// En fait elle me va bien. C'est vrai que il ne sont pas ouf mais bon...
|
// En fait elle me va bien. C'est vrai que il ne sont pas ouf mais bon...
|
||||||
let mut segments = vec![];
|
let mut segments = vec![];
|
||||||
for (_i, iland) in segment_iland_pt.iter().enumerate() {
|
for (i, iland) in segment_iland_pt.iter().enumerate() {
|
||||||
let mut center = Pt { x: 0., y: 0. };
|
let mut center = Pt { x: 0., y: 0. };
|
||||||
for p in iland {
|
for p in iland {
|
||||||
center += *p;
|
center += *p;
|
||||||
@ -464,7 +460,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 = 360;
|
||||||
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 {
|
||||||
let rad = (deg as f64) / (max_deg as f64) * PI * 2.;
|
let rad = (deg as f64) / (max_deg as f64) * PI * 2.;
|
||||||
@ -476,7 +472,7 @@ 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 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 +481,7 @@ 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;
|
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,8 +492,8 @@ 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 {
|
//if err < err_min {
|
||||||
// err_min = _err;
|
// err_min = err;
|
||||||
// rad_min = rad;
|
// rad_min = rad;
|
||||||
// iland_min = tmp_iland;
|
// iland_min = tmp_iland;
|
||||||
//}
|
//}
|
||||||
@ -538,18 +534,14 @@ pub fn get_vertical_segment(m: &Mat) -> Result<Vec<(((f32, f32), (f32, f32)), f3
|
|||||||
let pt_up_2 = pt_down + (pt_up - pt_down) * 1.5;
|
let pt_up_2 = pt_down + (pt_up - pt_down) * 1.5;
|
||||||
let pt_down_2 = pt_up + (pt_down - pt_up) * 1.5;
|
let pt_down_2 = pt_up + (pt_down - pt_up) * 1.5;
|
||||||
segments.push((
|
segments.push((
|
||||||
(
|
|
||||||
(pt_down_2.x as f32, pt_down_2.y as f32),
|
(pt_down_2.x as f32, pt_down_2.y as f32),
|
||||||
(pt_up_2.x as f32, pt_up_2.y as f32),
|
(pt_up_2.x as f32, pt_up_2.y as f32),
|
||||||
),
|
|
||||||
x_min as f32,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(segments)
|
Ok(segments)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn average_pt_i32(vals: &[(i32, i32)]) -> (f32, f32) {
|
fn average_pt_i32(vals: &[(i32, i32)]) -> (f32, f32) {
|
||||||
let (mut mean_x, mut mean_y) = (0., 0.);
|
let (mut mean_x, mut mean_y) = (0., 0.);
|
||||||
let len = vals.len() as f32;
|
let len = vals.len() as f32;
|
||||||
@ -571,7 +563,6 @@ fn get_id_groups(limits: &Vec<(usize, usize)>, id: usize) -> Option<usize> {
|
|||||||
//return usize::MAX; // im lazy to have Option return...
|
//return usize::MAX; // im lazy to have Option return...
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn annalyse_segment(m: &Mat) -> Result<Vec<Vec<(i32, i32)>>> {
|
pub fn annalyse_segment(m: &Mat) -> Result<Vec<Vec<(i32, i32)>>> {
|
||||||
// on recupere les coordoner des point selectioner
|
// on recupere les coordoner des point selectioner
|
||||||
let mut seg_pt = HashSet::from([]);
|
let mut seg_pt = HashSet::from([]);
|
||||||
@ -591,7 +582,7 @@ pub fn annalyse_segment(m: &Mat) -> Result<Vec<Vec<(i32, i32)>>> {
|
|||||||
let mut selected: HashSet<(i32, i32)> = seg_pt
|
let mut selected: HashSet<(i32, i32)> = seg_pt
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(x, y)| {
|
.filter_map(|(x, y)| {
|
||||||
for (_k, (i, j)) in around_all.iter().enumerate() {
|
for (k, (i, j)) in around_all.iter().enumerate() {
|
||||||
if seg_pt.get(&(*x + i, *y + j)).is_none() {
|
if seg_pt.get(&(*x + i, *y + j)).is_none() {
|
||||||
return Some((*x, *y));
|
return Some((*x, *y));
|
||||||
}
|
}
|
||||||
@ -648,7 +639,6 @@ pub fn annalyse_segment(m: &Mat) -> Result<Vec<Vec<(i32, i32)>>> {
|
|||||||
Ok(lines)
|
Ok(lines)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn image_mean(frames: &[Mat]) -> Result<Mat> {
|
pub fn image_mean(frames: &[Mat]) -> Result<Mat> {
|
||||||
/*
|
/*
|
||||||
* Il faudrait pouvoir changer les matrice de type pour avoir des valeur plus grande
|
* Il faudrait pouvoir changer les matrice de type pour avoir des valeur plus grande
|
||||||
@ -809,8 +799,7 @@ pub fn first_invert(histo: &Vec<f64>) -> ((usize, f64), (usize, f64)) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
pub fn trackbar_init_param(mem: &mut Qualibration, winname: &str) -> Result<()> {
|
||||||
pub fn trackbar_init_param(mem: &mut Param, winname: &str) -> Result<()> {
|
|
||||||
named_window(winname, WINDOW_AUTOSIZE)?;
|
named_window(winname, WINDOW_AUTOSIZE)?;
|
||||||
highgui::move_window(winname, 20, 20)?;
|
highgui::move_window(winname, 20, 20)?;
|
||||||
let v: VecN<f64, 4> = VecN::new(0., 0., 0., 255.);
|
let v: VecN<f64, 4> = VecN::new(0., 0., 0., 255.);
|
||||||
@ -826,8 +815,7 @@ pub fn trackbar_init_param(mem: &mut Param, winname: &str) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
pub fn trackbar_line_segment(mem: &mut Qualibration, winname: &str) -> Result<()> {
|
||||||
pub fn trackbar_line_segment(mem: &mut Param, winname: &str) -> Result<()> {
|
|
||||||
//highgui
|
//highgui
|
||||||
let winname = format!("{}: {}", winname, 0); //"bord selected: 0";
|
let winname = format!("{}: {}", winname, 0); //"bord selected: 0";
|
||||||
named_window(winname.as_str(), WINDOW_AUTOSIZE)?;
|
named_window(winname.as_str(), WINDOW_AUTOSIZE)?;
|
||||||
@ -890,8 +878,7 @@ pub fn trackbar_line_segment(mem: &mut Param, winname: &str) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
pub fn line_pos(mem: &mut Qualibration, winname: &str) -> Result<()> {
|
||||||
pub fn line_pos(mem: &mut Param, winname: &str) -> Result<()> {
|
|
||||||
named_window(winname, WINDOW_AUTOSIZE)?;
|
named_window(winname, WINDOW_AUTOSIZE)?;
|
||||||
highgui::move_window(winname, 20, 20)?;
|
highgui::move_window(winname, 20, 20)?;
|
||||||
let v: VecN<f64, 4> = VecN::new(0., 0., 0., 255.);
|
let v: VecN<f64, 4> = VecN::new(0., 0., 0., 255.);
|
||||||
@ -911,7 +898,7 @@ pub fn line_pos(mem: &mut Param, winname: &str) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn adding_trackbar(mem: &mut Param, _winname: &str) -> Result<()> {
|
pub fn adding_trackbar(mut mem: &mut Qualibration, 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")?;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use super::param::HoughLine;
|
use super::HoughLine;
|
||||||
use crate::utils::{CartesianEquation, EqAffine, Pt};
|
use crate::utils::{CartesianEquation, EqAffine, Pt};
|
||||||
use opencv::core::{add, subtract, Mat, VecN, Vector, CV_8UC3};
|
use opencv::core::{add, subtract, Mat, VecN, Vector, CV_8UC3};
|
||||||
//use opencv::prelude::MatTraitConst;
|
//use opencv::prelude::MatTraitConst;
|
||||||
@ -7,7 +7,6 @@ use opencv::prelude::*; //MatTraitConst;
|
|||||||
use opencv::types::VectorOfVec4i;
|
use opencv::types::VectorOfVec4i;
|
||||||
use opencv::Result;
|
use opencv::Result;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn mix_borders(background: &Mat, borders: Vec<Mat>) -> Result<Mat> {
|
pub fn mix_borders(background: &Mat, borders: Vec<Mat>) -> Result<Mat> {
|
||||||
let (row, col) = (background.rows(), background.cols());
|
let (row, col) = (background.rows(), background.cols());
|
||||||
//let mask = Mat::default();
|
//let mask = Mat::default();
|
||||||
@ -75,9 +74,8 @@ pub fn bord_mult(pt: Vec<(f64, f64)>, factor: f64) -> Vec<(f64, f64)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// en fait ca marche pas dutout...next time
|
// en fait ca marche pas dutout...next time
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn bord_mult_v2(pt: Vec<(f64, f64)>, factor: f64) -> Vec<(f64, f64)> {
|
pub fn bord_mult_v2(pt: Vec<(f64, f64)>, factor: f64) -> Vec<(f64, f64)> {
|
||||||
let pt: Vec<Pt> = pt.iter().map(|p| Pt::from(p)).collect();
|
let mut pt: Vec<Pt> = pt.iter().map(|p| Pt::from(p)).collect();
|
||||||
|
|
||||||
let mut pn = vec![];
|
let mut pn = vec![];
|
||||||
for i in 0..pt.len() {
|
for i in 0..pt.len() {
|
||||||
@ -161,7 +159,7 @@ pub fn get_extermities(lines: &Vector<VecN<i32, 4>>, id: usize) -> ((f64, f64),
|
|||||||
pub fn probabilistic_hough(
|
pub fn probabilistic_hough(
|
||||||
edges: &Mat,
|
edges: &Mat,
|
||||||
hough_param: &HoughLine,
|
hough_param: &HoughLine,
|
||||||
_id: usize,
|
id: usize,
|
||||||
) -> Result<Vector<VecN<i32, 4>>> {
|
) -> Result<Vector<VecN<i32, 4>>> {
|
||||||
let mut p_lines = VectorOfVec4i::new();
|
let mut p_lines = VectorOfVec4i::new();
|
||||||
let mut probabalistic_hough = Mat::default();
|
let mut probabalistic_hough = Mat::default();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use super::param::Treshold;
|
use super::Treshold;
|
||||||
use opencv::core::{self, bitwise_and, in_range, Mat, Scalar, Size_};
|
use opencv::core::{self, bitwise_and, in_range, Mat, Scalar, Size_};
|
||||||
use opencv::imgproc;
|
use opencv::imgproc;
|
||||||
use opencv::Result;
|
use opencv::Result;
|
||||||
@ -31,7 +31,6 @@ pub fn image_treshold(img: &Mat, tresh: &Treshold) -> Result<Mat> {
|
|||||||
Ok(bord_treshed)
|
Ok(bord_treshed)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn image_warp_treshold(
|
pub fn image_warp_treshold(
|
||||||
img: &Mat,
|
img: &Mat,
|
||||||
homography: &Mat,
|
homography: &Mat,
|
||||||
|
@ -1,185 +0,0 @@
|
|||||||
use opencv::imgcodecs::{imread, imwrite, IMREAD_COLOR};
|
|
||||||
use opencv::{
|
|
||||||
core::{find_file, Mat, Size, Size_, Vector},
|
|
||||||
Result,
|
|
||||||
};
|
|
||||||
use std::f64::consts::PI;
|
|
||||||
use std::fs::{create_dir, read_dir};
|
|
||||||
use std::time::Instant;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct Param {
|
|
||||||
pub seq_id: usize,
|
|
||||||
pub imgs: Vec<Vec<Mat>>,
|
|
||||||
pub dst_size: i32,
|
|
||||||
pub r: i32,
|
|
||||||
pub g: i32,
|
|
||||||
pub b: i32,
|
|
||||||
pub nb_all: i32,
|
|
||||||
pub nb_visible: i32,
|
|
||||||
pub nb_wait: i32,
|
|
||||||
pub nb_liss: i32,
|
|
||||||
pub tresh: Treshold,
|
|
||||||
pub canny_v1: i32,
|
|
||||||
pub canny_v2: i32,
|
|
||||||
pub hough_param: HoughLine,
|
|
||||||
pub border_pt: Vec<(f64, f64)>,
|
|
||||||
pub homography: Mat,
|
|
||||||
pub h_size: Size_<i32>,
|
|
||||||
pub line_pos: Vec<i32>,
|
|
||||||
pub multiple: u16, // le nombre de fois qu'une photo est prise pour certaine sequence
|
|
||||||
pub key: i32,
|
|
||||||
pub dir_name: String,
|
|
||||||
pub begin: Instant,
|
|
||||||
pub capture_mode: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Param {
|
|
||||||
pub fn new(dir_name: String) -> Result<Self> {
|
|
||||||
Ok(Self {
|
|
||||||
begin: std::time::Instant::now(),
|
|
||||||
capture_mode: dir_name.len() == 0,
|
|
||||||
dir_name,
|
|
||||||
key: -1,
|
|
||||||
imgs: vec![vec![]],
|
|
||||||
seq_id: 0,
|
|
||||||
dst_size: 900,
|
|
||||||
r: 150,
|
|
||||||
g: 0,
|
|
||||||
b: 0,
|
|
||||||
nb_all: 120,
|
|
||||||
nb_visible: 40,
|
|
||||||
nb_liss: 10,
|
|
||||||
nb_wait: 30,
|
|
||||||
tresh: Treshold::new("histogram", 160, 255)?,
|
|
||||||
canny_v1: 170,
|
|
||||||
canny_v2: 255,
|
|
||||||
hough_param: HoughLine {
|
|
||||||
rho: 100,
|
|
||||||
theta: 100,
|
|
||||||
treshold: 30,
|
|
||||||
min_length: 0,
|
|
||||||
max_line_gap: 50000,
|
|
||||||
},
|
|
||||||
border_pt: vec![],
|
|
||||||
homography: Mat::default(),
|
|
||||||
h_size: Size::default(),
|
|
||||||
line_pos: vec![4095; 34],
|
|
||||||
multiple: 20,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn save_image(&self) -> Result<()> {
|
|
||||||
let now = self.begin;
|
|
||||||
let img_root = format!("image");
|
|
||||||
create_dir(&img_root).unwrap_or(());
|
|
||||||
let new_dir = format!(
|
|
||||||
"{img_root}/{:0>6?}_{:0>9?}",
|
|
||||||
now.elapsed().as_millis(),
|
|
||||||
now.elapsed().as_nanos()
|
|
||||||
);
|
|
||||||
create_dir(&new_dir).unwrap_or(());
|
|
||||||
for (i, img_seq) in self.imgs.iter().enumerate() {
|
|
||||||
let seq_dir_name = format!("{new_dir}/{i}");
|
|
||||||
create_dir(&seq_dir_name).unwrap_or(());
|
|
||||||
for img in img_seq {
|
|
||||||
let mut name_img = format!("{seq_dir_name}/");
|
|
||||||
name_img.push_str(&format!("img_{i}.png"));
|
|
||||||
imwrite(&name_img, img, &Vector::from_slice(&[6, 6, 6, 0]))?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_image(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let mut imgs = vec![];
|
|
||||||
let paths = read_dir(&self.dir_name)?;
|
|
||||||
for entry in paths {
|
|
||||||
let mut seq_img = vec![];
|
|
||||||
let dir = entry?;
|
|
||||||
let path = dir.path(); // sequence directory
|
|
||||||
let names: Vec<&str> = path.to_str().unwrap().split("/").collect();
|
|
||||||
let seq_id: usize = names[names.len() - 1].parse()?;
|
|
||||||
for entry in read_dir(&path)? {
|
|
||||||
let sub_path = entry?.path();
|
|
||||||
let names: Vec<&str> = path.to_str().unwrap().split("/").collect();
|
|
||||||
let img_name = names[names.len() - 1];
|
|
||||||
let img_id: usize = img_name[4..img_name.len() - 4].parse()?;
|
|
||||||
let img: Mat = imread(
|
|
||||||
&find_file(&sub_path.to_str().unwrap(), false, false)?,
|
|
||||||
IMREAD_COLOR,
|
|
||||||
)?;
|
|
||||||
seq_img.push((img_id, img));
|
|
||||||
}
|
|
||||||
imgs.push((seq_id, seq_img));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.imgs = vec![vec![]; imgs.len()];
|
|
||||||
for (seq_id, seq_img) in imgs {
|
|
||||||
self.imgs[seq_id] = vec![Mat::default(); seq_img.len()];
|
|
||||||
for (img_id, img) in seq_img {
|
|
||||||
self.imgs[seq_id][img_id] = img;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct HoughLine {
|
|
||||||
pub rho: i32,
|
|
||||||
pub theta: i32,
|
|
||||||
pub treshold: i32,
|
|
||||||
pub min_length: i32,
|
|
||||||
pub max_line_gap: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
// ca c'est les donner qu'on envoie a la fonction
|
|
||||||
pub struct HoughLineValue {
|
|
||||||
pub rho: f64,
|
|
||||||
pub theta: f64,
|
|
||||||
pub treshold: i32,
|
|
||||||
pub min_length: f64,
|
|
||||||
pub max_line_gap: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HoughLine {
|
|
||||||
pub fn get_param(&self) -> HoughLineValue {
|
|
||||||
HoughLineValue {
|
|
||||||
rho: self.rho as f64 / 100.,
|
|
||||||
theta: self.theta as f64 / 100. * PI / 180.,
|
|
||||||
treshold: self.treshold,
|
|
||||||
min_length: self.min_length as f64 / 100.,
|
|
||||||
max_line_gap: self.max_line_gap as f64 / 100.,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct Treshold {
|
|
||||||
pub win_name: String,
|
|
||||||
pub min_0: i32,
|
|
||||||
pub min_1: i32,
|
|
||||||
pub min_2: i32,
|
|
||||||
pub max_0: i32,
|
|
||||||
pub max_1: i32,
|
|
||||||
pub max_2: i32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Treshold {
|
|
||||||
pub fn new(name: &str, min: i32, max: i32) -> Result<Self> {
|
|
||||||
let tresh = Treshold {
|
|
||||||
win_name: name.to_owned(),
|
|
||||||
min_0: min,
|
|
||||||
min_1: min,
|
|
||||||
min_2: min,
|
|
||||||
max_0: max,
|
|
||||||
max_1: max,
|
|
||||||
max_2: max,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(tresh)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
use super::Param;
|
|
||||||
use crate::point::Point;
|
|
||||||
|
|
||||||
mod init_border;
|
|
||||||
mod init_idcode;
|
|
||||||
mod line_dotted;
|
|
||||||
mod load_image;
|
|
||||||
mod save_image;
|
|
||||||
mod wait_space;
|
|
||||||
pub use init_border::InitBorder;
|
|
||||||
pub use init_idcode::InitIdcode;
|
|
||||||
pub use line_dotted::LineDotted;
|
|
||||||
pub use load_image::LoadImage;
|
|
||||||
pub use save_image::SaveImage;
|
|
||||||
pub use wait_space::WaitSpace;
|
|
||||||
|
|
||||||
pub trait Sequence {
|
|
||||||
fn draw(&self, mem: &Param) -> Option<Vec<Point>>;
|
|
||||||
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>>;
|
|
||||||
fn is_capture(&self) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::fmt::Debug for dyn Sequence {
|
|
||||||
fn fmt(self: &Self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
write!(f, "{self:?}")
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,212 +0,0 @@
|
|||||||
use crate::draw::draw_line;
|
|
||||||
use crate::point::{Color, Point};
|
|
||||||
use crate::qualibration::{
|
|
||||||
param::{HoughLine, Param},
|
|
||||||
Sequence,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::qualibration::annalyse::image_diff;
|
|
||||||
use crate::qualibration::borders::{
|
|
||||||
bord_mult, get_extermities, get_intersection, probabilistic_hough,
|
|
||||||
};
|
|
||||||
|
|
||||||
use opencv::{
|
|
||||||
calib3d,
|
|
||||||
core::{Mat, Point as OcvPoint, Size, VecN, Vector},
|
|
||||||
imgproc::{canny, cvt_color, COLOR_BGR2GRAY},
|
|
||||||
Result,
|
|
||||||
};
|
|
||||||
|
|
||||||
opencv::opencv_branch_4! {
|
|
||||||
#[allow(unused)]
|
|
||||||
use opencv::imgproc::LINE_AA;
|
|
||||||
}
|
|
||||||
opencv::not_opencv_branch_4! {
|
|
||||||
use opencv::core::LINE_AA;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct InitBorder {
|
|
||||||
finished: bool,
|
|
||||||
cnt: usize,
|
|
||||||
borders: [Point; 4],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InitBorder {
|
|
||||||
pub fn new(beg: Point, end: Point) -> Self {
|
|
||||||
InitBorder {
|
|
||||||
borders: [
|
|
||||||
Point {
|
|
||||||
x: beg.x,
|
|
||||||
y: beg.y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
Point {
|
|
||||||
x: end.x,
|
|
||||||
y: beg.y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
Point {
|
|
||||||
x: end.x,
|
|
||||||
y: end.y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
Point {
|
|
||||||
x: beg.x,
|
|
||||||
y: end.y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
cnt: 0,
|
|
||||||
finished: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sequence for InitBorder {
|
|
||||||
//type Obj = Self;
|
|
||||||
|
|
||||||
fn draw(&self, mem: &Param) -> Option<Vec<Point>> {
|
|
||||||
if self.cnt > self.borders.len() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
if self.cnt == self.borders.len() {
|
|
||||||
return Some(vec![]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let color = Color {
|
|
||||||
r: mem.r as u8,
|
|
||||||
g: mem.g as u8,
|
|
||||||
b: mem.b as u8,
|
|
||||||
};
|
|
||||||
let id1 = (self.cnt + 1) % self.borders.len();
|
|
||||||
let p0 = Point {
|
|
||||||
color,
|
|
||||||
..self.borders[self.cnt]
|
|
||||||
};
|
|
||||||
let p1 = Point {
|
|
||||||
color,
|
|
||||||
..self.borders[id1]
|
|
||||||
};
|
|
||||||
Some(draw_line(
|
|
||||||
&p0,
|
|
||||||
&p1,
|
|
||||||
mem.nb_all as usize,
|
|
||||||
mem.nb_visible as usize,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
if self.cnt < self.borders.len() {
|
|
||||||
self.cnt += 1;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let len = self.borders.len();
|
|
||||||
let imgs = mem.imgs[mem.seq_id].clone();
|
|
||||||
let borders: Vec<Mat> = imgs[..len].into();
|
|
||||||
let background = imgs[len].clone();
|
|
||||||
|
|
||||||
// on recupere chaqu'un des 4 bord
|
|
||||||
let mut bords_pts = vec![];
|
|
||||||
for (id, bord) in borders.iter().enumerate() {
|
|
||||||
let lines = get_lines(
|
|
||||||
&background,
|
|
||||||
&bord,
|
|
||||||
id,
|
|
||||||
mem.canny_v1,
|
|
||||||
mem.canny_v2,
|
|
||||||
&mem.hough_param,
|
|
||||||
)?;
|
|
||||||
let bord_pt = get_extermities(&lines, id);
|
|
||||||
bords_pts.push(bord_pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// on calcul le cadre
|
|
||||||
let border_pt = get_intersection(&bords_pts);
|
|
||||||
mem.border_pt = bord_mult(border_pt, 1.1);
|
|
||||||
|
|
||||||
//// on dessine le cadre
|
|
||||||
//let color: VecN<f64, 4> = VecN::new(255., 128., 0., 255.);
|
|
||||||
//let mut mixed = mix_borders(&background, borders)?;
|
|
||||||
//let b = &mem.border_pt;
|
|
||||||
//for i in 0..b.len() {
|
|
||||||
// let j = (i + 1) % mem.border_pt.len();
|
|
||||||
// let pa = VecN::from_array([b[i].0 as i32, b[i].1 as i32]);
|
|
||||||
// let pb = VecN::from_array([b[j].0 as i32, b[j].1 as i32]);
|
|
||||||
// let a = OcvPoint::from_vec2(pa);
|
|
||||||
// let b = OcvPoint::from_vec2(pb);
|
|
||||||
// line(&mut mixed, a, b, color, 1, LINE_AA, 0)?;
|
|
||||||
//}
|
|
||||||
//highgui::imshow("mixed bored", &mixed)?;
|
|
||||||
|
|
||||||
// on calcule l'homography
|
|
||||||
let size = mem.dst_size;
|
|
||||||
// ici on va requadrer la partie de la projection laser de l'image
|
|
||||||
let warped_image_size = Size::new(size, size);
|
|
||||||
let roi_corners: Vec<OcvPoint> = mem
|
|
||||||
.border_pt
|
|
||||||
.iter()
|
|
||||||
.map(|(x, y)| OcvPoint::new(*x as i32, *y as i32))
|
|
||||||
.collect();
|
|
||||||
//let dst = [(0, 0), (0, size), (size, size), (size, 0)]; // in: laser repere
|
|
||||||
let dst = [(0, size), (0, 0), (size, 0), (size, size)];
|
|
||||||
let dst_corners: Vec<OcvPoint> = dst.iter().map(|(x, y)| OcvPoint::new(*x, *y)).collect();
|
|
||||||
let roi_corners_mat = Mat::from_slice(&roi_corners[..])?;
|
|
||||||
let dst_corners_mat = Mat::from_slice(&dst_corners)?;
|
|
||||||
let h = calib3d::find_homography(
|
|
||||||
&roi_corners_mat,
|
|
||||||
&dst_corners_mat,
|
|
||||||
&mut Mat::default(),
|
|
||||||
0,
|
|
||||||
3.,
|
|
||||||
)?; //get homography
|
|
||||||
mem.homography = h.clone();
|
|
||||||
mem.h_size = warped_image_size.clone();
|
|
||||||
//let mut warped_image = Mat::default();
|
|
||||||
//imgproc::warp_perspective(
|
|
||||||
// &mixed,
|
|
||||||
// &mut warped_image,
|
|
||||||
// &h,
|
|
||||||
// warped_image_size,
|
|
||||||
// imgproc::INTER_CUBIC, // I dont see difference with INTER_CUBIC
|
|
||||||
// core::BORDER_CONSTANT,
|
|
||||||
// Scalar::default(),
|
|
||||||
//)?; // do perspective transformation
|
|
||||||
//highgui::imshow("Warped Image", &warped_image)?;
|
|
||||||
self.finished = true;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_capture(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_lines(
|
|
||||||
background: &Mat,
|
|
||||||
bord: &Mat,
|
|
||||||
id: usize,
|
|
||||||
canny_v1: i32,
|
|
||||||
canny_v2: i32,
|
|
||||||
hough_param: &HoughLine,
|
|
||||||
) -> Result<Vector<VecN<i32, 4>>> {
|
|
||||||
let diff: Mat = image_diff(bord, background)?;
|
|
||||||
|
|
||||||
// Pass the image to gray
|
|
||||||
let mut diff_gray = Mat::default();
|
|
||||||
cvt_color(&diff, &mut diff_gray, COLOR_BGR2GRAY, 0)?;
|
|
||||||
// Apply Canny edge detector
|
|
||||||
let mut edges = Mat::default();
|
|
||||||
canny(
|
|
||||||
&diff_gray,
|
|
||||||
&mut edges,
|
|
||||||
canny_v1 as f64,
|
|
||||||
canny_v2 as f64,
|
|
||||||
3,
|
|
||||||
false,
|
|
||||||
)?;
|
|
||||||
let lines = probabilistic_hough(&edges, hough_param, id)?;
|
|
||||||
//let ((x1, y1), (x2, y2)) = get_extermities(&lines, id);
|
|
||||||
Ok(lines)
|
|
||||||
}
|
|
@ -1,105 +0,0 @@
|
|||||||
use crate::{
|
|
||||||
draw::draw_line_dotted,
|
|
||||||
point::Point,
|
|
||||||
qualibration::{
|
|
||||||
annalyse::{get_horizontal_segment, image_diff},
|
|
||||||
compute_image::{image_treshold, image_warp},
|
|
||||||
param::Param,
|
|
||||||
Sequence,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
use opencv::{
|
|
||||||
core::{Point as OcvPoint, VecN},
|
|
||||||
highgui,
|
|
||||||
imgproc::line,
|
|
||||||
Result,
|
|
||||||
};
|
|
||||||
|
|
||||||
opencv::opencv_branch_4! {
|
|
||||||
use opencv::imgproc::LINE_8;
|
|
||||||
}
|
|
||||||
opencv::not_opencv_branch_4! {
|
|
||||||
use opencv::core::LINE_AA;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct InitIdcode {
|
|
||||||
finished: bool,
|
|
||||||
cnt: usize,
|
|
||||||
beg: Point,
|
|
||||||
end: Point,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InitIdcode {
|
|
||||||
pub fn new(beg: Point, end: Point) -> InitIdcode {
|
|
||||||
InitIdcode {
|
|
||||||
finished: false,
|
|
||||||
cnt: 0,
|
|
||||||
beg,
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sequence for InitIdcode {
|
|
||||||
fn draw(&self, mem: &Param) -> Option<Vec<Point>> {
|
|
||||||
if self.finished {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
if self.cnt == 0 {
|
|
||||||
return Some(vec![]);
|
|
||||||
}
|
|
||||||
let mut pl = vec![];
|
|
||||||
pl.extend(draw_line_dotted(
|
|
||||||
&self.beg,
|
|
||||||
&self.end,
|
|
||||||
mem.nb_all as usize,
|
|
||||||
mem.nb_visible as usize,
|
|
||||||
true,
|
|
||||||
));
|
|
||||||
Some(pl)
|
|
||||||
}
|
|
||||||
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
if self.cnt == 0 {
|
|
||||||
self.cnt += 1;
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
let id = mem.seq_id;
|
|
||||||
let mut id_code_1 = image_diff(&mem.imgs[id][1], &mem.imgs[id][0])?;
|
|
||||||
|
|
||||||
id_code_1 = image_warp(&id_code_1, &mem.homography, mem.h_size)?;
|
|
||||||
id_code_1 = image_treshold(&id_code_1, &mem.tresh)?;
|
|
||||||
|
|
||||||
let code_seg_1 = get_horizontal_segment(&id_code_1)?;
|
|
||||||
let code_seg_1 = code_seg_1[1..(code_seg_1.len() - 1)].to_owned();
|
|
||||||
|
|
||||||
// on dessine
|
|
||||||
let color_1: VecN<f64, 4> = VecN::new(255., 0., 0., 255.);
|
|
||||||
for i in 0..code_seg_1.len() {
|
|
||||||
let (((x0, y0), (x1, y1)), size) = code_seg_1[i];
|
|
||||||
//line(&mut id_code_1, );
|
|
||||||
let s = size as i32;
|
|
||||||
let x = ((x0 + x1) / 2.) as i32;
|
|
||||||
let y = ((y0 + y1) / 2.) as i32;
|
|
||||||
let a = OcvPoint::from_vec2(VecN::from_array([x, y - s]));
|
|
||||||
let b = OcvPoint::from_vec2(VecN::from_array([x, y + s]));
|
|
||||||
line(&mut id_code_1, a, b, color_1, 1, LINE_8, 0)?;
|
|
||||||
if i < (code_seg_1.len() - 1) {
|
|
||||||
let (((x2, _), _), _) = code_seg_1[i + 1];
|
|
||||||
let x = ((x1 + x2) / 2.) as i32;
|
|
||||||
let y = ((y0 + y1) / 2.) as i32;
|
|
||||||
let a = OcvPoint::from_vec2(VecN::from_array([x, y - s]));
|
|
||||||
let b = OcvPoint::from_vec2(VecN::from_array([x, y + s]));
|
|
||||||
line(&mut id_code_1, a, b, color_1, 1, LINE_8, 0)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
highgui::imshow("code 1", &id_code_1)?;
|
|
||||||
self.finished = true;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn is_capture(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,167 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
use super::{super::Param, Sequence};
|
|
||||||
use crate::point::Point;
|
|
||||||
use opencv::Result;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct LoadImage {
|
|
||||||
finished: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LoadImage {
|
|
||||||
pub fn new() -> LoadImage {
|
|
||||||
LoadImage { finished: false }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sequence for LoadImage {
|
|
||||||
fn draw(&self, _mem: &Param) -> Option<Vec<Point>> {
|
|
||||||
if self.finished {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Some(vec![])
|
|
||||||
}
|
|
||||||
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
if !mem.capture_mode {
|
|
||||||
mem.load_image()?;
|
|
||||||
}
|
|
||||||
self.finished = true;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn is_capture(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
use super::{super::Param, Sequence};
|
|
||||||
use crate::point::Point;
|
|
||||||
use opencv::Result;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct SaveImage {
|
|
||||||
finished: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SaveImage {
|
|
||||||
pub fn new() -> SaveImage {
|
|
||||||
SaveImage { finished: false }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sequence for SaveImage {
|
|
||||||
fn draw(&self, _mem: &Param) -> Option<Vec<Point>> {
|
|
||||||
if self.finished {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Some(vec![])
|
|
||||||
}
|
|
||||||
fn compute_sequence(&mut self, mem: &mut Param) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
mem.save_image()?;
|
|
||||||
self.finished = true;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn is_capture(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,176 +0,0 @@
|
|||||||
use super::{super::Param, Sequence};
|
|
||||||
use crate::{
|
|
||||||
draw::{draw_line, draw_line_dotted},
|
|
||||||
point::{Color, Point},
|
|
||||||
};
|
|
||||||
|
|
||||||
use opencv::Result;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct WaitSpace {
|
|
||||||
borders: [Point; 4],
|
|
||||||
red: [Point; 2],
|
|
||||||
green: [Point; 2],
|
|
||||||
blue: [Point; 2],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WaitSpace {
|
|
||||||
pub fn new(beg: Point, end: Point) -> Self {
|
|
||||||
let red_y = (end.y - beg.y) * 1./5. + beg.y;
|
|
||||||
let green_y = (end.y - beg.y) * 2./5. + beg.y;
|
|
||||||
let blue_y = (end.y - beg.y) * 3./5. + beg.y;
|
|
||||||
Self {
|
|
||||||
borders: [
|
|
||||||
Point {
|
|
||||||
x: beg.x,
|
|
||||||
y: beg.y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
Point {
|
|
||||||
x: end.x,
|
|
||||||
y: beg.y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
Point {
|
|
||||||
x: end.x,
|
|
||||||
y: end.y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
Point {
|
|
||||||
x: beg.x,
|
|
||||||
y: end.y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
red: [
|
|
||||||
Point {
|
|
||||||
x: beg.x,
|
|
||||||
y: red_y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
Point {
|
|
||||||
x: end.x,
|
|
||||||
y: red_y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
blue: [
|
|
||||||
Point {
|
|
||||||
x: beg.x,
|
|
||||||
y: blue_y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
Point {
|
|
||||||
x: end.x,
|
|
||||||
y: blue_y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
green: [
|
|
||||||
Point {
|
|
||||||
x: beg.x,
|
|
||||||
y: green_y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
Point {
|
|
||||||
x: end.x,
|
|
||||||
y: green_y,
|
|
||||||
color: end.color,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sequence for WaitSpace {
|
|
||||||
fn draw(&self, mem: &Param) -> Option<Vec<Point>> {
|
|
||||||
if mem.key == 32 || !mem.capture_mode {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut pl = vec![];
|
|
||||||
let color = Color {
|
|
||||||
r: mem.r as u8,
|
|
||||||
g: mem.g as u8,
|
|
||||||
b: mem.b as u8,
|
|
||||||
};
|
|
||||||
let red = Color {
|
|
||||||
r: mem.r as u8,
|
|
||||||
g: 0,
|
|
||||||
b: 0,
|
|
||||||
};
|
|
||||||
let green = Color {
|
|
||||||
r: 0,
|
|
||||||
g: mem.g as u8,
|
|
||||||
b: 0,
|
|
||||||
};
|
|
||||||
let blue = Color {
|
|
||||||
r: 0,
|
|
||||||
g: 0,
|
|
||||||
b: mem.b as u8,
|
|
||||||
};
|
|
||||||
for i in 0..self.borders.len() {
|
|
||||||
let id1 = (i + 1) % self.borders.len();
|
|
||||||
let p0 = Point {
|
|
||||||
color,
|
|
||||||
..self.borders[i]
|
|
||||||
};
|
|
||||||
let p1 = Point {
|
|
||||||
color,
|
|
||||||
..self.borders[id1]
|
|
||||||
};
|
|
||||||
pl.extend(draw_line(
|
|
||||||
&p0,
|
|
||||||
&p1,
|
|
||||||
mem.nb_all as usize,
|
|
||||||
mem.nb_visible as usize,
|
|
||||||
));
|
|
||||||
pl.extend(draw_line_dotted(
|
|
||||||
&Point{
|
|
||||||
color: blue,
|
|
||||||
..self.blue[0]
|
|
||||||
},
|
|
||||||
&Point{
|
|
||||||
color: blue,
|
|
||||||
..self.blue[1]
|
|
||||||
},
|
|
||||||
mem.nb_all as usize,
|
|
||||||
mem.nb_visible as usize,
|
|
||||||
true,
|
|
||||||
));
|
|
||||||
pl.extend(draw_line_dotted(
|
|
||||||
&Point{
|
|
||||||
color: green,
|
|
||||||
..self.green[0]
|
|
||||||
},
|
|
||||||
&Point{
|
|
||||||
color: green,
|
|
||||||
..self.green[1]
|
|
||||||
},
|
|
||||||
mem.nb_all as usize,
|
|
||||||
mem.nb_visible as usize,
|
|
||||||
true,
|
|
||||||
));
|
|
||||||
pl.extend(draw_line_dotted(
|
|
||||||
&Point{
|
|
||||||
color: red,
|
|
||||||
..self.red[0]
|
|
||||||
},
|
|
||||||
&Point{
|
|
||||||
color: red,
|
|
||||||
..self.red[1]
|
|
||||||
},
|
|
||||||
mem.nb_all as usize,
|
|
||||||
mem.nb_visible as usize,
|
|
||||||
true,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Some(pl)
|
|
||||||
}
|
|
||||||
fn compute_sequence(&mut self, _mem: &mut Param) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn is_capture(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,13 @@
|
|||||||
use crate::point::Point;
|
use crate::point::Point;
|
||||||
static NEAR_ZERO: f64 = 0.000001;
|
static NEAR_ZERO: f64 = 0.000001;
|
||||||
|
|
||||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub};
|
use std::ops::Add;
|
||||||
|
use std::ops::AddAssign;
|
||||||
|
use std::ops::Div;
|
||||||
|
use std::ops::DivAssign;
|
||||||
|
use std::ops::Mul;
|
||||||
|
use std::ops::MulAssign;
|
||||||
|
use std::ops::Sub;
|
||||||
//use std::ops::BitXor
|
//use std::ops::BitXor
|
||||||
|
|
||||||
impl Add for Pt {
|
impl Add for Pt {
|
||||||
|
Loading…
Reference in New Issue
Block a user