Implement gradient thresholding for Canny filter
This commit is contained in:
1 parent
6258219ff2
commit
ba0c3b4756
1 file changed
+79
@@ -0,0 +1,79 @@
|
||||
use super::*;
|
||||
|
||||
use crate::*;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
struct Step {
|
||||
x: isize,
|
||||
y: isize,
|
||||
}
|
||||
|
||||
impl Step {
|
||||
fn of(mut theta: f32) -> Self {
|
||||
theta /= std::f32::consts::PI;
|
||||
if theta < 0.0 {
|
||||
theta += 1.0;
|
||||
}
|
||||
|
||||
if theta <= 0.125 {
|
||||
Self { x: 1, y: 0 }
|
||||
} else if theta <= 0.375 {
|
||||
Self { x: 1, y: 1 }
|
||||
} else if theta <= 0.625 {
|
||||
Self { x: 0, y: 1 }
|
||||
} else if theta <= 0.875 {
|
||||
Self { x: -1, y: 1 }
|
||||
} else if theta <= 1.0 {
|
||||
Self { x: 1, y: 0 }
|
||||
} else {
|
||||
panic!("Angle out of expected range");
|
||||
}
|
||||
}
|
||||
|
||||
fn back(&self) -> Self {
|
||||
Self {
|
||||
x: -self.x,
|
||||
y: -self.y,
|
||||
}
|
||||
}
|
||||
|
||||
fn from(&self, x: usize, y: usize) -> (isize, isize) {
|
||||
(x as isize + self.x, y as isize + self.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Step {
|
||||
fn default() -> Self {
|
||||
Step { x: 0, y: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gradient_threshold(img: Image<filter::sobel::Vector>) -> Image<f32> {
|
||||
let mut result = image::Image::<f32>::with_extent(img.extent);
|
||||
result.for_each(|x, y, p| {
|
||||
let value = img.at(x, y);
|
||||
let step = Step::of(value.direction);
|
||||
|
||||
let this = value.magnitude;
|
||||
let next = get(&img, step.from(x, y))
|
||||
.map_or(f32::NEG_INFINITY, |v| v.magnitude);
|
||||
let prev = get(&img, step.back().from(x, y))
|
||||
.map_or(f32::NEG_INFINITY, |v| v.magnitude);
|
||||
if this > next && this > prev {
|
||||
*p = this;
|
||||
}
|
||||
});
|
||||
result
|
||||
}
|
||||
|
||||
fn get<T: Copy>(img: &Image<T>, pos: (isize, isize)) -> Option<T> {
|
||||
if pos.0 >= 0
|
||||
&& pos.0 < img.extent.x as isize
|
||||
&& pos.1 >= 0
|
||||
&& pos.1 < img.extent.y as isize
|
||||
{
|
||||
Some(img.at(pos.0 as usize, pos.1 as usize))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user