1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//! Image storage, views, ROIs, tiles, and neighborhood shapes.
//!
//! Start with [`Image`](crate::image::Image) when you own pixels, [`ImageRef`](crate::image::ImageRef) / [`ImageRefMut`](crate::image::ImageRefMut)
//! when you borrow existing storage, and [`ImageView`](crate::image::ImageView) when you are writing an
//! algorithm that only needs random access.
//!
//! ## Which access trait?
//!
//! | Trait | Guarantee | Reach for it when |
//! |---|---|---|
//! | [`ImageView`](crate::image::ImageView) | `pixel_at(x, y)` by value | You only need random access. |
//! | [`ImageViewMut`](crate::image::ImageViewMut) | mutable random access | You need to edit individual pixels. |
//! | [`RasterImage`](crate::image::RasterImage) | dense row slices | You scan rows or want cache-friendly loops. |
//! | [`RasterImageMut`](crate::image::RasterImageMut) | mutable row slices | You mutate rows in place. |
//! | [`ContiguousImage`](crate::image::ContiguousImage) | one dense pixel slice | You need the fastest whole-buffer path. |
//! | [`PlainImage`](crate::image::PlainImage) | byte access to `PlainPixel` storage | You write camera, file, FFI, or GPU boundaries. |
//!
//! ## Multi-image structures
//!
//! [`ImagePlanes`](crate::image::ImagePlanes) holds one plane per channel,
//! [`ImageArray`](crate::image::ImageArray) is a compile-time-sized image, and
//! [`Pyramid`](crate::image::Pyramid) chains levels at decreasing resolution
//! (built via [`PyramidMethod`](crate::transform::PyramidMethod) strategies
//! in [`crate::transform`]). Levels opt into scale metadata through the
//! [`Decimated`](crate::image::Decimated) /
//! [`ScaleLevel`](crate::image::ScaleLevel) capability traits.
//!
//! ## Views do not allocate
//!
//! [`SubView::roi`](crate::image::SubView::roi) returns a borrowed region of interest. [`SubView::tiles`](crate::image::SubView::tiles)
//! splits an image into borrowed immutable tiles. [`IntoTilesMut`](crate::image::IntoTilesMut) yields
//! disjoint mutable tiles for safe chunked in-place processing.
//!
//! Those three are gated on
//! [`OriginInvariantPixel`](crate::pixel::OriginInvariantPixel), so images of
//! [Bayer CFA samples](crate::pixel::bayer) do not have them — cropping such
//! an image at an odd origin changes what every sample means. They use
//! [`BayerSubView::aligned_bayer_roi`](crate::image::BayerSubView::aligned_bayer_roi)
//! and [`BayerSubViewMut`](crate::image::BayerSubViewMut) instead, which
//! check the 2×2 phase and return `None` rather than a mislabelled view.
//!
//! Do not use this module for pixel semantics. If the question is "is this
//! gamma-encoded?" or "can this be interpolated?", look in [`crate::pixel`].
/// Border policies for out-of-bounds neighborhood access.
pub
pub
pub use ;
pub use ;
pub use ImagePlanes;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
// ─── Binary image vocabulary ────────────────────────────────────
//
// Binary images are images whose pixel type is `bool`. `bool` rides the
// `T: Copy` pathway through `Image<T>`, `ImageView`, `ImageRef`, zip, and the
// parallel iteration machinery, and — because a boolean mask value means the
// same thing wherever it sits — it also implements
// [`OriginInvariantPixel`](crate::pixel::OriginInvariantPixel) (below), which
// is what keeps ordinary `SubView` ROI, tiling, and sliding windows available
// for binary images. `bool` is also the pixel type that
// `map_neighborhood*` already consumes as its topology mask parameter
// (`MI: ImageView<Pixel = bool>`), so morphology and neighborhood operations
// natively accept binary images with no bridging conversion.
//
// These aliases give that concept a first-class name. They are zero-cost
// documentation: every `BinaryImage` is structurally identical to the
// `Image<bool>` it aliases.
//
// Naming: `BinaryImage`, not `Mask`. The name `Mask` is already taken in
// this codebase for compile-time-sized structuring elements
// (`Mask<KW, KH> = Neighborhood<bool, KW, KH>`). Reusing `Mask` for whole
// images would be a three-way collision.
// A boolean mask value carries no coordinate phase — `true` / `false` means
// the same thing at any origin — so binary images keep ordinary
// same-pixel-type ROI, tiling, and sliding windows. The impl lives here,
// beside the `BinaryImage` aliases it exists to serve, rather than in a pixel
// family module, because `bool` is a primitive and belongs to no pixel family.
/// An image whose pixels are binary (`bool`).
///
/// Produced by strategies such as [`BinaryMask`](crate::transform::BinaryMask);
/// consumed directly by morphology operations
/// ([`erode`](crate::transform::erode), [`dilate`](crate::transform::dilate)),
/// connected-components analysis, and anything else that accepts
/// `ImageView<Pixel = bool>`.
///
/// This is a type alias for `Image<bool>`; every method, trait impl, and
/// storage guarantee of `Image<bool>` applies transparently.
///
/// # Example
/// ```
/// # use fovea::image::{BinaryImage, Image, ImageView};
/// # use fovea::pixel::Mono8;
/// # use fovea::transform::{BinaryMask, convert_image};
/// let img: Image<Mono8> = Image::fill(4, 4, Mono8::new(200));
/// let mask: BinaryImage = convert_image(&img, BinaryMask { thresh: Mono8::new(128) });
/// assert!(mask.pixel_at(0, 0));
/// ```
pub type BinaryImage = ;
/// An immutable reference to a binary image. Alias for [`ImageRef<bool>`].
pub type BinaryImageRef<'a> = ;
/// A mutable reference to a binary image. Alias for [`ImageRefMut<bool>`].
pub type BinaryImageRefMut<'a> = ;