52 lines
1.5 KiB
Rust
52 lines
1.5 KiB
Rust
mod common;
|
|
|
|
use ccvl::*;
|
|
|
|
fn main() -> std::process::ExitCode {
|
|
common::process_image(|mut img| {
|
|
let greyscale = img.map(|p| image::Luminance::from(p));
|
|
let edges = filter::canny(greyscale);
|
|
for line in hough::lines(10.0, edges) {
|
|
let ((x0, y0), (x1, y1)) = endpoints(line, img.extent);
|
|
draw::line(x0, y0, x1, y1, &mut img, colours::RED);
|
|
}
|
|
img
|
|
})
|
|
}
|
|
|
|
fn endpoints(
|
|
l: hough::Line,
|
|
lim: image::Extent,
|
|
) -> ((usize, usize), (usize, usize)) {
|
|
if l.theta.abs() < 1e-3 {
|
|
((l.rho as usize, 0), (l.rho as usize, lim.y - 1))
|
|
} else if l.theta - std::f32::consts::PI / 2.0 < 1e-3 {
|
|
((0, l.rho as usize), (lim.x - 1, l.rho as usize))
|
|
} else {
|
|
let w = lim.x as f32 - 1e-3;
|
|
let h = lim.y as f32 - 1e-3;
|
|
|
|
let ros = l.rho / l.theta.sin();
|
|
let roc = l.rho / l.theta.cos();
|
|
let t = l.theta.tan();
|
|
|
|
let candidates: [(f32, f32); 4] =
|
|
[(roc - h * t, h), (0.0, ros), (roc, 0.0), (w, ros - w / t)];
|
|
let res = candidates
|
|
.into_iter()
|
|
.filter(|p| in_bounds(p, lim))
|
|
.map(|(x, y)| (x as usize, y as usize))
|
|
.collect::<Vec<_>>();
|
|
if res.len() != 2 {
|
|
panic!("Unexpected number of endpoints for {:?}", l);
|
|
}
|
|
(res[0], res[1])
|
|
}
|
|
}
|
|
|
|
fn in_bounds(q: &(f32, f32), lim: image::Extent) -> bool {
|
|
let x_in = 0.0 <= q.0 && q.0 < lim.x as f32;
|
|
let y_in = 0.0 <= q.1 && q.1 < lim.y as f32;
|
|
x_in && y_in
|
|
}
|