diff --git a/examples/contours.rs b/examples/contours.rs index c97777b..ef4f52a 100644 --- a/examples/contours.rs +++ b/examples/contours.rs @@ -15,22 +15,29 @@ const INNER: image::SRGBA = image::SRGBA { a: 1.0, }; +fn draw(contour: &contour::Contour, img: &mut image::Image) { + let n = contour.vertices.len(); + for i in 0..n { + let (x0, y0) = contour.vertices[i]; + let (x1, y1) = contour.vertices[(i + 1) % n]; + let colour = match contour.kind { + contour::Kind::Outer => OUTER, + contour::Kind::Inner => INNER, + }; + draw::line(x0, y0, x1, y1, img, colour); + } +} + fn main() -> std::process::ExitCode { common::process_image(|mut img| { let greyscale = img.map(|p| image::Luminance::from(p)); - let thresholded = filter::threshold_auto(greyscale); + let thresholded = filter::threshold_auto(greyscale); + let contours = contour::find(thresholded); for contour in contours { - let n = contour.vertices.len(); - for i in 0..n { - let (x0, y0) = contour.vertices[i]; - let (x1, y1) = contour.vertices[(i + 1) % n]; - draw::line(x0, y0, x1, y1, &mut img, match contour.kind { - contour::Kind::Outer => OUTER, - contour::Kind::Inner => INNER, - }); - } + draw(&contour, &mut img); } + img }) } diff --git a/src/contour.rs b/src/contour.rs index 3895f1a..1d452b5 100644 --- a/src/contour.rs +++ b/src/contour.rs @@ -18,7 +18,8 @@ pub struct Contour { enum Pixel { Foreground, Background, - Traced(usize), + TracedUp(usize), + TracedDown(usize), } #[derive(Clone, Copy, Debug, PartialEq)] @@ -60,14 +61,14 @@ pub fn find(img: image::Image) -> Vec { let q = (x, y); if foreground(&map, q) && background(&map, q.prev_x()) { add(q, Kind::Outer, parent, &mut contours, &mut map); - } else if foreground(&map, q) && background(&map, q.next_x()) { + } else if (foreground(&map, q) || traced_up(&map, q).is_some()) + && background(&map, q.next_x()) + { add(q, Kind::Inner, parent, &mut contours, &mut map); - } else if let Some(label) = traced(&map, q) { - if background(&map, q.prev_x()) { - parent = Some(label); - } else if background(&map, q.next_x()) { - parent = contours[label].parent; - } + } else if let Some(label) = traced_up(&map, q) { + parent = Some(label); + } else if let Some(label) = traced_down(&map, q) { + parent = contours[label].parent; } } } @@ -103,7 +104,9 @@ fn trace( let mut vertices = Vec::new(); loop { - q.set(img, Pixel::Traced(label)); + if foreground(img, q) { + q.set(img, Pixel::TracedUp(label)); + } let prev_dir = dir; dir = dir.flip().next(); @@ -115,6 +118,9 @@ fn trace( } break qp; } + if dir == Dir::E { + q.set(img, Pixel::TracedDown(label)); + } dir = dir.next(); }; @@ -122,9 +128,27 @@ fn trace( if dir != start_dir { vertices.push(q); } - break vertices; + break; } } + + // println!(); + // for y in 0..img.extent.y { + // for x in 0..img.extent.x { + // if let Some(label) = traced_up(img, (x, y)) { + // print!("{:1}", label); + // } else if let Some(label) = traced_down(img, (x, y)) { + // print!("-") + // } else if foreground(img, (x, y)) { + // print!("."); + // } else if background(img, (x, y)) { + // print!(" "); + // } + // } + // println!(); + // } + + vertices } fn foreground(img: &image::Image, q: (usize, usize)) -> bool { @@ -141,9 +165,19 @@ fn background(img: &image::Image, q: (usize, usize)) -> bool { } } -fn traced(img: &image::Image, q: (usize, usize)) -> Option { +fn traced_up(img: &image::Image, q: (usize, usize)) -> Option { match q.get(img) { - Some(Pixel::Traced(label)) => Some(label), + Some(Pixel::TracedUp(label)) => Some(label), + _ => None, + } +} + +fn traced_down( + img: &image::Image, + q: (usize, usize), +) -> Option { + match q.get(img) { + Some(Pixel::TracedDown(label)) => Some(label), _ => None, } }