68 lines
1.7 KiB
Rust
68 lines
1.7 KiB
Rust
use crate::*;
|
|
|
|
const THETA_N: usize = 200;
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
pub struct Line {
|
|
pub theta: f32,
|
|
pub rho: f32,
|
|
pub significance: f32,
|
|
}
|
|
|
|
pub fn transform(img: image::Image<image::Luminance>) -> image::Image<f32> {
|
|
let diag = ((img.extent.x.pow(2) + img.extent.y.pow(2)) as f32).sqrt();
|
|
let mut res = image::Image::<f32>::with_extent(image::Extent {
|
|
x: THETA_N,
|
|
y: diag as usize,
|
|
});
|
|
for y in 0..img.extent.y {
|
|
for x in 0..img.extent.x {
|
|
if img.at(x, y).y != 1.0 {
|
|
continue;
|
|
}
|
|
for a in 0..THETA_N {
|
|
let theta = theta_from(a);
|
|
let rho = x as f32 * theta.cos() + y as f32 * theta.sin();
|
|
if rho < 0.0 {
|
|
continue;
|
|
}
|
|
|
|
*res.at_mut(a, rho as usize) += 1.0;
|
|
}
|
|
}
|
|
}
|
|
res
|
|
}
|
|
|
|
pub fn lines(
|
|
min_significance: f32,
|
|
img: image::Image<image::Luminance>,
|
|
) -> Vec<Line> {
|
|
let hough = transform(img);
|
|
|
|
let mu = stats::mean((&hough.pixels).into_iter().map(|p| *p));
|
|
let sigma = stats::stddev((&hough.pixels).into_iter().map(|p| *p), mu);
|
|
|
|
let mut lines = Vec::<Line>::new();
|
|
for y in 0..hough.extent.y {
|
|
for x in 0..hough.extent.x {
|
|
let value = hough.at(x, y);
|
|
let significance = (value - mu) / sigma;
|
|
if significance >= min_significance {
|
|
let theta = theta_from(x);
|
|
let rho = y as f32;
|
|
lines.push(Line {
|
|
theta,
|
|
rho,
|
|
significance,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
lines
|
|
}
|
|
|
|
fn theta_from(x: usize) -> f32 {
|
|
x as f32 * std::f32::consts::PI / THETA_N as f32
|
|
}
|