fn main() {
use fovea::image::{Image, ImageView, ImageViewMut};
use fovea::pixel::{Mono8, MonoF32};
use fovea::border::Clamp;
use fovea::transform::sobel_x;
let width: usize = 16;
let height: usize = 16;
let edge_col: usize = 8;
let mut img = Image::<Mono8>::zero(width, height);
for y in 0..height {
for x in edge_col..width {
*img.pixel_at_mut(x, y) = Mono8::new(200);
}
}
println!(
"Input image: {}×{} Mono8 with a vertical step edge at x={}",
img.width(),
img.height(),
edge_col,
);
assert_eq!(img.pixel_at(edge_col - 1, 0).value(), 0);
assert_eq!(img.pixel_at(edge_col, 0).value(), 200);
let edges: Image<MonoF32> = sobel_x(&img, &Clamp);
println!(
"Output image: {}×{} MonoF32 (one value per pixel)",
edges.width(),
edges.height(),
);
let sample_y: usize = height / 2;
let response_flat_left = edges.pixel_at(2, sample_y).0;
let response_at_edge = edges.pixel_at(edge_col, sample_y).0;
let response_flat_right = edges.pixel_at(14, sample_y).0;
println!("\nSobel-X responses along row y={sample_y}:");
println!(" x=2 (flat dark region): {response_flat_left:>8.1}");
println!(" x={edge_col} (step edge): {response_at_edge:>8.1}");
println!(" x=14 (flat bright region): {response_flat_right:>8.1}");
assert!(
response_at_edge.abs() > response_flat_left.abs(),
"edge response ({}) should dominate flat-left response ({})",
response_at_edge,
response_flat_left,
);
assert!(
response_at_edge.abs() > response_flat_right.abs(),
"edge response ({}) should dominate flat-right response ({})",
response_at_edge,
response_flat_right,
);
println!(
"Edge response sign: {}",
if response_at_edge > 0.0 {
"positive"
} else {
"negative"
}
);
println!("\nFull Sobel-X profile along row y={sample_y}:");
for x in 0..width {
let val = edges.pixel_at(x, sample_y).0;
let bar_len = (val.abs() / 25.0).round() as usize;
let bar: String = "#".repeat(bar_len);
let sign = if val >= 0.0 { '+' } else { '-' };
println!(" x={x:>2}: {sign}{:>7.1} {bar}", val.abs());
}
println!("\nEdge detection verified — the Sobel-X filter found the vertical edge!");
}