Ocean
Loading...
Searching...
No Matches
FrameFilterGradient.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_GRADIENT_H
9#define META_OCEAN_CV_FRAME_FILTER_GRADIENT_H
10
11#include "ocean/cv/CV.h"
13
14#include "ocean/base/Worker.h"
15
16namespace Ocean
17{
18
19namespace CV
20{
21
22/**
23 * This class implements a gradient frame filter.
24 * @ingroup cv
25 */
27{
28 public:
29
30 /**
31 * Horizontal and vertical gradient filter for a 1-plane frame with arbitrary data type and arbitrary number of channels.
32 * The horizontal and vertical filter responses are stored in a 1-plane response frame so that for each pixel and channel two corresponding filter results exist (interleaved).<br>
33 * The border response pixel results are set to zero.
34 * @param source The source frame to filter, must be valid
35 * @param target The filter response with two filter response elements per pixel and channel, must be valid
36 * @param width The width of the frame in pixel, with range [3, infinity)
37 * @param height The height of the frame in pixel, with range [3, infinity)
38 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
39 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
40 * @param multiplicationFactor Multiplication factor that is applied to each filter result before the value is assigned to the target, with range (-infinity, infinity)
41 * @param worker Optional worker object to distribute the computational load
42 * @tparam TSource The data type of the source frame
43 * @tparam TTarget The data type of the target frame
44 * @tparam tChannels The number of the source frame, with range [1, infinity)
45 * @tparam tNormalizeByTwo True, to normalize the subtraction result by two; False, to simply determine the subtraction result
46 * @see filterHorizontalVerticalSubFrame(), filterHorizontalVerticalMagnitudeSquared().
47 */
48 template <typename TSource, typename TTarget, unsigned int tChannels, bool tNormalizeByTwo>
49 static inline void filterHorizontalVertical(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const TTarget multiplicationFactor = TTarget(1), Worker* worker = nullptr);
50
51 /**
52 * Squared magnitude gradient filter using the horizontal and vertical gradients that can be applied to zipped frames with arbitrary data type and arbitrary number of channels.
53 * The border pixel results are set to zero.<br>
54 * The two individual filter responses are collected, applied as a vector and the vector's squared length is stored as result.<br>
55 * Thus, for each pixel and each channel one filter response is created.
56 * @param source The source frame to filter, must be valid
57 * @param target Filter response with one filter response (the squared magnitude of the gradient) per pixel and channel
58 * @param width The width of the frame in pixel, with range [3, infinity)
59 * @param height The height of the frame in pixel, with range [3, infinity)
60 * @param multiplicationFactor Multiplication factor that is applied to each filter result before the value is assigned to the target, with range (-infinity, infinity)
61 * @param worker Optional worker object to distribute the computational load
62 * @tparam TSource The data type of the source frame
63 * @tparam TTarget The data type of the target frame
64 * @tparam tChannels The number of the source frame, with range [1, infinity)
65 * @tparam tNormalizeByTwo True, to normalize the subtraction result by two; False, to simply determine the subtraction result
66 * @see filterHorizontalVertical().
67 */
68 template <typename TSource, typename TTarget, unsigned int tChannels, bool tNormalizeByTwo>
69 static inline void filterHorizontalVerticalMagnitudeSquared(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const TTarget multiplicationFactor = TTarget(1), Worker* worker = nullptr);
70
71 /**
72 * Horizontal and vertical gradient filter for sub-frame of a 1-plane frame with arbitrary data type and arbitrary number of channels.
73 * In contrast to filterHorizontalVertical(), this function does not set border response pixels to zero in case the border of the sub-frame is not located at the border of the source frame.
74 * @param source The source frame to filter, must be valid
75 * @param sourceWidth The width of the source frame in pixel, with range [3, infinity)
76 * @param sourceHeight the height of the source frame in pixel, with range [3, infinity)
77 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
78 * @param sourceLeft Horizontal start position of the sub-frame inside the source frame, in pixels, with range [0, sourceWidth)
79 * @param sourceTop Vertical start position of the sub-frame inside the source frame, in pixels, with range [0, sourceHeight)
80 * @param target The filter response with two elements per pixel and channel with dimension targetWidth x targetHeight, must be valid
81 * @param targetWidth The width of the sub-frame inside the source frame (and thus the width of the target response frame), in pixels, with range [1, sourceWidth - sourceLeft]
82 * @param targetHeight The height of the sub-frame inside the source frame (and thus the height of the target response frame), in pixels, with range [1, sourceHeight - sourceTop]
83 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
84 * @param multiplicationFactor Multiplication factor that is applied to each filter result before the value is assigned to the target, with range (-infinity, infinity)
85 * @param worker Optional worker object to distribute the computational load
86 * @tparam TSource The data type of the source frame
87 * @tparam TTarget The data type of the target frame
88 * @tparam tChannels The number of the source frame, with range [1, infinity)
89 * @tparam tNormalizeByTwo True, to normalize the subtraction result by two; False, to simply determine the subtraction result
90 * @see filterHorizontalVertical().
91 */
92 template <typename TSource, typename TTarget, unsigned int tChannels, bool tNormalizeByTwo>
93 static inline void filterHorizontalVerticalSubFrame(const TSource* source, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourcePaddingElements, const unsigned int sourceLeft, const unsigned int sourceTop, TTarget* target, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetPaddingElements, const TTarget multiplicationFactor = TTarget(1), Worker* worker = nullptr);
94
95 /**
96 * Determines the lined integral image of the horizontal 1x2 gradient filter when applied to a source image.
97 * The function applies the following 1x2 box filter to each pixel of the source image:
98 * <pre>
99 * [-1. 1]
100 * </pre>
101 * The response value will be stored at the location of the left filter pixel (marked with a dot `.`).
102 * The intermediate (internal only) response image has resolution (width-1)x(height).
103 * The resulting (lined) integral response image has the following scheme:
104 * <pre>
105 * ------------
106 * |000000000000|
107 * |0|----------|
108 * |0| |
109 * |0| Integral |
110 * |0| |
111 * ------------
112 * </pre>
113 * The resolution of the (lined) integral image is: (width)x(height + 1).
114 * @param source The source image to which the horizontal gradient filter will be applied, with resolution (width)x(height), must be valid
115 * @param width The width of the source image in pixel, with range [2, infinity)
116 * @param height The height of the source image in pixel, with range [1, infinity)
117 * @param integral The resulting integral image, with resolution (width)x(height + 1), must be valid
118 * @param sourcePaddingElements Optional number of padding elements at the end of each row of the source frame, in elements, with range [0, infinity)
119 * @param integralPaddingElements Optional number of padding elements at the end of each row of the integral frame, in elements, with range [0, infinity)
120 * @tparam T The data type of the elements in the source image
121 * @tparam TIntegral The data type of the elements in the integral image
122 * @tparam tAbsoluteGradient True, to determine the absolute gradients; False, to determine the signed gradients
123 */
124 template <typename T, typename TIntegral, bool tAbsoluteGradient = false>
125 static void filterHorizontal1x2LinedIntegralImage(const T* source, const unsigned int width, const unsigned int height, TIntegral* integral, const unsigned int sourcePaddingElements, const unsigned int integralPaddingElements);
126
127 /**
128 * Determines the lined integral image of the vertical 2x1 gradient filter when applied to a source image.
129 * The function applies the following 2x1 box filter to each pixel of the source image:
130 * <pre>
131 * [ -1. ]
132 * [ 1 ]
133 * </pre>
134 * The response value will be stored at the location of the left filter pixel (marked with a dot `.`).
135 * The intermediate (internal only) response image has resolution (width)x(height - 1).
136 * The resulting (lined) integral response image has the following scheme:
137 * <pre>
138 * ------------
139 * |000000000000|
140 * |0|----------|
141 * |0| |
142 * |0| Integral |
143 * |0| |
144 * ------------
145 * </pre>
146 * The resolution of the (lined) integral image is: (width + 1)x(height).
147 * @param source The source image to which the horizontal gradient filter will be applied, with resolution (width)x(height), must be valid
148 * @param width The width of the source image in pixel, with range [1, infinity)
149 * @param height The height of the source image in pixel, with range [2, infinity)
150 * @param integral The resulting integral image, with resolution (width + 1)x(height), must be valid
151 * @param sourcePaddingElements Optional number of padding elements at the end of each row of the source frame, in elements, with range [0, infinity)
152 * @param integralPaddingElements Optional number of padding elements at the end of each row of the integral frame, in elements, with range [0, infinity)
153 * @tparam T The data type of the elements in the source image
154 * @tparam TIntegral The data type of the elements in the integral image
155 * @tparam tAbsoluteGradient True, to determine the absolute gradients; False, to determine the signed gradients
156 */
157 template <typename T, typename TIntegral, bool tAbsoluteGradient = false>
158 static void filterVertical2x1LinedIntegralImage(const T* source, const unsigned int width, const unsigned int height, TIntegral* integral, const unsigned int sourcePaddingElements, const unsigned int integralPaddingElements);
159};
160
161template <typename TSource, typename TTarget, unsigned int tChannels, bool tNormalizeByTwo>
162inline void FrameFilterGradient::filterHorizontalVertical(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const TTarget multiplicationFactor, Worker* worker)
163{
164 FrameFilterGradientBase::filterHorizontalVertical<TSource, TTarget, tChannels, tNormalizeByTwo>(source, target, width, height, sourcePaddingElements, targetPaddingElements, multiplicationFactor, worker);
165}
166
167template <typename TSource, typename TTarget, unsigned int tChannels, bool tNormalizeByTwo>
168inline void FrameFilterGradient::filterHorizontalVerticalMagnitudeSquared(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const TTarget multiplicationFactor, Worker* worker)
169{
170 FrameFilterGradientBase::filterHorizontalVerticalMagnitudeSquared<TSource, TTarget, tChannels, tNormalizeByTwo>(source, target, width, height, multiplicationFactor, worker);
171}
172
173template <typename TSource, typename TTarget, unsigned int tChannels, bool tNormalizeByTwo>
174inline void FrameFilterGradient::filterHorizontalVerticalSubFrame(const TSource* source, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourcePaddingElements, const unsigned int sourceLeft, const unsigned int sourceTop, TTarget* target, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetPaddingElements, const TTarget multiplicationFactor, Worker* worker)
175{
176 FrameFilterGradientBase::filterHorizontalVerticalSubFrame<TSource, TTarget, tChannels, tNormalizeByTwo>(source, sourceWidth, sourceHeight, sourcePaddingElements, sourceLeft, sourceTop, target, targetWidth, targetHeight, targetPaddingElements, multiplicationFactor, worker);
177}
178
179template <typename T, typename TIntegral, bool tAbsoluteGradient>
180void FrameFilterGradient::filterHorizontal1x2LinedIntegralImage(const T* source, const unsigned int width, const unsigned int height, TIntegral* integral, const unsigned int sourcePaddingElements, const unsigned int integralPaddingElements)
181{
182 static_assert(sizeof(T) <= sizeof(TIntegral), "Invalid integral elements!");
183
184 ocean_assert(source != nullptr);
185 ocean_assert(width >= 2u);
186 ocean_assert(height >= 1u);
187 ocean_assert(integral != nullptr);
188
189 /*
190 * This is the resulting lined integral image, with resolution (width)x(height + 1):
191 * ------------
192 * |000000000000|
193 * |0|----------|
194 * |0| |
195 * |0| Integral |
196 * |0| |
197 * |------------
198 */
199
200 typedef typename DifferenceValueTyper<TIntegral>::Type TSignedIntegral;
201
202 // entire top line will be set to zero
203 memset(integral, 0x00, width * sizeof(TIntegral));
204
205#ifdef OCEAN_DEBUG
206 for (unsigned int n = 0u; n < width; ++n)
207 {
208 ocean_assert(integral[n] == TIntegral(0));
209 }
210#endif
211
212 integral += width + integralPaddingElements;
213
214 // we calculate the first row of the integral image
215
216 const T* const sourceFirstRowEnd = source + width - 1u; // excluding the last pixel
217 const T* const sourceEnd = source + (width + sourcePaddingElements) * height;
218
219 const TIntegral* integralPreviousRow = integral;
220
221 TIntegral previousIntegral = TIntegral(0);
222
223 *integral++ = TIntegral(0);
224
225 // the remaining pixels of the first row
226
227 while (source != sourceFirstRowEnd)
228 {
229 previousIntegral += tAbsoluteGradient ? TIntegral(NumericT<TSignedIntegral>::abs(TSignedIntegral(source[1] - source[0]))) : TIntegral(source[1] - source[0]);
230 ++source;
231
232 *integral++ = previousIntegral;
233 }
234
235 source += sourcePaddingElements + 1u; // including the last pixel
236 integral += integralPaddingElements;
237
238 // we calculate the remaining rows
239
240 while (source != sourceEnd)
241 {
242 const T* const sourceRowEnd = source + width - 1u; // excluding the last pixel
243
244 previousIntegral = TIntegral(0);
245
246 // left pixel
247 *integral++ = TIntegral(0);
248
249 ++integralPreviousRow;
250
251 while (source != sourceRowEnd)
252 {
253 previousIntegral += tAbsoluteGradient ? TIntegral(NumericT<TSignedIntegral>::abs(TSignedIntegral(source[1] - source[0]))) : TIntegral(source[1] - source[0]);
254 ++source;
255
256 *integral++ = previousIntegral + *integralPreviousRow++;
257 }
258
259 source += sourcePaddingElements + 1u; // including the last pixel
260 integral += integralPaddingElements;
261 integralPreviousRow += integralPaddingElements;
262 }
263}
264
265template <typename T, typename TIntegral, bool tAbsoluteGradient>
266void FrameFilterGradient::filterVertical2x1LinedIntegralImage(const T* source, const unsigned int width, const unsigned int height, TIntegral* integral, const unsigned int sourcePaddingElements, const unsigned int integralPaddingElements)
267{
268 ocean_assert(source != nullptr);
269 ocean_assert(width >= 1u);
270 ocean_assert(height >= 2u);
271 ocean_assert(integral != nullptr);
272
273 const unsigned int sourceStrideElements = width + sourcePaddingElements;
274
275 /*
276 * This is the resulting lined integral image, with resolution (width + 1)x(height):
277 * ------------
278 * |000000000000|
279 * |0|----------|
280 * |0| |
281 * |0| Integral |
282 * |0| |
283 * |------------
284 */
285
286 typedef typename DifferenceValueTyper<TIntegral>::Type TSignedIntegral;
287
288 // entire top line will be set to zero
289 memset(integral, 0x00, (width + 1u) * sizeof(TIntegral));
290
291#ifdef OCEAN_DEBUG
292 for (unsigned int n = 0u; n < width + 1u; ++n)
293 {
294 ocean_assert(integral[n] == TIntegral(0));
295 }
296#endif
297
298 integral += width + 1u + integralPaddingElements;
299
300 // we calculate the first row of the integral image
301
302 const T* const sourceFirstRowEnd = source + width;
303 const T* const sourceEnd = source + sourceStrideElements * (height - 1u); // excluding the last row
304
305 const TIntegral* integralPreviousRow = integral;
306
307 TIntegral previousIntegral = TIntegral(0);
308
309 *integral++ = TIntegral(0);
310
311 // the remaining pixels of the first row
312
313 const T* sourceNextRow = source + sourceStrideElements;
314
315 while (source != sourceFirstRowEnd)
316 {
317 previousIntegral += tAbsoluteGradient ? TIntegral(NumericT<TSignedIntegral>::abs(TSignedIntegral(*sourceNextRow++ - *source++))) : TIntegral(*sourceNextRow++ - *source++);
318
319 *integral++ = previousIntegral;
320 }
321
322 source += sourcePaddingElements;
323 sourceNextRow += sourcePaddingElements;
324 integral += integralPaddingElements;
325
326 // we calculate the remaining rows
327
328 while (source != sourceEnd)
329 {
330 const T* const sourceRowEnd = source + width;
331
332 previousIntegral = TIntegral(0);
333
334 // left pixel
335 *integral++ = TIntegral(0);
336
337 ++integralPreviousRow;
338
339 while (source != sourceRowEnd)
340 {
341 previousIntegral += tAbsoluteGradient ? TIntegral(NumericT<TSignedIntegral>::abs(TSignedIntegral(*sourceNextRow++ - *source++))) : TIntegral(*sourceNextRow++ - *source++);
342
343 *integral++ = previousIntegral + *integralPreviousRow++;
344 }
345
346 source += sourcePaddingElements;
347 sourceNextRow += sourcePaddingElements;
348
349 integral += integralPaddingElements;
350 integralPreviousRow += integralPaddingElements;
351 }
352}
353
354}
355
356}
357
358#endif // META_OCEAN_CV_FRAME_FILTER_GRADIENT_H
This class implements a gradient frame filter.
Definition FrameFilterGradient.h:27
static void filterHorizontal1x2LinedIntegralImage(const T *source, const unsigned int width, const unsigned int height, TIntegral *integral, const unsigned int sourcePaddingElements, const unsigned int integralPaddingElements)
Determines the lined integral image of the horizontal 1x2 gradient filter when applied to a source im...
Definition FrameFilterGradient.h:180
static void filterHorizontalVertical(const TSource *source, TTarget *target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const TTarget multiplicationFactor=TTarget(1), Worker *worker=nullptr)
Horizontal and vertical gradient filter for a 1-plane frame with arbitrary data type and arbitrary nu...
Definition FrameFilterGradient.h:162
static void filterHorizontalVerticalSubFrame(const TSource *source, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourcePaddingElements, const unsigned int sourceLeft, const unsigned int sourceTop, TTarget *target, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int targetPaddingElements, const TTarget multiplicationFactor=TTarget(1), Worker *worker=nullptr)
Horizontal and vertical gradient filter for sub-frame of a 1-plane frame with arbitrary data type and...
Definition FrameFilterGradient.h:174
static void filterVertical2x1LinedIntegralImage(const T *source, const unsigned int width, const unsigned int height, TIntegral *integral, const unsigned int sourcePaddingElements, const unsigned int integralPaddingElements)
Determines the lined integral image of the vertical 2x1 gradient filter when applied to a source imag...
Definition FrameFilterGradient.h:266
static void filterHorizontalVerticalMagnitudeSquared(const TSource *source, TTarget *target, const unsigned int width, const unsigned int height, const TTarget multiplicationFactor=TTarget(1), Worker *worker=nullptr)
Squared magnitude gradient filter using the horizontal and vertical gradients that can be applied to ...
Definition FrameFilterGradient.h:168
T Type
Definition of the data type for the signed difference value.
Definition DataType.h:176
This class provides basic numeric functionalities.
Definition Numeric.h:57
This class implements a worker able to distribute function calls over different threads.
Definition Worker.h:33
The namespace covering the entire Ocean framework.
Definition Accessor.h:15