Ocean
Loading...
Searching...
No Matches
MaskAnalyzer.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_MASK_ANALYZER_H
9#define META_OCEAN_CV_MASK_ANALYZER_H
10
11#include "ocean/cv/CV.h"
12
13#include "ocean/base/Frame.h"
14#include "ocean/base/Worker.h"
15
17
18namespace Ocean
19{
20
21namespace CV
22{
23
24/**
25 * This class implements basic maks analyzing functions.
26 * More advanced mask analyzing functions are available in CV::Segmentation::MaskAnalyzer.
27 * @ingroup cv
28 */
29class OCEAN_CV_EXPORT MaskAnalyzer
30{
31 public:
32
33 /**
34 * Detects the smallest axis-aligned bounding box enclosing all isolated mask islands in a binary (but 8-bit) mask frame.
35 * @param mask The 8 bit mask frame in which the enclosing bounding box will be determined, must be valid
36 * @param width The width of the mask frame in pixel, with range [1, infinity)
37 * @param height The height of the mask frame in pixel, with range [1, infinity)
38 * @param nonMaskPixel The value of pixels not part of the mask, all other values will be mask pixels, with range [0, infinity)
39 * @param maskPaddingElements The number of padding elements at the end of each mask row, with range [0, infinity)
40 * @return Resulting mask bounding box, invalid if no mask could be found
41 * @see CV::Segmentation::MaskAnalyzer::detectBoundingBoxes().
42 */
43 static PixelBoundingBox detectBoundingBox(const uint8_t* mask, const unsigned int width, const unsigned int height, const uint8_t nonMaskPixel, const unsigned int maskPaddingElements);
44
45 /**
46 * Detects the smallest axis-aligned bounding box enclosing all isolated mask islands inside a given mask frame using a rough approximation of the bounding box.
47 * @param mask The 8 bit mask frame in which the bounding box will be determined, must be valid
48 * @param width The width of the mask frame in pixel, with range [1, infinity)
49 * @param height The height of the mask frame in pixel, with range [1, infinity)
50 * @param rough Rough approximation of the final bounding box, must be valid
51 * @param maxUncertainty Maximal pixel uncertainty of the rough box guess, with range [1, infinity)
52 * @param nonMaskPixel The value of pixel not part of the mask, all other values will be mask pixels, with range [0, infinity)
53 * @param maskPaddingElements The number of padding elements at the end of each mask row, with range [0, infinity)
54 * @return Resulting mask bounding box, invalid if no mask could be found
55 */
56 static PixelBoundingBox detectBoundingBox(const uint8_t* const mask, const unsigned int width, const unsigned int height, const PixelBoundingBox& rough, const unsigned int maxUncertainty, const uint8_t nonMaskPixel = 0xFFu, const unsigned int maskPaddingElements = 0u);
57
58 /**
59 * Detects the smallest bounding box enclosing all opaque pixels in a given frame.
60 * @param frame The frame in which the bounding box enclosing all opaque pixels is determined, must be valid
61 * @param width The width of the frame in pixel, with range [1, infinity)
62 * @param height The height of the frame in pixel, with range [1, infinity)
63 * @param alphaChannelIndex The index of the alpha channel, with range [0, channels)
64 * @param channels The number of frame channels, with range [1, infinity)
65 * @param fullTransparentValue The alpha pixel value of a full transparent pixel
66 * @param framePaddingElements The number of padding elements at the end of each frame row, in elements, with range [0, infinity)
67 * @param worker Optional worker object to distribute the computation
68 * @return The smallest bounding box enclosing all opaque pixels, an invalid bounding box if the frames does not contain an opaque pixel
69 * @tparam T Data type of each pixel channel value
70 */
71 template <typename T>
72 static PixelBoundingBox detectOpaqueBoundingBox(const T* frame, const unsigned int width, const unsigned int height, const unsigned int alphaChannelIndex, const unsigned int channels, const T fullTransparentValue, const unsigned int framePaddingElements, Worker* worker = nullptr);
73
74 /**
75 * Detects the smallest bounding box of opaque pixels in a given frame.
76 * @param frame The frame in the opaque pixels are determined
77 * @param transparentIs0xFF True, if 0xFF is interpreted as a full transparent pixel
78 * @param worker Optional worker object to distribute the computation
79 * @return Resulting smallest bounding box, an invalid bounding box if no opaque pixel has been found
80 */
81 static PixelBoundingBox detectOpaqueBoundingBox(const Frame& frame, const bool transparentIs0xFF, Worker* worker = nullptr);
82
83 /**
84 * Returns whether a mask frame has at least one pixel with a specific mask value.
85 * @param mask The 8 bit mask frame in which the pixel value is sought, must be valid
86 * @param width The width of the mask frame in pixel, with range [1, infinity)
87 * @param height The height of the mask frame in pixel, with range [1, infinity)
88 * @param value The value to be sought, with range [0, 255]
89 * @param maskPaddingElements The number of padding elements at the end of each mask row, in elements, with range [0, infinity)
90 * @param boundingBox Optional bounding box to speedup the computation, must fit into the given frame if defined
91 * @return True, if at least one mask pixel has the specified value
92 */
93 static inline bool hasValue(const uint8_t* mask, const unsigned int width, const unsigned int height, const uint8_t value, const unsigned int maskPaddingElements, const PixelBoundingBox& boundingBox = CV::PixelBoundingBox());
94
95 protected:
96
97 /**
98 * Detects the smallest bounding box enclosing all opaque pixels in a subset of a given frame.
99 * @param frame The frame in which the bounding box enclosing all opaque pixels is determined, must be valid
100 * @param width The width of the frame in pixel, with range [1, infinity)
101 * @param height The height of the frame in pixel, with range [1, infinity)
102 * @param alphaChannelIndex The index of the alpha channel, with range [0, channels - 1]
103 * @param channels The number of frame channels, with range [1, infinity)
104 * @param fullTransparentValue The alpha pixel value of a full transparent pixel
105 * @param framePaddingElements The number of padding elements at the end of each frame row, in elements, with range [0, infinity)
106 * @param left Resulting left bounding box position
107 * @param top Resulting top bounding box position
108 * @param right Resulting right bounding box position
109 * @param bottom Resulting bottom bounding box position
110 * @param lock Optional lock if this function is executed distributed within several threads
111 * @param firstRow First row to be handled
112 * @param numberRows Number of rows to be handled
113 * @tparam T Data type of each pixel channel value
114 */
115 template <typename T>
116 static void detectOpaqueBoundingBoxSubset(const T* frame, const unsigned int width, const unsigned int height, const unsigned int alphaChannelIndex, const unsigned int channels, const T fullTransparentValue, const unsigned int framePaddingElements, unsigned int* left, unsigned int* top, unsigned int* right, unsigned int* bottom, Lock* lock, const unsigned int firstRow, const unsigned int numberRows);
117};
118
119template <typename T>
120PixelBoundingBox MaskAnalyzer::detectOpaqueBoundingBox(const T* frame, const unsigned int width, const unsigned int height, const unsigned int alphaChannelIndex, const unsigned int channels, const T fullTransparentValue, const unsigned int framePaddingElements, Worker* worker)
121{
122 ocean_assert(frame != nullptr);
123 ocean_assert(channels != 0u);
124 ocean_assert(alphaChannelIndex < channels);
125
126 unsigned int left = (unsigned int)(-1);
127 unsigned int top = (unsigned int)(-1);
128 unsigned int right = 0u;
129 unsigned int bottom = 0u;
130
131 if (worker)
132 {
133 Lock lock;
134 worker->executeFunction(Worker::Function::createStatic(&MaskAnalyzer::detectOpaqueBoundingBoxSubset<T>, frame, width, height, alphaChannelIndex, channels, fullTransparentValue, framePaddingElements, &left, &top, &right, &bottom, &lock, 0u, 0u), 0u, height, 12u, 13u, 20u);
135 }
136 else
137 {
138 detectOpaqueBoundingBoxSubset<T>(frame, width, height, alphaChannelIndex, channels, fullTransparentValue, framePaddingElements, &left, &top, &right, &bottom, nullptr, 0u, height);
139 }
140
141 return PixelBoundingBox(left, top, right, bottom);
142}
143
144template <typename T>
145void MaskAnalyzer::detectOpaqueBoundingBoxSubset(const T* frame, const unsigned int width, const unsigned int height, const unsigned int alphaChannelIndex, const unsigned int channels, const T fullTransparentValue, const unsigned int framePaddingElements, unsigned int* left, unsigned int* top, unsigned int* right, unsigned int* bottom, Lock* lock, const unsigned int firstRow, const unsigned int numberRows)
146{
147 ocean_assert(frame != nullptr);
148 ocean_assert(alphaChannelIndex < channels);
149 ocean_assert_and_suppress_unused(firstRow + numberRows <= height, height);
150
151 const unsigned int frameStrideElements = width * channels + framePaddingElements;
152
153 unsigned int localLeft = (unsigned int)(-1);
154 unsigned int localRight = 0u;
155 unsigned int localTop = (unsigned int)(-1);
156 unsigned int localBottom = 0u;
157
158 for (unsigned int y = firstRow; y < firstRow + numberRows; ++y)
159 {
160 const T* frameRow = frame + y * frameStrideElements + alphaChannelIndex;
161
162 for (unsigned int x = 0u; x < width; ++x)
163 {
164 if (*frameRow != fullTransparentValue)
165 {
166 if (x < localLeft)
167 {
168 localLeft = x;
169 }
170
171 if (x > localRight)
172 {
173 localRight = x;
174 }
175
176 if (y < localTop)
177 {
178 localTop = y;
179 }
180
181 if (y > localBottom)
182 {
183 localBottom = y;
184 }
185 }
186
187 frameRow += channels;
188 }
189 }
190
191 const OptionalScopedLock scopedLock(lock);
192
193 *left = min(*left, localLeft);
194 *top = min(*top, localTop);
195
196 *right = max(*right, localRight);
197 *bottom = max(*bottom, localBottom);
198}
199
200inline bool MaskAnalyzer::hasValue(const uint8_t* mask, const unsigned int width, const unsigned int height, const uint8_t value, const unsigned int maskPaddingElements, const PixelBoundingBox& boundingBox)
201{
202 ocean_assert(mask != nullptr && width != 0u && height != 0u);
203
204 const Frame maskFrame(FrameType(width, height, FrameType::FORMAT_Y8, FrameType::ORIGIN_UPPER_LEFT), mask, Frame::CM_USE_KEEP_LAYOUT, maskPaddingElements);
205
206 const Frame::PixelType<uint8_t, 1u> pixelValue = {{value}};
207
208 if (boundingBox.isValid())
209 {
210 return maskFrame.subFrame(boundingBox.left(), boundingBox.top(), boundingBox.width(), boundingBox.height(), Frame::CM_USE_KEEP_LAYOUT).containsValue<uint8_t, 1u>(pixelValue);
211 }
212
213 return maskFrame.containsValue<uint8_t, 1u>(pixelValue);
214}
215
216}
217
218}
219
220#endif // META_OCEAN_CV_MASK_ANALYZER_H
This class implements basic maks analyzing functions.
Definition MaskAnalyzer.h:30
static PixelBoundingBox detectBoundingBox(const uint8_t *mask, const unsigned int width, const unsigned int height, const uint8_t nonMaskPixel, const unsigned int maskPaddingElements)
Detects the smallest axis-aligned bounding box enclosing all isolated mask islands in a binary (but 8...
static PixelBoundingBox detectOpaqueBoundingBox(const Frame &frame, const bool transparentIs0xFF, Worker *worker=nullptr)
Detects the smallest bounding box of opaque pixels in a given frame.
static PixelBoundingBox detectBoundingBox(const uint8_t *const mask, const unsigned int width, const unsigned int height, const PixelBoundingBox &rough, const unsigned int maxUncertainty, const uint8_t nonMaskPixel=0xFFu, const unsigned int maskPaddingElements=0u)
Detects the smallest axis-aligned bounding box enclosing all isolated mask islands inside a given mas...
static bool hasValue(const uint8_t *mask, const unsigned int width, const unsigned int height, const uint8_t value, const unsigned int maskPaddingElements, const PixelBoundingBox &boundingBox=CV::PixelBoundingBox())
Returns whether a mask frame has at least one pixel with a specific mask value.
Definition MaskAnalyzer.h:200
static PixelBoundingBox detectOpaqueBoundingBox(const T *frame, const unsigned int width, const unsigned int height, const unsigned int alphaChannelIndex, const unsigned int channels, const T fullTransparentValue, const unsigned int framePaddingElements, Worker *worker=nullptr)
Detects the smallest bounding box enclosing all opaque pixels in a given frame.
Definition MaskAnalyzer.h:120
static void detectOpaqueBoundingBoxSubset(const T *frame, const unsigned int width, const unsigned int height, const unsigned int alphaChannelIndex, const unsigned int channels, const T fullTransparentValue, const unsigned int framePaddingElements, unsigned int *left, unsigned int *top, unsigned int *right, unsigned int *bottom, Lock *lock, const unsigned int firstRow, const unsigned int numberRows)
Detects the smallest bounding box enclosing all opaque pixels in a subset of a given frame.
Definition MaskAnalyzer.h:145
T left() const
Returns the left (including) pixel position of this bounding box.
Definition PixelBoundingBox.h:416
unsigned int width() const
Returns the width (the number of horizontal including pixels) of this bounding box.
Definition PixelBoundingBox.h:482
bool isValid() const
Returns whether this bounding box covers a valid pixel area.
Definition PixelBoundingBox.h:577
T top() const
Returns the top (including) pixel position of this bounding box.
Definition PixelBoundingBox.h:423
unsigned int height() const
Returns the height (the number of vertical including pixels) of this bounding box.
Definition PixelBoundingBox.h:489
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:1808
typename Ocean::DataType< T, tChannels >::Type PixelType
Definition of a data type storing all channel values of one pixel in an array.
Definition Frame.h:2338
Frame subFrame(const unsigned int subFrameLeft, const unsigned int subFrameTop, const unsigned int subFrameWidth, const unsigned int subFrameHeight, const CopyMode copyMode=CM_USE_KEEP_LAYOUT) const
Returns a sub-frame of this frame.
@ CM_USE_KEEP_LAYOUT
The source memory is used only, no copy is created, the padding layout is preserved.
Definition Frame.h:1817
bool containsValue(const PixelType< T, tPlaneChannels > &planePixelValue, const unsigned int planeIndex=0u) const
Returns whether the frame (one plane) contains a specified pixel value.
Definition Frame.h:4004
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 recursive lock object.
Definition Lock.h:31
This class implements an optional recursive scoped lock object locking the lock object only if it's d...
Definition Lock.h:325
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.
PixelBoundingBoxT< unsigned int > PixelBoundingBox
Definition of the default PixelBoundingBox object with data type allowing only positive coordinate va...
Definition PixelBoundingBox.h:28
The namespace covering the entire Ocean framework.
Definition Accessor.h:15