Implement sobel filter
This commit is contained in:
1 parent
5af54f2702
commit
6258219ff2
3 files changed
+59
No files matched your search
@@ -0,0 +1,3 @@
|
||||
pub mod sobel;
|
||||
|
||||
pub use sobel::sobel;
|
||||
@@ -0,0 +1,55 @@
|
||||
use crate::image::*;
|
||||
use crate::kernel::Kernel;
|
||||
use crate::*;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct Vector {
|
||||
pub magnitude: f32,
|
||||
pub direction: f32,
|
||||
}
|
||||
|
||||
impl Default for Vector {
|
||||
fn default() -> Self {
|
||||
Vector {
|
||||
magnitude: 0.0,
|
||||
direction: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const KERNEL_X: [[f32; 3]; 3] =
|
||||
[[-1.0, 0.0, 1.0], [-2.0, 0.0, 2.0], [-1.0, 0.0, 1.0]];
|
||||
const KERNEL_Y: [[f32; 3]; 3] =
|
||||
[[-1.0, -2.0, -1.0], [0.0, 0.0, 0.0], [1.0, 2.0, 1.0]];
|
||||
|
||||
pub fn sobel(img: Image<Luminance>) -> Image<Vector> {
|
||||
let x_edges = KERNEL_X.convolve(&img);
|
||||
let y_edges = KERNEL_Y.convolve(&img);
|
||||
|
||||
let mut result = image::Image::<Vector>::with_extent(x_edges.extent);
|
||||
result.for_each(|x, y, p| {
|
||||
let gx = x_edges.at(x, y).y;
|
||||
let gy = y_edges.at(x, y).y;
|
||||
p.magnitude = norm(gx, gy);
|
||||
p.direction = gy.atan2(gx);
|
||||
});
|
||||
|
||||
normalise_magnitude(&mut result);
|
||||
result
|
||||
}
|
||||
|
||||
fn norm(x: f32, y: f32) -> f32 {
|
||||
(x * x + y * y).sqrt()
|
||||
}
|
||||
|
||||
fn normalise_magnitude(img: &mut Image<Vector>) {
|
||||
let mut max = f32::NEG_INFINITY;
|
||||
for p in &img.pixels {
|
||||
if p.magnitude > max {
|
||||
max = p.magnitude;
|
||||
}
|
||||
}
|
||||
img.for_each(|_, _, p| {
|
||||
p.magnitude /= max;
|
||||
});
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
pub mod image;
|
||||
pub mod kernel;
|
||||
pub mod filter;
|
||||
Reference in new issue
Block a user