Ocean
FrameFilterDilation.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_CV_FRAME_FILTER_DILATION_H
9 #define META_OCEAN_CV_FRAME_FILTER_DILATION_H
10 
11 #include "ocean/cv/CV.h"
14 
15 #include "ocean/base/Frame.h"
16 #include "ocean/base/Worker.h"
17 
18 namespace Ocean
19 {
20 
21 namespace CV
22 {
23 
24 /**
25  * This class implements a frame dilation filter.
26  * @ingroup cv
27  */
28 class OCEAN_CV_EXPORT FrameFilterDilation : public FrameFilterMorphology
29 {
30  public:
31 
32  /**
33  * Applies several dilation filter iterations for an 8 bit mask image.
34  * The value of a mask pixel (to be dilated) can be defined, every other pixel value is interpreted as a non-mask pixels.
35  * @param mask The mask frame to be filtered, must be valid
36  * @param width The width of the mask frame in pixel, with range [4, infinity)
37  * @param height The height of the mask frame in pixel, with range [4, infinity)
38  * @param iterations Number of iterations to be applied, best performance when number of iterations is even, with range [1, infinity)
39  * @param maskValue The value of a mask pixel to be dilated, pixels with other values will be untouched, with range [0, 255]
40  * @param maskPaddingElements Optional number of padding elements at the end of each mask row, in elements, with range [0, infinity)
41  * @param worker Optional worker object to distribute the computation
42  * @tparam tDilationFilter The type of the dilation filter to be applied
43  * @see filter1Channel8Bit4Neighbor(), filter1Channel8Bit8Neighbor().
44  */
45  template <MorphologyFilter tDilationFilter>
46  static void filter1Channel8Bit(uint8_t* mask, const unsigned int width, const unsigned int height, const unsigned int iterations, const uint8_t maskValue = 0x00, const unsigned int maskPaddingElements = 0u, Worker* worker = nullptr);
47 
48  /**
49  * Applies one dilation filter iteration for an 8 bit mask image using a 4-neighborhood.
50  * The value of a mask pixel (to be dilated) can be defined, every other pixel value is interpreted as a non-mask pixels.
51  * @param mask The mask frame to be filtered, must be valid
52  * @param target The target frame receiving the filter response, must be valid
53  * @param width The width of the mask frame in pixel, with range [2, infinity)
54  * @param height The height of the mask frame in pixel, with range [2, infinity)
55  * @param maskValue The value of a mask pixel to be dilated, pixels with other values will be untouched, with range [0, 255]
56  * @param maskPaddingElements Optional number of padding elements at the end of each mask row, in elements, with range [0, infinity)
57  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
58  * @param worker Optional worker object to distribute the computation
59  */
60  static inline void filter1Channel8Bit4Neighbor(const uint8_t* mask, uint8_t* target, const unsigned int width, const unsigned int height, const uint8_t maskValue = 0x00, const unsigned int maskPaddingElements = 0u, const unsigned int targetPaddingElements = 0u, Worker* worker = nullptr);
61 
62  /**
63  * Applies one dilation filter iteration for an 8 bit mask image using a 8-neighborhood, a 3x3 square kernel.
64  * The value of a mask pixel (to be dilated) can be defined, every other pixel value is interpreted as a non-mask pixels.
65  * @param mask The mask frame to be filtered, must be valid
66  * @param target The target frame receiving the filter response, must be valid
67  * @param width The width of the mask frame in pixel, with range [2, infinity)
68  * @param height The height of the mask frame in pixel, with range [2, infinity)
69  * @param maskValue The value of a mask pixel to be dilated, pixels with other values will be untouched, with range [0, 255]
70  * @param maskPaddingElements Optional number of padding elements at the end of each mask row, in elements, with range [0, infinity)
71  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
72  * @param worker Optional worker object to distribute the computation
73  */
74  static inline void filter1Channel8Bit8Neighbor(const uint8_t* mask, uint8_t* target, const unsigned int width, const unsigned int height, const uint8_t maskValue = 0x00, const unsigned int maskPaddingElements = 0u, const unsigned int targetPaddingElements = 0u, Worker* worker = nullptr);
75 
76  /**
77  * Applies one dilation filter iteration for an 8 bit mask image using a 24-neighborhood, a 5x5 square kernel.
78  * The value of a mask pixel (to be dilated) can be defined, every other pixel value is interpreted as a non-mask pixels.
79  * @param mask The mask frame to be filtered, must be valid
80  * @param target The target frame receiving the filter response, must be valid
81  * @param width The width of the mask frame in pixel, with range [4, infinity)
82  * @param height The height of the mask frame in pixel, with range [4, infinity)
83  * @param maskValue The value of a mask pixel to be dilated, pixels with other values will be untouched, with range [0, 255]
84  * @param maskPaddingElements Optional number of padding elements at the end of each mask row, in elements, with range [0, infinity)
85  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
86  * @param worker Optional worker object to distribute the computation
87  */
88  static inline void filter1Channel8Bit24Neighbor(const uint8_t* mask, uint8_t* target, const unsigned int width, const unsigned int height, const uint8_t maskValue = 0x00, const unsigned int maskPaddingElements = 0u, const unsigned int targetPaddingElements = 0u, Worker* worker = nullptr);
89 
90  private:
91 
92  /**
93  * Applies one dilation filter iteration in a subset of an 8 bit mask image using a 4-neighborhood.
94  * @param mask The mask frame to be filtered, must be valid
95  * @param target The target frame receiving the filter response, must be valid
96  * @param width The width of the mask frame in pixel, with range [2, infinity)
97  * @param height The height of the mask frame in pixel, with range [2, infinity)
98  * @param maskValue The value of a mask pixel to be eroded, pixels with other values will be untouched, with range [0, 255]
99  * @param maskPaddingElements Optional number of padding elements at the end of each mask row, in elements, with range [0, infinity)
100  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
101  * @param firstRow First row to be handled, with range [0, height - 1]
102  * @param numberRows Number of rows to be handled, with range [1, height - firstRow]
103  */
104  static void filter1Channel8Bit4NeighborSubset(const uint8_t* mask, uint8_t* target, const unsigned int width, const unsigned int height, const uint8_t maskValue, const unsigned int maskPaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows);
105 
106  /**
107  * Applies one dilation filter iteration in a subset of an 8 bit mask image using a 8-neighborhood.
108  * @param mask The mask frame to be filtered, must be valid
109  * @param target The target frame receiving the filter response, must be valid
110  * @param width The width of the mask frame in pixel, with range [2, infinity)
111  * @param height The height of the mask frame in pixel, with range [2, infinity)
112  * @param maskValue The value of a mask pixel to be eroded, pixels with other values will be untouched, with range [0, 255]
113  * @param maskPaddingElements Optional number of padding elements at the end of each mask row, in elements, with range [0, infinity)
114  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
115  * @param firstRow First row to be handled, with range [0, height - 1]
116  * @param numberRows Number of rows to be handled, with range [1, height - firstRow]
117  */
118  static void filter1Channel8Bit8NeighborSubset(const uint8_t* mask, uint8_t* target, const unsigned int width, const unsigned int height, const uint8_t maskValue, const unsigned int maskPaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows);
119 
120  /**
121  * Applies one dilation filter iteration in a subset of an 8 bit mask image using a 24-neighborhood.
122  * @param mask The mask frame to be filtered, must be valid
123  * @param target The target frame receiving the filter response, must be valid
124  * @param width The width of the mask frame in pixel, with range [4, infinity)
125  * @param height The height of the mask frame in pixel, with range [4, infinity)
126  * @param maskValue The value of a mask pixel to be eroded, pixels with other values will be untouched, with range [0, 255]
127  * @param maskPaddingElements Optional number of padding elements at the end of each mask row, in elements, with range [0, infinity)
128  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
129  * @param firstRow First row to be handled, with range [0, height - 1]
130  * @param numberRows Number of rows to be handled, with range [1, height - firstRow]
131  */
132  static void filter1Channel8Bit24NeighborSubset(const uint8_t* mask, uint8_t* target, const unsigned int width, const unsigned int height, const uint8_t maskValue, const unsigned int maskPaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows);
133 
134  /**
135  * Returns whether each several pixels in a row is not equal to a specified value.
136  * @param maskPixels The first pixel within the row to check, must be valid
137  * @param maskValue The mask value to check, with range [0, 255]
138  * @return True, if so
139  * @tparam tSize The number of pixels in a row to check, with range [1, infinity)
140  */
141  template <unsigned int tSize>
142  static OCEAN_FORCE_INLINE bool eachPixelNotEqual(const uint8_t* const maskPixels, const uint8_t maskValue);
143 };
144 
145 template <FrameFilterDilation::MorphologyFilter tDilationFilter>
146 void FrameFilterDilation::filter1Channel8Bit(uint8_t* mask, const unsigned int width, const unsigned int height, const unsigned int iterations, const uint8_t maskValue, const unsigned int maskPaddingElements, Worker* worker)
147 {
148  ocean_assert(mask != nullptr);
149  ocean_assert(width >= 2u && height >= 2u);
150  ocean_assert(iterations >= 1u);
151 
152  Frame intermediateTarget(FrameType(width, height, FrameType::FORMAT_Y8, FrameType::ORIGIN_UPPER_LEFT));
153 
154  switch (tDilationFilter)
155  {
156  case MF_CROSS_3:
157  {
158  for (unsigned int n = 0u; n < iterations / 2u; ++n)
159  {
160  filter1Channel8Bit4Neighbor(mask, intermediateTarget.data<uint8_t>(), width, height, maskValue, maskPaddingElements, intermediateTarget.paddingElements(), worker);
161  filter1Channel8Bit4Neighbor(intermediateTarget.constdata<uint8_t>(), mask, width, height, maskValue, intermediateTarget.paddingElements(), maskPaddingElements, worker);
162  }
163 
164  if (iterations % 2u == 1u)
165  {
166  filter1Channel8Bit4Neighbor(mask, intermediateTarget.data<uint8_t>(), width, height, maskValue, maskPaddingElements, intermediateTarget.paddingElements(), worker);
167  }
168 
169  break;
170  }
171 
172  case MF_SQUARE_3:
173  {
174  for (unsigned int n = 0u; n < iterations / 2u; ++n)
175  {
176  filter1Channel8Bit8Neighbor(mask, intermediateTarget.data<uint8_t>(), width, height, maskValue, maskPaddingElements, intermediateTarget.paddingElements(), worker);
177  filter1Channel8Bit8Neighbor(intermediateTarget.constdata<uint8_t>(), mask, width, height, maskValue, intermediateTarget.paddingElements(), maskPaddingElements, worker);
178  }
179 
180  if (iterations % 2u == 1u)
181  {
182  filter1Channel8Bit8Neighbor(mask, intermediateTarget.data<uint8_t>(), width, height, maskValue, maskPaddingElements, intermediateTarget.paddingElements(), worker);
183  }
184 
185  break;
186  }
187 
188  case MF_SQUARE_5:
189  {
190  for (unsigned int n = 0u; n < iterations / 2u; ++n)
191  {
192  filter1Channel8Bit24Neighbor(mask, intermediateTarget.data<uint8_t>(), width, height, maskValue, maskPaddingElements, intermediateTarget.paddingElements(), worker);
193  filter1Channel8Bit24Neighbor(intermediateTarget.constdata<uint8_t>(), mask, width, height, maskValue, intermediateTarget.paddingElements(), maskPaddingElements, worker);
194  }
195 
196  if (iterations % 2u == 1u)
197  {
198  filter1Channel8Bit24Neighbor(mask, intermediateTarget.data<uint8_t>(), width, height, maskValue, maskPaddingElements, intermediateTarget.paddingElements(), worker);
199  }
200 
201  break;
202  }
203 
204  default:
205  ocean_assert(false && "Invalid dilation filter!");
206  }
207 
208  if (iterations % 2u == 1u)
209  {
210  CV::FrameConverter::subFrame<uint8_t>(intermediateTarget.constdata<uint8_t>(), mask, width, height, width, height, 1u, 0u, 0u, 0u, 0u, width, height, intermediateTarget.paddingElements(), maskPaddingElements);
211  }
212 }
213 
214 inline void FrameFilterDilation::filter1Channel8Bit4Neighbor(const uint8_t* mask, uint8_t* target, const unsigned int width, const unsigned int height, const uint8_t maskValue, const unsigned int maskPaddingElements, const unsigned int targetPaddingElements, Worker* worker)
215 {
216  ocean_assert(mask && target);
217  ocean_assert(width >= 2u && height >= 2u);
218 
219  if (worker)
220  {
221  worker->executeFunction(Worker::Function::createStatic(&FrameFilterDilation::filter1Channel8Bit4NeighborSubset, mask, target, width, height, maskValue, maskPaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 7u, 8u, 20u);
222  }
223  else
224  {
225  filter1Channel8Bit4NeighborSubset(mask, target, width, height, maskValue, maskPaddingElements, targetPaddingElements, 0u, height);
226  }
227 }
228 
229 inline void FrameFilterDilation::filter1Channel8Bit8Neighbor(const uint8_t* mask, uint8_t* target, const unsigned int width, const unsigned int height, const uint8_t maskValue, const unsigned int maskPaddingElements, const unsigned int targetPaddingElements, Worker* worker)
230 {
231  ocean_assert(mask && target);
232  ocean_assert(width >= 2u && height >= 2u);
233 
234  if (worker)
235  {
236  worker->executeFunction(Worker::Function::createStatic(&FrameFilterDilation::filter1Channel8Bit8NeighborSubset, mask, target, width, height, maskValue, maskPaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 7u, 8u, 20u);
237  }
238  else
239  {
240  filter1Channel8Bit8NeighborSubset(mask, target, width, height, maskValue, maskPaddingElements, targetPaddingElements, 0u, height);
241  }
242 }
243 
244 inline void FrameFilterDilation::filter1Channel8Bit24Neighbor(const uint8_t* mask, uint8_t* target, const unsigned int width, const unsigned int height, const uint8_t maskValue, const unsigned int maskPaddingElements, const unsigned int targetPaddingElements, Worker* worker)
245 {
246  ocean_assert(mask && target);
247  ocean_assert(width >= 4u && height >= 4u);
248 
249  if (worker)
250  {
251  worker->executeFunction(Worker::Function::createStatic(&FrameFilterDilation::filter1Channel8Bit24NeighborSubset, mask, target, width, height, maskValue, maskPaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 7u, 8u, 20u);
252  }
253  else
254  {
255  filter1Channel8Bit24NeighborSubset(mask, target, width, height, maskValue, maskPaddingElements, targetPaddingElements, 0u, height);
256  }
257 }
258 
259 template <>
260 OCEAN_FORCE_INLINE bool FrameFilterDilation::eachPixelNotEqual<3u>(const uint8_t* const maskPixels, const uint8_t maskValue)
261 {
262  ocean_assert(maskPixels != nullptr);
263 
264  return maskPixels[0] != maskValue && maskPixels[1] != maskValue && maskPixels[2] != maskValue;
265 }
266 
267 template <>
268 OCEAN_FORCE_INLINE bool FrameFilterDilation::eachPixelNotEqual<4u>(const uint8_t* const maskPixels, const uint8_t maskValue)
269 {
270  ocean_assert(maskPixels != nullptr);
271 
272  return maskPixels[0] != maskValue && maskPixels[1] != maskValue && maskPixels[2] != maskValue && maskPixels[3] != maskValue;
273 }
274 
275 template <>
276 OCEAN_FORCE_INLINE bool FrameFilterDilation::eachPixelNotEqual<5u>(const uint8_t* const maskPixels, const uint8_t maskValue)
277 {
278  ocean_assert(maskPixels != nullptr);
279 
280  return maskPixels[0] != maskValue && maskPixels[1] != maskValue && maskPixels[2] != maskValue && maskPixels[3] != maskValue && maskPixels[4] != maskValue;
281 }
282 
283 }
284 
285 }
286 
287 #endif // META_OCEAN_CV_FRAME_FILTER_DILATION_H
This class implements a frame dilation filter.
Definition: FrameFilterDilation.h:29
static void filter1Channel8Bit8Neighbor(const uint8_t *mask, uint8_t *target, const unsigned int width, const unsigned int height, const uint8_t maskValue=0x00, const unsigned int maskPaddingElements=0u, const unsigned int targetPaddingElements=0u, Worker *worker=nullptr)
Applies one dilation filter iteration for an 8 bit mask image using a 8-neighborhood,...
Definition: FrameFilterDilation.h:229
static void filter1Channel8Bit4NeighborSubset(const uint8_t *mask, uint8_t *target, const unsigned int width, const unsigned int height, const uint8_t maskValue, const unsigned int maskPaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
Applies one dilation filter iteration in a subset of an 8 bit mask image using a 4-neighborhood.
static void filter1Channel8Bit24NeighborSubset(const uint8_t *mask, uint8_t *target, const unsigned int width, const unsigned int height, const uint8_t maskValue, const unsigned int maskPaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
Applies one dilation filter iteration in a subset of an 8 bit mask image using a 24-neighborhood.
static void filter1Channel8Bit4Neighbor(const uint8_t *mask, uint8_t *target, const unsigned int width, const unsigned int height, const uint8_t maskValue=0x00, const unsigned int maskPaddingElements=0u, const unsigned int targetPaddingElements=0u, Worker *worker=nullptr)
Applies one dilation filter iteration for an 8 bit mask image using a 4-neighborhood.
Definition: FrameFilterDilation.h:214
static void filter1Channel8Bit(uint8_t *mask, const unsigned int width, const unsigned int height, const unsigned int iterations, const uint8_t maskValue=0x00, const unsigned int maskPaddingElements=0u, Worker *worker=nullptr)
Applies several dilation filter iterations for an 8 bit mask image.
Definition: FrameFilterDilation.h:146
static OCEAN_FORCE_INLINE bool eachPixelNotEqual(const uint8_t *const maskPixels, const uint8_t maskValue)
Returns whether each several pixels in a row is not equal to a specified value.
static void filter1Channel8Bit8NeighborSubset(const uint8_t *mask, uint8_t *target, const unsigned int width, const unsigned int height, const uint8_t maskValue, const unsigned int maskPaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
Applies one dilation filter iteration in a subset of an 8 bit mask image using a 8-neighborhood.
static void filter1Channel8Bit24Neighbor(const uint8_t *mask, uint8_t *target, const unsigned int width, const unsigned int height, const uint8_t maskValue=0x00, const unsigned int maskPaddingElements=0u, const unsigned int targetPaddingElements=0u, Worker *worker=nullptr)
Applies one dilation filter iteration for an 8 bit mask image using a 24-neighborhood,...
Definition: FrameFilterDilation.h:244
This class implements the base class for all morphology frame filter.
Definition: FrameFilterMorphology.h:26
@ MF_SQUARE_3
Square mask filter defined by one center point and 8 surrounded filter pixels with an area of 3x3.
Definition: FrameFilterMorphology.h:37
@ MF_CROSS_3
Cross mask filter defined by one center point and 4 (north, south, west, east) filter pixels with an ...
Definition: FrameFilterMorphology.h:35
@ MF_SQUARE_5
Square mask filter defined by one center point and 24 surrounded filter pixels with an area of 5x5.
Definition: FrameFilterMorphology.h:39
static Caller< void > createStatic(typename StaticFunctionPointerMaker< void, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass >::Type function)
Creates a new caller container for a static function with no function parameter.
Definition: Caller.h:2876
This class implements Ocean's image class.
Definition: Frame.h:1792
const T * constdata(const unsigned int planeIndex=0u) const
Returns a pointer to the read-only pixel data of a specific plane.
Definition: Frame.h:4168
T * data(const unsigned int planeIndex=0u)
Returns a pointer to the pixel data of a specific plane.
Definition: Frame.h:4159
unsigned int paddingElements(const unsigned int planeIndex=0u) const
Returns the optional number of padding elements at the end of each row for a specific plane.
Definition: Frame.h:4042
Definition of a frame type composed by the frame dimension, pixel format and pixel origin.
Definition: Frame.h:30
@ FORMAT_Y8
Pixel format for grayscale images with byte order Y and 8 bits per pixel.
Definition: Frame.h:594
@ ORIGIN_UPPER_LEFT
The first pixel lies in the upper left corner, the last pixel in the lower right corner.
Definition: Frame.h:1050
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
bool executeFunction(const Function &function, const unsigned int first, const unsigned int size, const unsigned int firstIndex=(unsigned int)(-1), const unsigned int sizeIndex=(unsigned int)(-1), const unsigned int minimalIterations=1u, const unsigned int threadIndex=(unsigned int)(-1))
Executes a callback function separable by two function parameters.
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15