Use proptest for kernel convolution

This commit is contained in:
cdo committed 2026-10-26 15:52:20 +00:00
1 parent 96d1af5b78
commit a3743dd921
1 file changed
+40 -30
+40 -30
View File
@@ -32,10 +32,7 @@ impl<const N: usize> Kernel for [[f32; N]; N] {
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;
@@ -47,6 +44,7 @@ impl<const N: usize> Kernel for [[f32; N]; N] {
#[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);
}
proptest! {
#[test]
fn single_pixel_result() {
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: 3, y: 3 },
extent: image::Extent { x: 5, y: 5 },
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),
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 = [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], [0.7, 0.8, 0.9]];
let kernel = [[k1, k2, k3], [k4, k5, k6], [k7, k8, k9]];
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,
);
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);
}
}
}