10 inline bool is_fg(
float v)
noexcept {
return v >= 0.5F; }
12 std::vector<float> morph_op(
13 std::span<const float> mask, uint32_t w, uint32_t
h,
14 uint32_t
radius,
bool dilating)
16 const size_t n =
static_cast<size_t>(w) *
h;
17 const auto r =
static_cast<int32_t
>(
radius);
18 std::vector<float>
out(n);
20 std::for_each(std::execution::par_unseq,
21 std::views::iota(
size_t { 0 }, n).begin(),
22 std::views::iota(
size_t { 0 }, n).end(),
24 const auto px =
static_cast<int32_t
>(idx % w);
25 const auto py =
static_cast<int32_t
>(idx / w);
27 bool result = !dilating;
29 for (int32_t dy = -r; dy <= r && result == !dilating; ++dy) {
30 const int32_t ny = std::clamp(
py + dy, 0,
static_cast<int32_t
>(
h) - 1);
31 for (int32_t dx = -r; dx <= r && result == !dilating; ++dx) {
32 const int32_t nx = std::clamp(
px + dx, 0,
static_cast<int32_t
>(w) - 1);
33 const bool fg = is_fg(mask[
static_cast<size_t>(ny) * w + nx]);
36 }
else if (!dilating && !fg) {
42 out[idx] = result ? 1.0F : 0.0F;
49 std::span<const float> mask, std::span<float>
out,
50 uint32_t w, uint32_t
h, uint32_t
radius,
bool dilating)
52 const size_t n =
static_cast<size_t>(w) *
h;
53 const auto r =
static_cast<int32_t
>(
radius);
55 std::for_each(std::execution::par_unseq,
56 std::views::iota(
size_t { 0 }, n).begin(),
57 std::views::iota(
size_t { 0 }, n).end(),
59 const auto px =
static_cast<int32_t
>(idx % w);
60 const auto py =
static_cast<int32_t
>(idx / w);
61 bool result = !dilating;
63 for (int32_t dy = -r; dy <= r && result == !dilating; ++dy) {
64 const int32_t ny = std::clamp(
py + dy, 0,
static_cast<int32_t
>(
h) - 1);
66 for (int32_t dx = -r; dx <= r && result == !dilating; ++dx) {
67 const int32_t nx = std::clamp(
px + dx, 0,
static_cast<int32_t
>(w) - 1);
68 const bool fg = is_fg(mask[
static_cast<size_t>(ny) * w + nx]);
72 }
else if (!dilating && !fg) {
77 out[idx] = result ? 1.0F : 0.0F;
83void erode(std::span<const float> mask, std::span<float>
dst,
84 uint32_t w, uint32_t
h, uint32_t
radius)
89std::vector<float>
erode(std::span<const float> mask, uint32_t w, uint32_t
h, uint32_t
radius)
91 std::vector<float>
out(
static_cast<size_t>(w) *
h);
96void dilate(std::span<const float> mask, std::span<float>
dst,
97 uint32_t w, uint32_t
h, uint32_t
radius)
102std::vector<float>
dilate(std::span<const float> mask, uint32_t w, uint32_t
h, uint32_t
radius)
104 std::vector<float>
out(
static_cast<size_t>(w) *
h);
109void open(std::span<const float> mask, std::span<float> tmp, std::span<float>
dst,
110 uint32_t w, uint32_t
h, uint32_t
radius)
116std::vector<float>
open(std::span<const float> mask, uint32_t w, uint32_t
h, uint32_t
radius)
118 std::vector<float> tmp(
static_cast<size_t>(w) *
h);
119 std::vector<float>
out(tmp.size());
124void close(std::span<const float> mask, std::span<float> tmp, std::span<float>
dst,
125 uint32_t w, uint32_t
h, uint32_t
radius)
131std::vector<float>
close(std::span<const float> mask, uint32_t w, uint32_t
h, uint32_t
radius)
133 std::vector<float> tmp(
static_cast<size_t>(w) *
h);
134 std::vector<float>
out(tmp.size());
140 uint32_t w, uint32_t
h, uint32_t
radius)
142 const auto en =
static_cast<Eigen::Index
>(
static_cast<size_t>(w) *
h);
146 Eigen::Map<Eigen::ArrayXf>(
dst.data(), en) = Eigen::Map<const Eigen::ArrayXf>(tmp.data(), en)
147 - Eigen::Map<const Eigen::ArrayXf>(
dst.data(), en);
152 std::vector<float> tmp(
static_cast<size_t>(w) *
h);
153 std::vector<float>
out(tmp.size());
std::vector< float > * out
Binary morphological operations on normalised float masks.
void erode(std::span< const float > mask, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Erosion writing into dst.
void close(std::span< const float > mask, std::span< float > tmp, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Morphological closing writing into dst.
void dilate(std::span< const float > mask, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Dilation writing into dst.
void morph_gradient(std::span< const float > mask, std::span< float > tmp, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Morphological gradient (dilate - erode) writing into dst.
void open(std::span< const float > mask, std::span< float > tmp, std::span< float > dst, uint32_t w, uint32_t h, uint32_t radius)
Morphological opening writing into dst.