Use proptest for kernel convolution
This commit is contained in:
1 parent
96d1af5b78
commit
a3743dd921
1 file changed
+49
-39
+49
-39
@@ -28,25 +28,23 @@ impl<const N: usize> Kernel for [[f32; N]; N] {
|
||||
x: img.extent.x - 2 * l,
|
||||
y: img.extent.y - 2 * l,
|
||||
};
|
||||
let mut result = image::Image::with_extent(extent);
|
||||
result.for_each(|x, y, p| {
|
||||
let mut result = image::Image::with_extent(extent);
|
||||
result.for_each(|x, y, p| {
|
||||
for i in 0..N {
|
||||
for j in 0..N {
|
||||
let img_x = x as usize + i;
|
||||
let img_y = y as usize + j;
|
||||
let idx = img_y * img.extent.x as usize + img_x;
|
||||
*p += img.pixels[idx] * self[j][i];
|
||||
*p += img.at(x + i, y + j) * self[j][i];
|
||||
}
|
||||
}
|
||||
*p /= mag;
|
||||
});
|
||||
result
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use proptest::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn size_of_result_img() {
|
||||
@@ -60,37 +58,49 @@ mod tests {
|
||||
assert_eq!(output.extent.y, 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_pixel_result() {
|
||||
let input = image::Image {
|
||||
extent: image::Extent { x: 3, y: 3 },
|
||||
pixels: vec![
|
||||
image::SRGB::new(0.1, 0.0, 0.0),
|
||||
image::SRGB::new(0.0, 0.2, 0.0),
|
||||
image::SRGB::new(0.0, 0.0, 0.3),
|
||||
image::SRGB::new(0.2, 0.0, 0.0),
|
||||
image::SRGB::new(0.0, 0.3, 0.0),
|
||||
image::SRGB::new(0.0, 0.0, 0.1),
|
||||
image::SRGB::new(0.3, 0.0, 0.0),
|
||||
image::SRGB::new(0.0, 0.1, 0.0),
|
||||
image::SRGB::new(0.0, 0.0, 0.2),
|
||||
],
|
||||
};
|
||||
let kernel = [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], [0.7, 0.8, 0.9]];
|
||||
let output = kernel.convolve(&input);
|
||||
assert_eq!(output.extent.x, 1);
|
||||
assert_eq!(output.extent.y, 1);
|
||||
assert_eq!(
|
||||
output.pixels[0].r,
|
||||
(0.1 * 0.1 + 0.2 * 0.4 + 0.3 * 0.7) / 4.5,
|
||||
);
|
||||
assert_eq!(
|
||||
output.pixels[0].g,
|
||||
(0.2 * 0.2 + 0.3 * 0.5 + 0.1 * 0.8) / 4.5,
|
||||
);
|
||||
assert_eq!(
|
||||
output.pixels[0].b,
|
||||
(0.3 * 0.3 + 0.1 * 0.6 + 0.2 * 0.9) / 4.5,
|
||||
);
|
||||
proptest! {
|
||||
#[test]
|
||||
fn single_pixel_result_3x3(
|
||||
p1 in 0.1f32..1.0,
|
||||
p2 in 0.0f32..1.0,
|
||||
p3 in 0.0f32..1.0,
|
||||
p4 in 0.0f32..1.0,
|
||||
p5 in 0.0f32..1.0,
|
||||
p6 in 0.0f32..1.0,
|
||||
p7 in 0.0f32..1.0,
|
||||
p8 in 0.0f32..1.0,
|
||||
p9 in 0.0f32..1.0,
|
||||
k1 in 0.0f32..1.0,
|
||||
k2 in 0.0f32..1.0,
|
||||
k3 in 0.0f32..1.0,
|
||||
k4 in 0.0f32..1.0,
|
||||
k5 in 0.0f32..1.0,
|
||||
k6 in 0.0f32..1.0,
|
||||
k7 in 0.0f32..1.0,
|
||||
k8 in 0.0f32..1.0,
|
||||
k9 in 0.0f32..1.0,
|
||||
) {
|
||||
let input = image::Image {
|
||||
extent: image::Extent { x: 5, y: 5 },
|
||||
pixels: vec![
|
||||
10.0, 10.0, 10.0, 10.0, 10.0,
|
||||
10.0, p1, p2, p3, 10.0,
|
||||
10.0, p4, p5, p6, 10.0,
|
||||
10.0, p7, p8, p9, 10.0,
|
||||
10.0, 10.0, 10.0, 10.0, 10.0,
|
||||
],
|
||||
};
|
||||
let kernel = [[k1, k2, k3], [k4, k5, k6], [k7, k8, k9]];
|
||||
let output = kernel.convolve(&input);
|
||||
prop_assert_eq!(output.extent.x, 3);
|
||||
prop_assert_eq!(output.extent.y, 3);
|
||||
|
||||
let mag = k1 + k2 + k3 + k4 + k5 + k6 + k7 + k8 + k9;
|
||||
let sum = p1 * k1 + p2 * k2 + p3 * k3
|
||||
+ p4 * k4 + p5 * k5 + p6 * k6
|
||||
+ p7 * k7 + p8 * k8 + p9 * k9;
|
||||
let exp = sum / mag;
|
||||
prop_assert!((output.at(1, 1) - exp).abs() < 1e-6);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user