Skip to content

Instantly share code, notes, and snippets.

@hauleth
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hauleth/39e74f1335c9eb04e129 to your computer and use it in GitHub Desktop.
Save hauleth/39e74f1335c9eb04e129 to your computer and use it in GitHub Desktop.
Filter application
fn clamp<N: PartialOrd>(val: N, min: N, max: N) -> N {
if val > max { max }
else if val < min { min }
else { val }
}
fn filter<P: Primitive + 'static, T: Pixel<P> + 'static, I: GenericImage<T>>(
image: &I,
kernel: &Matrix<f32>) -> ImageBuffer<Vec<P>, P, T> {
let xcenter = kernel.rows() / 2;
let ycenter = kernel.cols() / 2;
let (width, height) = image.dimensions();
let sum = match kernel.sum() {
0.0 => 1.0,
v => v
};
let sumx4 = f32x4(sum, sum, sum, sum);
let max : f32 = Primitive::max_value();
let mut out = ImageBuffer::new(width, height);
for i in (xcenter..width - xcenter) {
for j in (ycenter..height - ycenter) {
let mut sum = f32x4(0.0, 0.0, 0.0, 0.0);
for x in (0..kernel.rows()) {
for y in (0..kernel.cols()) {
let diffx = x as isize - xcenter as isize;
let diffy = y as isize - ycenter as isize;
let x0 = i as isize + diffx;
let y0 = j as isize + diffy;
let k = kernel[(x, y)];
let kx4 = f32x4(k, k, k, k);
let pixel = image.get_pixel(x0 as u32, y0 as u32);
let (c1, c2, c3, c4) = pixel.channels4();
let vec = f32x4(
cast(c1).unwrap(),
cast(c2).unwrap(),
cast(c3).unwrap(),
cast(c4).unwrap());
sum += vec * kx4;
}
}
let f32x4(s1, s2, s3, s4) = sum / sumx4;
let t: T = Pixel::from_channels(
cast(clamp(s1, 0.0, max)).unwrap(),
cast(clamp(s2, 0.0, max)).unwrap(),
cast(clamp(s3, 0.0, max)).unwrap(),
cast(clamp(s4, 0.0, max)).unwrap());
out.put_pixel(i, j, t);
}
}
out
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment