Ocean
FrameFilterScharr.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_SCHARR_H
9 #define META_OCEAN_CV_FRAME_FILTER_SCHARR_H
10 
11 #include "ocean/cv/CV.h"
12 #include "ocean/cv/FrameChannels.h"
13 
14 #include "ocean/base/Worker.h"
15 
16 namespace Ocean
17 {
18 
19 namespace CV
20 {
21 
22 /**
23  * This class implements a Scharr filter.
24  * The horizontal (0 degree) and vertical (90 degree - clockwise) 3x3 Scharr filter (not the convolution filter) are defined as:
25  * <pre>
26  * horizontal: vertical (90 degree):
27  * | -3 0 3 | | -3 -10 -3 |
28  * | -10 0 10 | | 0 0 0 |
29  * | -3 0 3 | | 3 10 3 |
30  * </pre>
31  *
32  * The diagonal 3x3 Scharr filters are defined as:
33  * <pre>
34  * 45 degree: 135 degree:
35  * | -10 -3 0 | | 0 -3 -10 |
36  * | -3 0 3 | | 3 0 -3 |
37  * | 0 3 10 | | 10 3 0 |
38  * </pre>
39  * @see FrameFilterScharrMagnitude, FrameFilterSobel.
40  * @ingroup cv
41  */
42 class OCEAN_CV_EXPORT FrameFilterScharr
43 {
44  public:
45 
46  /**
47  * The following comfort class provides comfortable functions simplifying prototyping applications but also increasing binary size of the resulting applications.
48  * Best practice is to avoid using these functions if binary size matters,<br>
49  * as for every comfort function a corresponding function exists with specialized functionality not increasing binary size significantly.<br>
50  */
51  class OCEAN_CV_EXPORT Comfort
52  {
53  public:
54 
55  /**
56  * Horizontal and vertical Scharr filer for images.
57  * The target frame must be valid, must have data type 'DT_SIGNED_INTEGER_8` or `DT_SIGNED_INTEGER_16`.
58  * @param source The source frame to filter, must be valid
59  * @param target The target frame receiving the filtered frame, must be valid
60  * @param worker Optional worker object to distribute the computational load
61  * @return True, if succeeded
62  */
63  static bool filterHorizontalVertical(const Frame& source, Frame& target, Worker* worker = nullptr);
64 
65  /**
66  * Diagonal (45 and 135 degree) Scharr filer for images.
67  * The target frame must be valid, must have data type 'DT_SIGNED_INTEGER_8` or `DT_SIGNED_INTEGER_16`.
68  * @param source The source frame to filter, must be valid
69  * @param target The target frame receiving the filtered frame, must be valid
70  * @param worker Optional worker object to distribute the computational load
71  * @return True, if succeeded
72  */
73  static bool filterDiagonal(const Frame& source, Frame& target, Worker* worker = nullptr);
74 
75  /**
76  * Horizontal, vertical, and diagonal Scharr filer for images.
77  * The target frame must be valid, must have data type 'DT_SIGNED_INTEGER_8` or `DT_SIGNED_INTEGER_16`.
78  * @param source The source frame to filter, must be valid
79  * @param target The target frame receiving the filtered frame, must be valid
80  * @param worker Optional worker object to distribute the computational load
81  * @return True, if succeeded
82  */
83  static bool filter(const Frame& source, Frame& target, Worker* worker = nullptr);
84 
85  /**
86  * Determines the maximum of the absolute horizontal and vertical Scharr filter.
87  * The target frame must be valid, must have data type 'DT_UNSIGNED_INTEGER_8` or `DT_UNSIGNED_INTEGER_16`.
88  * @param source The source frame to filter, must be valid
89  * @param target The target frame receiving the filtered frame, must be valid
90  * @param worker Optional worker object to distribute the computational load
91  * @return True, if succeeded
92  */
93  static bool filterHorizontalVerticalMaximumAbsolute(const Frame& source, Frame& target, Worker* worker = nullptr);
94 
95  /**
96  * Determines the maximum of the absolute horizontal, vertical, and diagonal Scharr filter.
97  * The target frame must be valid, must have data type 'DT_UNSIGNED_INTEGER_8` or `DT_UNSIGNED_INTEGER_16`.
98  * @param source The source frame to filter, must be valid
99  * @param target The target frame receiving the filtered frame, must be valid
100  * @param worker Optional worker object to distribute the computational load
101  * @return True, if succeeded
102  */
103  static bool filterMaximumAbsolute(const Frame& source, Frame& target, Worker* worker = nullptr);
104  };
105 
106  public:
107 
108  /**
109  * Horizontal and vertical Scharr filer for images.
110  * If the target response data type is selected to be `int8_t`, each filter response is normalized by 1/32 to fit into the value range [-128, 127].<br>
111  * If the target response data type is selected to be `int16_t` no normalization will be applied.
112  * The border pixels are set to zero.
113  * @param source The source frame to which the Scharr filter will be applied, with `tSourceChannels` channels, must be valid
114  * @param target The target response frame receiving the horizontal and vertical Scharr responses, with `tSourceChannels * 2` channels, must be valid
115  * @param width The width of the frame in pixel, with range [3, infinity)
116  * @param height The height of the frame in pixel, with range [3, infinity)
117  * @param sourcePaddingElements Optional padding at the end of each source row in elements, with range [0, infinity)
118  * @param targetPaddingElements Optional padding at the end of each target row in elements, with range [0, infinity)
119  * @param worker Optional worker object to distribute the computational load
120  * @tparam TTarget The data type of the response values, either `int8_t` or `int16_t`
121  * @tparam tSourceChannels The number of channels of the source frame, with range [1, infinity)
122  */
123  template <typename TTarget, unsigned int tSourceChannels>
124  static inline void filterHorizontalVertical8BitPerChannel(const uint8_t* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
125 
126  /**
127  * Diagonal (45 and 135 degree) Scharr filer for images.
128  * If the target response data type is selected to be `int8_t`, each filter response is normalized by 1/32 to fit into the value range [-128, 127].<br>
129  * If the target response data type is selected to be `int16_t` no normalization will be applied.
130  * The border pixels are set to zero.
131  * @param source The source frame to which the Scharr filter will be applied, with `tSourceChannels` channels, must be valid
132  * @param target The target response frame receiving the 45 diagonal and 135 diagonal Scharr responses, with `tSourceChannels * 2` channels, must be valid
133  * @param width The width of the frame in pixel, with range [3, infinity)
134  * @param height The height of the frame in pixel, with range [3, infinity)
135  * @param sourcePaddingElements Optional padding at the end of each source row in elements, with range [0, infinity)
136  * @param targetPaddingElements Optional padding at the end of each target row in elements, with range [0, infinity)
137  * @param worker Optional worker object to distribute the computational load
138  * @tparam TTarget The data type of the response values, either `int8_t` or `int16_t`
139  * @tparam tSourceChannels The number of channels of the source frame, with range [1, infinity)
140  */
141  template <typename TTarget, unsigned int tSourceChannels>
142  static inline void filterDiagonal8BitPerChannel(const uint8_t* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
143 
144  /**
145  * Horizontal, vertical, and diagonal Scharr filer for images.
146  * If the target response data type is selected to be `int8_t`, each filter response is normalized by 1/32 to fit into the value range [-128, 127].<br>
147  * If the target response data type is selected to be `int16_t` no normalization will be applied.
148  * The border pixels are set to zero.
149  * @param source The source frame to which the Scharr filter will be applied, with `tSourceChannels` channels, must be valid
150  * @param target The target response frame receiving the horizontal, vertical, and both diagonal Scharr responses, with `tSourceChannels * 4` channels, must be valid
151  * @param width The width of the frame in pixel, with range [3, infinity)
152  * @param height The height of the frame in pixel, with range [3, infinity)
153  * @param sourcePaddingElements Optional padding at the end of each source row in elements, with range [0, infinity)
154  * @param targetPaddingElements Optional padding at the end of each target row in elements, with range [0, infinity)
155  * @param worker Optional worker object to distribute the computational load
156  * @tparam TTarget The data type of the response values, either `int8_t` or `int16_t`
157  * @tparam tSourceChannels The number of channels of the source frame, with range [1, infinity)
158  */
159  template <typename TTarget, unsigned int tSourceChannels>
160  static inline void filter8BitPerChannel(const uint8_t* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
161 
162  /**
163  * Determines the maximum of the absolute horizontal and vertical Scharr filter.
164  * If the target response data type is selected to be `uint8_t`, each filter response is normalized by 1/16 to fit into the value range [0, 255].<br>
165  * If the target response data type is selected to be `uint16_t` no normalization will be applied.
166  * The border pixels are set to zero.
167  * @param source The source frame to which the Scharr filter will be applied, with `tSourceChannels` channels, must be valid
168  * @param target The target response frame receiving the maximal Scharr responses, with `tSourceChannels` channels, must be valid
169  * @param width The width of the frame in pixel, with range [3, infinity)
170  * @param height The height of the frame in pixel, with range [3, infinity)
171  * @param sourcePaddingElements Optional padding at the end of each source row in elements, with range [0, infinity)
172  * @param targetPaddingElements Optional padding at the end of each target row in elements, with range [0, infinity)
173  * @param worker Optional worker object to distribute the computational load
174  * @tparam TTarget The data type of the response values, either `uint8_t` or `uint16_t`
175  * @tparam tSourceChannels The number of channels of the source frame, with range [1, infinity)
176  */
177  template <typename TTarget, unsigned int tSourceChannels>
178  static inline void filterHorizontalVerticalMaximumAbsolute8BitPerChannel(const uint8_t* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
179 
180  /**
181  * Determines the maximum of the absolute horizontal, vertical, and diagonal Scharr filter.
182  * If the target response data type is selected to be `uint8_t`, each filter response is normalized by 1/16 to fit into the value range [0, 255].<br>
183  * If the target response data type is selected to be `uint16_t` no normalization will be applied.
184  * The border pixels are set to zero.
185  * @param source The source frame to which the Scharr filter will be applied, with `tSourceChannels` channels, must be valid
186  * @param target The target response frame receiving the maximal Scharr responses, with `tSourceChannels` channels, must be valid
187  * @param width The width of the frame in pixel, with range [3, infinity)
188  * @param height The height of the frame in pixel, with range [3, infinity)
189  * @param sourcePaddingElements Optional padding at the end of each source row in elements, with range [0, infinity)
190  * @param targetPaddingElements Optional padding at the end of each target row in elements, with range [0, infinity)
191  * @param worker Optional worker object to distribute the computational load
192  * @tparam TTarget The data type of the response values, either `uint8_t` or `uint16_t`
193  * @tparam tSourceChannels The number of channels of the source frame, with range [1, infinity)
194  */
195  template <typename TTarget, unsigned int tSourceChannels>
196  static inline void filterMaximumAbsolute8BitPerChannel(const uint8_t* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
197 
198  private:
199 
200  /**
201  * Applies the horizontal and vertical Scharr filter to one row of a source frame.
202  * @param sourceRow The row of the source frame, must be valid
203  * @param targetRow The row of the target response frame, must be valid
204  * @param width The width of the source and target frame in pixel, with range [3, infinity)
205  * @param height The height of the source and target frame in pixel, with range [3, infinity)
206  * @param rowIndex The index of the row to which the filter is applied, with range [0, height - 1]
207  * @param sourceStrideElements The number of elements between the start of two consecutive source rows, with range [width * tSourceChannels, infinity)
208  * @param targetStrideElements The number of elements between the start of two consecutive target rows, with range [width * tTargetChannels, infinity)
209  * @tparam TSource The data type of the source frame, must be `uint8_t`
210  * @tparam TTarget The data type oft he target response frame, must be `int8_t` or `int16_t`
211  * @tparam tSourceChannels The number of channels the source frame has, with range [1, infinity)
212  * @tparam tTargetChannels The number of channels the target frame has, must be `tSourceChannels * 2`
213  */
214  template <typename TSource, typename TTarget, unsigned int tSourceChannels, unsigned int tTargetChannels>
215  static void filterHorizontalVerticalRow(const TSource* sourceRow, TTarget* targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int targetStrideElements);
216 
217  /**
218  * Applies the diagonal Scharr filter to one row of a source frame.
219  * @param sourceRow The row of the source frame, must be valid
220  * @param targetRow The row of the target response frame, must be valid
221  * @param width The width of the source and target frame in pixel, with range [3, infinity)
222  * @param height The height of the source and target frame in pixel, with range [3, infinity)
223  * @param rowIndex The index of the row to which the filter is applied, with range [0, height - 1]
224  * @param sourceStrideElements The number of elements between the start of two consecutive source rows, with range [width * tSourceChannels, infinity)
225  * @param targetStrideElements The number of elements between the start of two consecutive target rows, with range [width * tTargetChannels, infinity)
226  * @tparam TSource The data type of the source frame, must be `uint8_t`
227  * @tparam TTarget The data type oft he target response frame, must be `int8_t` or `int16_t`
228  * @tparam tSourceChannels The number of channels the source frame has, with range [1, infinity)
229  * @tparam tTargetChannels The number of channels the target frame has, must be `tSourceChannels * 2`
230  */
231  template <typename TSource, typename TTarget, unsigned int tSourceChannels, unsigned int tTargetChannels>
232  static void filterDiagonalRow(const TSource* sourceRow, TTarget* targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int targetStrideElements);
233 
234  /**
235  * Applies the horizontal, vertical, and diagonal Scharr filter to one row of a source frame.
236  * @param sourceRow The row of the source frame, must be valid
237  * @param targetRow The row of the target response frame, must be valid
238  * @param width The width of the source and target frame in pixel, with range [3, infinity)
239  * @param height The height of the source and target frame in pixel, with range [3, infinity)
240  * @param rowIndex The index of the row to which the filter is applied, with range [0, height - 1]
241  * @param sourceStrideElements The number of elements between the start of two consecutive source rows, with range [width * tSourceChannels, infinity)
242  * @param targetStrideElements The number of elements between the start of two consecutive target rows, with range [width * tTargetChannels, infinity)
243  * @tparam TSource The data type of the source frame, must be `uint8_t`
244  * @tparam TTarget The data type oft he target response frame, must be `int8_t` or `int16_t`
245  * @tparam tSourceChannels The number of channels the source frame has, with range [1, infinity)
246  * @tparam tTargetChannels The number of channels the target frame has, must be `tSourceChannels * 2`
247  */
248  template <typename TSource, typename TTarget, unsigned int tSourceChannels, unsigned int tTargetChannels>
249  static void filterRow(const TSource* sourceRow, TTarget* targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int targetStrideElements);
250 
251  /**
252  * Applies the maximum of the absolute horizontal and vertical Scharr filter to one row of a source frame.
253  * @param sourceRow The row of the source frame, must be valid
254  * @param targetRow The row of the target response frame, must be valid
255  * @param width The width of the source and target frame in pixel, with range [3, infinity)
256  * @param height The height of the source and target frame in pixel, with range [3, infinity)
257  * @param rowIndex The index of the row to which the filter is applied, with range [0, height - 1]
258  * @param sourceStrideElements The number of elements between the start of two consecutive source rows, with range [width * tSourceChannels, infinity)
259  * @param targetStrideElements The number of elements between the start of two consecutive target rows, with range [width * tTargetChannels, infinity)
260  * @tparam TSource The data type of the source frame, must be `uint8_t`
261  * @tparam TTarget The data type oft he target response frame, must be `int8_t` or `int16_t`
262  * @tparam tSourceChannels The number of channels the source frame has, with range [1, infinity)
263  * @tparam tTargetChannels The number of channels the target frame has, must be `tSourceChannels * 2`
264  */
265  template <typename TSource, typename TTarget, unsigned int tSourceChannels, unsigned int tTargetChannels>
266  static void filterHorizontalVerticalMaximumAbsoluteRow(const TSource* sourceRow, TTarget* targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int targetStrideElements);
267 
268  /**
269  * Applies the maximum of the absolute horizontal, vertical, and diagonal Scharr filter to one row of a source frame.
270  * @param sourceRow The row of the source frame, must be valid
271  * @param targetRow The row of the target response frame, must be valid
272  * @param width The width of the source and target frame in pixel, with range [3, infinity)
273  * @param height The height of the source and target frame in pixel, with range [3, infinity)
274  * @param rowIndex The index of the row to which the filter is applied, with range [0, height - 1]
275  * @param sourceStrideElements The number of elements between the start of two consecutive source rows, with range [width * tSourceChannels, infinity)
276  * @param targetStrideElements The number of elements between the start of two consecutive target rows, with range [width * tTargetChannels, infinity)
277  * @tparam TSource The data type of the source frame, must be `uint8_t`
278  * @tparam TTarget The data type oft he target response frame, must be `int8_t` or `int16_t`
279  * @tparam tSourceChannels The number of channels the source frame has, with range [1, infinity)
280  * @tparam tTargetChannels The number of channels the target frame has, must be `tSourceChannels * 2`
281  */
282  template <typename TSource, typename TTarget, unsigned int tSourceChannels, unsigned int tTargetChannels>
283  static void filterMaximumAbsoluteRow(const TSource* sourceRow, TTarget* targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int targetStrideElements);
284 };
285 
286 template <typename TTarget, unsigned int tSourceChannels>
287 inline void FrameFilterScharr::filterHorizontalVertical8BitPerChannel(const uint8_t* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
288 {
289  static_assert(std::is_same<TTarget, int8_t>::value || std::is_same<TTarget, int16_t>::value, "Invalid target data type!");
290  static_assert(tSourceChannels >= 1u, "Invalid channel number!");
291 
292  ocean_assert(source != nullptr && target != nullptr);
293  ocean_assert(width >= 3u && height >= 3u);
294 
295  //using TSource = uint8_t;
296  constexpr unsigned int tTargetChannels = tSourceChannels * 2u;
297 
298  FrameChannels::applyRowOperator<uint8_t, TTarget, tSourceChannels, tTargetChannels>(source, target, width, height, sourcePaddingElements, targetPaddingElements, &filterHorizontalVerticalRow<uint8_t, TTarget, tSourceChannels, tTargetChannels>, worker);
299 }
300 
301 template <typename TTarget, unsigned int tSourceChannels>
302 inline void FrameFilterScharr::filterDiagonal8BitPerChannel(const uint8_t* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
303 {
304  static_assert(std::is_same<TTarget, int8_t>::value || std::is_same<TTarget, int16_t>::value, "Invalid target data type!");
305  static_assert(tSourceChannels >= 1u, "Invalid channel number!");
306 
307  ocean_assert(source != nullptr && target != nullptr);
308  ocean_assert(width >= 3u && height >= 3u);
309 
310  //using TSource = uint8_t;
311  constexpr unsigned int tTargetChannels = tSourceChannels * 2u;
312 
313  FrameChannels::applyRowOperator<uint8_t, TTarget, tSourceChannels, tTargetChannels>(source, target, width, height, sourcePaddingElements, targetPaddingElements, &filterDiagonalRow<uint8_t, TTarget, tSourceChannels, tTargetChannels>, worker);
314 }
315 
316 template <typename TTarget, unsigned int tSourceChannels>
317 inline void FrameFilterScharr::filter8BitPerChannel(const uint8_t* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
318 {
319  static_assert(std::is_same<TTarget, int8_t>::value || std::is_same<TTarget, int16_t>::value, "Invalid target data type!");
320  static_assert(tSourceChannels >= 1u, "Invalid channel number!");
321 
322  ocean_assert(source != nullptr && target != nullptr);
323  ocean_assert(width >= 3u && height >= 3u);
324 
325  //using TSource = uint8_t;
326  constexpr unsigned int tTargetChannels = tSourceChannels * 4u;
327 
328  FrameChannels::applyRowOperator<uint8_t, TTarget, tSourceChannels, tTargetChannels>(source, target, width, height, sourcePaddingElements, targetPaddingElements, &filterRow<uint8_t, TTarget, tSourceChannels, tTargetChannels>, worker);
329 }
330 
331 template <typename TTarget, unsigned int tSourceChannels>
332 inline void FrameFilterScharr::filterHorizontalVerticalMaximumAbsolute8BitPerChannel(const uint8_t* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
333 {
334  static_assert(std::is_same<TTarget, uint8_t>::value || std::is_same<TTarget, uint16_t>::value, "Invalid target data type!");
335  static_assert(tSourceChannels >= 1u, "Invalid channel number!");
336 
337  ocean_assert(source != nullptr && target != nullptr);
338  ocean_assert(width >= 3u && height >= 3u);
339 
340  //using TSource = uint8_t;
341  constexpr unsigned int tTargetChannels = tSourceChannels;
342 
343  FrameChannels::applyRowOperator<uint8_t, TTarget, tSourceChannels, tTargetChannels>(source, target, width, height, sourcePaddingElements, targetPaddingElements, &filterHorizontalVerticalMaximumAbsoluteRow<uint8_t, TTarget, tSourceChannels, tTargetChannels>, worker);
344 }
345 
346 template <typename TTarget, unsigned int tSourceChannels>
347 inline void FrameFilterScharr::filterMaximumAbsolute8BitPerChannel(const uint8_t* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
348 {
349  static_assert(std::is_same<TTarget, uint8_t>::value || std::is_same<TTarget, uint16_t>::value, "Invalid target data type!");
350  static_assert(tSourceChannels >= 1u, "Invalid channel number!");
351 
352  ocean_assert(source != nullptr && target != nullptr);
353  ocean_assert(width >= 3u && height >= 3u);
354 
355  //using TSource = uint8_t;
356  constexpr unsigned int tTargetChannels = tSourceChannels;
357 
358  FrameChannels::applyRowOperator<uint8_t, TTarget, tSourceChannels, tTargetChannels>(source, target, width, height, sourcePaddingElements, targetPaddingElements, &filterMaximumAbsoluteRow<uint8_t, TTarget, tSourceChannels, tTargetChannels>, worker);
359 }
360 
361 template <typename TSource, typename TTarget, unsigned int tSourceChannels, unsigned int tTargetChannels>
362 void FrameFilterScharr::filterHorizontalVerticalRow(const TSource* sourceRow, TTarget* targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int /*targetStrideElements*/)
363 {
364  static_assert(std::is_same<TSource, uint8_t>::value, "Invalid source data type!");
365  static_assert(std::is_same<TTarget, int8_t>::value || std::is_same<TTarget, int16_t>::value, "Invalid target data type!");
366 
367  static_assert(tSourceChannels >= 1u, "Invalid source channel number!");
368  static_assert(tTargetChannels == tSourceChannels * 2u, "Invalid target channel number!");
369 
370  ocean_assert(width >= 3u && height >= 3u);
371 
372  if (rowIndex == 0u || rowIndex == height - 1u)
373  {
374  // setting the first row and last row to zero
375 
376  memset(targetRow, 0, width * tTargetChannels * sizeof(TTarget));
377  return;
378  }
379 
380  const uint8_t* source0 = sourceRow - sourceStrideElements;
381  const uint8_t* source1 = sourceRow;
382  const uint8_t* source2 = sourceRow + sourceStrideElements;
383 
384  // setting first pixel to zero
385 
386  for (unsigned int n = 0u; n < tTargetChannels; ++n)
387  {
388  targetRow[n] = TTarget(0);
389  }
390 
391  targetRow += tTargetChannels;
392 
393  for (unsigned int x = 1u; x < width - 1u; ++x)
394  {
395  if constexpr (std::is_same<TTarget, int8_t>::value)
396  {
397  for (unsigned int n = 0u; n < tSourceChannels; ++n)
398  {
399  // 0 degree filter
400  // | -3 0 3 |
401  // | -10 0 10 | * 1/32
402  // | -3 0 3 |
403  *targetRow++ = TTarget((3 * (*(source0 + tSourceChannels * 2u) - *(source0) + *(source2 + tSourceChannels * 2u) - *(source2)) + 10 * (*(source1 + tSourceChannels * 2u) - *(source1))) / 32);
404 
405  // 90 degree filter
406  // | -3 -10 -3 |
407  // | 0 0 0 | * 1/32
408  // | 3 10 3 |
409  *targetRow++ = TTarget((3 * (*(source2) + *(source2 + tSourceChannels * 2u) - *(source0) - *(source0 + tSourceChannels * 2u)) + 10 * (*(source2 + tSourceChannels) - *(source0 + tSourceChannels))) / 32);
410 
411  ++source0;
412  ++source1;
413  ++source2;
414  }
415  }
416  else
417  {
418  ocean_assert((std::is_same<TTarget, int16_t>::value));
419 
420  for (unsigned int n = 0u; n < tSourceChannels; ++n)
421  {
422  // 0 degree filter
423  // | -3 0 3 |
424  // | -10 0 10 |
425  // | -3 0 3 |
426  *targetRow++ = TTarget(3 * (*(source0 + tSourceChannels * 2u) - *(source0) + *(source2 + tSourceChannels * 2u) - *(source2)) + 10 * (*(source1 + tSourceChannels * 2u) - *(source1)));
427 
428  // 90 degree filter
429  // | -3 -10 -3 |
430  // | 0 0 0 |
431  // | 3 10 3 |
432  *targetRow++ = TTarget(3 * (*(source2) + *(source2 + tSourceChannels * 2u) - *(source0) - *(source0 + tSourceChannels * 2u)) + 10 * (*(source2 + tSourceChannels) - *(source0 + tSourceChannels)));
433 
434  ++source0;
435  ++source1;
436  ++source2;
437  }
438  }
439  }
440 
441  // setting last pixel to zero
442  for (unsigned int n = 0u; n < tTargetChannels; ++n)
443  {
444  targetRow[n] = TTarget(0);
445  }
446 }
447 
448 template <typename TSource, typename TTarget, unsigned int tSourceChannels, unsigned int tTargetChannels>
449 void FrameFilterScharr::filterDiagonalRow(const TSource* sourceRow, TTarget* targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int /*targetStrideElements*/)
450 {
451  static_assert(std::is_same<TSource, uint8_t>::value, "Invalid source data type!");
452  static_assert(std::is_same<TTarget, int8_t>::value || std::is_same<TTarget, int16_t>::value, "Invalid target data type!");
453 
454  static_assert(tSourceChannels >= 1u, "Invalid source channel number!");
455  static_assert(tTargetChannels == tSourceChannels * 2u, "Invalid target channel number!");
456 
457  ocean_assert(width >= 3u && height >= 3u);
458 
459  if (rowIndex == 0u || rowIndex == height - 1u)
460  {
461  // setting the first row and last row to zero
462 
463  memset(targetRow, 0, width * tTargetChannels * sizeof(TTarget));
464  return;
465  }
466 
467  const uint8_t* source0 = sourceRow - sourceStrideElements;
468  const uint8_t* source1 = sourceRow;
469  const uint8_t* source2 = sourceRow + sourceStrideElements;
470 
471  // setting first pixel to zero
472 
473  for (unsigned int n = 0u; n < tTargetChannels; ++n)
474  {
475  targetRow[n] = TTarget(0);
476  }
477 
478  targetRow += tTargetChannels;
479 
480  for (unsigned int x = 1u; x < width - 1u; ++x)
481  {
482  if constexpr (std::is_same<TTarget, int8_t>::value)
483  {
484  for (unsigned int n = 0u; n < tSourceChannels; ++n)
485  {
486  // 45 degree filter
487  // | -10 -3 0 |
488  // | -3 0 3 | * 1/32
489  // | 0 3 10 |
490  *targetRow++ = TTarget((3 * (*(source1 + tSourceChannels * 2u) + *(source2 + tSourceChannels) - *(source0 + tSourceChannels) - *(source1)) + 10 * (*(source2 + tSourceChannels * 2u) - *(source0))) / 32);
491 
492  // 135 degree filter
493  // | 0 -3 -10 |
494  // | 3 0 -3 | * 1/32
495  // | 10 3 0 |
496  *targetRow++ = TTarget((3 * (*(source1) + *(source2 + tSourceChannels) - *(source0 + tSourceChannels) - *(source1 + tSourceChannels * 2u)) + 10 * (*(source2) - *(source0 + tSourceChannels * 2u))) / 32);
497 
498  ++source0;
499  ++source1;
500  ++source2;
501  }
502  }
503  else
504  {
505  ocean_assert((std::is_same<TTarget, int16_t>::value));
506 
507  for (unsigned int n = 0u; n < tSourceChannels; ++n)
508  {
509  // 45 degree filter
510  // | -10 -3 0 |
511  // | -3 0 3 | * 1/32
512  // | 0 3 10 |
513  *targetRow++ = TTarget(3 * (*(source1 + tSourceChannels * 2u) + *(source2 + tSourceChannels) - *(source0 + tSourceChannels) - *(source1)) + 10 * (*(source2 + tSourceChannels * 2u) - *(source0)));
514 
515  // 135 degree filter
516  // | 0 -3 -10 |
517  // | 3 0 -3 | * 1/32
518  // | 10 3 0 |
519  *targetRow++ = TTarget(3 * (*(source1) + *(source2 + tSourceChannels) - *(source0 + tSourceChannels) - *(source1 + tSourceChannels * 2u)) + 10 * (*(source2) - *(source0 + tSourceChannels * 2u)));
520 
521  ++source0;
522  ++source1;
523  ++source2;
524  }
525  }
526  }
527 
528  // setting last pixel to zero
529  for (unsigned int n = 0u; n < tTargetChannels; ++n)
530  {
531  targetRow[n] = TTarget(0);
532  }
533 }
534 
535 template <typename TSource, typename TTarget, unsigned int tSourceChannels, unsigned int tTargetChannels>
536 void FrameFilterScharr::filterRow(const TSource* sourceRow, TTarget* targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int /*targetStrideElements*/)
537 {
538  static_assert(std::is_same<TSource, uint8_t>::value, "Invalid source data type!");
539  static_assert(std::is_same<TTarget, int8_t>::value || std::is_same<TTarget, int16_t>::value, "Invalid target data type!");
540 
541  static_assert(tSourceChannels >= 1u, "Invalid source channel number!");
542  static_assert(tTargetChannels == tSourceChannels * 4u, "Invalid target channel number!");
543 
544  ocean_assert(width >= 3u && height >= 3u);
545 
546  if (rowIndex == 0u || rowIndex == height - 1u)
547  {
548  // setting the first row and last row to zero
549 
550  memset(targetRow, 0, width * tTargetChannels * sizeof(TTarget));
551  return;
552  }
553 
554  const uint8_t* source0 = sourceRow - sourceStrideElements;
555  const uint8_t* source1 = sourceRow;
556  const uint8_t* source2 = sourceRow + sourceStrideElements;
557 
558  // setting first pixel to zero
559 
560  for (unsigned int n = 0u; n < tTargetChannels; ++n)
561  {
562  targetRow[n] = TTarget(0);
563  }
564 
565  targetRow += tTargetChannels;
566 
567  for (unsigned int x = 1u; x < width - 1u; ++x)
568  {
569  if constexpr (std::is_same<TTarget, int8_t>::value)
570  {
571  for (unsigned int n = 0u; n < tSourceChannels; ++n)
572  {
573  // 0 degree filter
574  // | -3 0 3 |
575  // | -10 0 10 | * 1/32
576  // | -3 0 3 |
577  *targetRow++ = TTarget((3 * (*(source0 + tSourceChannels * 2u) - *(source0) + *(source2 + tSourceChannels * 2u) - *(source2)) + 10 * (*(source1 + tSourceChannels * 2u) - *(source1))) / 32);
578 
579  // 90 degree filter
580  // | -3 -10 -3 |
581  // | 0 0 0 | * 1/32
582  // | 3 10 3 |
583  *targetRow++ = TTarget((3 * (*(source2) + *(source2 + tSourceChannels * 2u) - *(source0) - *(source0 + tSourceChannels * 2u)) + 10 * (*(source2 + tSourceChannels) - *(source0 + tSourceChannels))) / 32);
584 
585  // 45 degree filter
586  // | -10 -3 0 |
587  // | -3 0 3 | * 1/32
588  // | 0 3 10 |
589  *targetRow++ = TTarget((3 * (*(source1 + tSourceChannels * 2u) + *(source2 + tSourceChannels) - *(source0 + tSourceChannels) - *(source1)) + 10 * (*(source2 + tSourceChannels * 2u) - *(source0))) / 32);
590 
591  // 135 degree filter
592  // | 0 -3 -10 |
593  // | 3 0 -3 | * 1/32
594  // | 10 3 0 |
595  *targetRow++ = TTarget((3 * (*(source1) + *(source2 + tSourceChannels) - *(source0 + tSourceChannels) - *(source1 + tSourceChannels * 2u)) + 10 * (*(source2) - *(source0 + tSourceChannels * 2u))) / 32);
596 
597  ++source0;
598  ++source1;
599  ++source2;
600  }
601  }
602  else
603  {
604  ocean_assert((std::is_same<TTarget, int16_t>::value));
605 
606  for (unsigned int n = 0u; n < tSourceChannels; ++n)
607  {
608  // 0 degree filter
609  // | -3 0 3 |
610  // | -10 0 10 |
611  // | -3 0 3 |
612  *targetRow++ = TTarget(3 * (*(source0 + tSourceChannels * 2u) - *(source0) + *(source2 + tSourceChannels * 2u) - *(source2)) + 10 * (*(source1 + tSourceChannels * 2u) - *(source1)));
613 
614  // 90 degree filter
615  // | -3 -10 -3 |
616  // | 0 0 0 |
617  // | 3 10 3 |
618  *targetRow++ = TTarget(3 * (*(source2) + *(source2 + tSourceChannels * 2u) - *(source0) - *(source0 + tSourceChannels * 2u)) + 10 * (*(source2 + tSourceChannels) - *(source0 + tSourceChannels)));
619 
620  // 45 degree filter
621  // | -10 -3 0 |
622  // | -3 0 3 | * 1/32
623  // | 0 3 10 |
624  *targetRow++ = TTarget(3 * (*(source1 + tSourceChannels * 2u) + *(source2 + tSourceChannels) - *(source0 + tSourceChannels) - *(source1)) + 10 * (*(source2 + tSourceChannels * 2u) - *(source0)));
625 
626  // 135 degree filter
627  // | 0 -3 -10 |
628  // | 3 0 -3 | * 1/32
629  // | 10 3 0 |
630  *targetRow++ = TTarget(3 * (*(source1) + *(source2 + tSourceChannels) - *(source0 + tSourceChannels) - *(source1 + tSourceChannels * 2u)) + 10 * (*(source2) - *(source0 + tSourceChannels * 2u)));
631 
632  ++source0;
633  ++source1;
634  ++source2;
635  }
636  }
637  }
638 
639  // setting last pixel to zero
640  for (unsigned int n = 0u; n < tTargetChannels; ++n)
641  {
642  targetRow[n] = TTarget(0);
643  }
644 }
645 
646 template <typename TSource, typename TTarget, unsigned int tSourceChannels, unsigned int tTargetChannels>
647 void FrameFilterScharr::filterHorizontalVerticalMaximumAbsoluteRow(const TSource* sourceRow, TTarget* targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int /*targetStrideElements*/)
648 {
649  static_assert(std::is_same<TSource, uint8_t>::value, "Invalid source data type!");
650  static_assert(std::is_same<TTarget, uint8_t>::value || std::is_same<TTarget, uint16_t>::value, "Invalid target data type!");
651 
652  static_assert(tSourceChannels >= 1u, "Invalid source channel number!");
653  static_assert(tTargetChannels == tSourceChannels, "Invalid target channel number!");
654 
655  ocean_assert(width >= 3u && height >= 3u);
656 
657  if (rowIndex == 0u || rowIndex == height - 1u)
658  {
659  // setting the first row and last row to zero
660 
661  memset(targetRow, 0, width * tTargetChannels * sizeof(TTarget));
662  return;
663  }
664 
665  const uint8_t* source0 = sourceRow - sourceStrideElements;
666  const uint8_t* source1 = sourceRow;
667  const uint8_t* source2 = sourceRow + sourceStrideElements;
668 
669  // setting first pixel to zero
670 
671  for (unsigned int n = 0u; n < tTargetChannels; ++n)
672  {
673  targetRow[n] = TTarget(0);
674  }
675 
676  targetRow += tTargetChannels;
677 
678  for (unsigned int x = 1u; x < width - 1u; ++x)
679  {
680  if constexpr (std::is_same<TTarget, uint8_t>::value)
681  {
682  for (unsigned int n = 0u; n < tSourceChannels; ++n)
683  {
684  // 0 degree filter
685  // | -3 0 3 |
686  // | -10 0 10 | * 1/32
687  // | -3 0 3 |
688  *targetRow++ = TTarget((max(abs(int16_t(3 * (*(source0 + tSourceChannels * 2u) - *(source0) + *(source2 + tSourceChannels * 2u) - *(source2)) + 10 * (*(source1 + tSourceChannels * 2u) - *(source1)))),
689 
690  // 90 degree filter
691  // | -3 -10 -3 |
692  // | 0 0 0 | * 1/32
693  // | 3 10 3 |
694  abs(int16_t(3 * (*(source2) + *(source2 + tSourceChannels * 2u) - *(source0) - *(source0 + tSourceChannels * 2u)) + 10 * (*(source2 + tSourceChannels) - *(source0 + tSourceChannels))))) + 8u) / 16u);
695 
696  ++source0;
697  ++source1;
698  ++source2;
699  }
700  }
701  else
702  {
703  ocean_assert((std::is_same<TTarget, uint16_t>::value));
704 
705  for (unsigned int n = 0u; n < tSourceChannels; ++n)
706  {
707  // 0 degree filter
708  // | -3 0 3 |
709  // | -10 0 10 | * 1/32
710  // | -3 0 3 |
711  *targetRow++ = TTarget(max(abs(int16_t(3 * (*(source0 + tSourceChannels * 2u) - *(source0) + *(source2 + tSourceChannels * 2u) - *(source2)) + 10 * (*(source1 + tSourceChannels * 2u) - *(source1)))),
712 
713  // 90 degree filter
714  // | -3 -10 -3 |
715  // | 0 0 0 | * 1/32
716  // | 3 10 3 |
717  abs(int16_t(3 * (*(source2) + *(source2 + tSourceChannels * 2u) - *(source0) - *(source0 + tSourceChannels * 2u)) + 10 * (*(source2 + tSourceChannels) - *(source0 + tSourceChannels))))));
718 
719  ++source0;
720  ++source1;
721  ++source2;
722  }
723  }
724  }
725 
726  // setting last pixel to zero
727  for (unsigned int n = 0u; n < tTargetChannels; ++n)
728  {
729  targetRow[n] = TTarget(0);
730  }
731 }
732 
733 template <typename TSource, typename TTarget, unsigned int tSourceChannels, unsigned int tTargetChannels>
734 void FrameFilterScharr::filterMaximumAbsoluteRow(const TSource* sourceRow, TTarget* targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int /*targetStrideElements*/)
735 {
736  static_assert(std::is_same<TSource, uint8_t>::value, "Invalid source data type!");
737  static_assert(std::is_same<TTarget, uint8_t>::value || std::is_same<TTarget, uint16_t>::value, "Invalid target data type!");
738 
739  static_assert(tSourceChannels >= 1u, "Invalid source channel number!");
740  static_assert(tTargetChannels == tSourceChannels, "Invalid target channel number!");
741 
742  ocean_assert(width >= 3u && height >= 3u);
743 
744  if (rowIndex == 0u || rowIndex == height - 1u)
745  {
746  // setting the first row and last row to zero
747 
748  memset(targetRow, 0, width * tTargetChannels * sizeof(TTarget));
749  return;
750  }
751 
752  const uint8_t* source0 = sourceRow - sourceStrideElements;
753  const uint8_t* source1 = sourceRow;
754  const uint8_t* source2 = sourceRow + sourceStrideElements;
755 
756  // setting first pixel to zero
757 
758  for (unsigned int n = 0u; n < tTargetChannels; ++n)
759  {
760  targetRow[n] = TTarget(0);
761  }
762 
763  targetRow += tTargetChannels;
764 
765  for (unsigned int x = 1u; x < width - 1u; ++x)
766  {
767  if constexpr (std::is_same<TTarget, uint8_t>::value)
768  {
769  for (unsigned int n = 0u; n < tSourceChannels; ++n)
770  {
771  // 0 degree filter
772  // | -3 0 3 |
773  // | -10 0 10 | * 1/32
774  // | -3 0 3 |
775  *targetRow++ = TTarget((max(max(abs(int16_t(3 * (*(source0 + tSourceChannels * 2u) - *(source0) + *(source2 + tSourceChannels * 2u) - *(source2)) + 10 * (*(source1 + tSourceChannels * 2u) - *(source1)))),
776 
777  // 90 degree filter
778  // | -3 -10 -3 |
779  // | 0 0 0 | * 1/32
780  // | 3 10 3 |
781  abs(int16_t(3 * (*(source2) + *(source2 + tSourceChannels * 2u) - *(source0) - *(source0 + tSourceChannels * 2u)) + 10 * (*(source2 + tSourceChannels) - *(source0 + tSourceChannels))))),
782 
783  // 45 degree filter
784  // | -10 -3 0 |
785  // | -3 0 3 | * 1/32
786  // | 0 3 10 |
787  max(abs(int16_t(3 * (*(source1 + tSourceChannels * 2u) + *(source2 + tSourceChannels) - *(source0 + tSourceChannels) - *(source1)) + 10 * (*(source2 + tSourceChannels * 2u) - *(source0)))),
788 
789  // 135 degree filter
790  // | 0 -3 -10 |
791  // | 3 0 -3 | * 1/32
792  // | 10 3 0 |
793  abs(int16_t(3 * (*(source1) + *(source2 + tSourceChannels) - *(source0 + tSourceChannels) - *(source1 + tSourceChannels * 2u)) + 10 * (*(source2) - *(source0 + tSourceChannels * 2u)))))) + 8u) / 16u);
794 
795  ++source0;
796  ++source1;
797  ++source2;
798  }
799  }
800  else
801  {
802  ocean_assert((std::is_same<TTarget, uint16_t>::value));
803 
804  for (unsigned int n = 0u; n < tSourceChannels; ++n)
805  {
806  // 0 degree filter
807  // | -3 0 3 |
808  // | -10 0 10 | * 1/32
809  // | -3 0 3 |
810  *targetRow++ = TTarget(max(max(abs(int16_t(3 * (*(source0 + tSourceChannels * 2u) - *(source0) + *(source2 + tSourceChannels * 2u) - *(source2)) + 10 * (*(source1 + tSourceChannels * 2u) - *(source1)))),
811 
812  // 90 degree filter
813  // | -3 -10 -3 |
814  // | 0 0 0 | * 1/32
815  // | 3 10 3 |
816  abs(int16_t(3 * (*(source2) + *(source2 + tSourceChannels * 2u) - *(source0) - *(source0 + tSourceChannels * 2u)) + 10 * (*(source2 + tSourceChannels) - *(source0 + tSourceChannels))))),
817 
818  // 45 degree filter
819  // | -10 -3 0 |
820  // | -3 0 3 | * 1/32
821  // | 0 3 10 |
822  max(abs(int16_t(3 * (*(source1 + tSourceChannels * 2u) + *(source2 + tSourceChannels) - *(source0 + tSourceChannels) - *(source1)) + 10 * (*(source2 + tSourceChannels * 2u) - *(source0)))),
823 
824  // 135 degree filter
825  // | 0 -3 -10 |
826  // | 3 0 -3 | * 1/32
827  // | 10 3 0 |
828  abs(int16_t(3 * (*(source1) + *(source2 + tSourceChannels) - *(source0 + tSourceChannels) - *(source1 + tSourceChannels * 2u)) + 10 * (*(source2) - *(source0 + tSourceChannels * 2u)))))));
829 
830  ++source0;
831  ++source1;
832  ++source2;
833  }
834  }
835  }
836 
837  // setting last pixel to zero
838  for (unsigned int n = 0u; n < tTargetChannels; ++n)
839  {
840  targetRow[n] = TTarget(0);
841  }
842 }
843 
844 }
845 
846 }
847 
848 #endif // META_OCEAN_CV_FRAME_FILTER_SCHARR_H
The following comfort class provides comfortable functions simplifying prototyping applications but a...
Definition: FrameFilterScharr.h:52
static bool filterDiagonal(const Frame &source, Frame &target, Worker *worker=nullptr)
Diagonal (45 and 135 degree) Scharr filer for images.
static bool filterHorizontalVerticalMaximumAbsolute(const Frame &source, Frame &target, Worker *worker=nullptr)
Determines the maximum of the absolute horizontal and vertical Scharr filter.
static bool filter(const Frame &source, Frame &target, Worker *worker=nullptr)
Horizontal, vertical, and diagonal Scharr filer for images.
static bool filterMaximumAbsolute(const Frame &source, Frame &target, Worker *worker=nullptr)
Determines the maximum of the absolute horizontal, vertical, and diagonal Scharr filter.
static bool filterHorizontalVertical(const Frame &source, Frame &target, Worker *worker=nullptr)
Horizontal and vertical Scharr filer for images.
This class implements a Scharr filter.
Definition: FrameFilterScharr.h:43
static void filterHorizontalVerticalRow(const TSource *sourceRow, TTarget *targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int targetStrideElements)
Applies the horizontal and vertical Scharr filter to one row of a source frame.
Definition: FrameFilterScharr.h:362
static void filterHorizontalVertical8BitPerChannel(const uint8_t *source, TTarget *target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Horizontal and vertical Scharr filer for images.
Definition: FrameFilterScharr.h:287
static void filter8BitPerChannel(const uint8_t *source, TTarget *target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Horizontal, vertical, and diagonal Scharr filer for images.
Definition: FrameFilterScharr.h:317
static void filterMaximumAbsolute8BitPerChannel(const uint8_t *source, TTarget *target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Determines the maximum of the absolute horizontal, vertical, and diagonal Scharr filter.
Definition: FrameFilterScharr.h:347
static void filterHorizontalVerticalMaximumAbsoluteRow(const TSource *sourceRow, TTarget *targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int targetStrideElements)
Applies the maximum of the absolute horizontal and vertical Scharr filter to one row of a source fram...
Definition: FrameFilterScharr.h:647
static void filterDiagonalRow(const TSource *sourceRow, TTarget *targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int targetStrideElements)
Applies the diagonal Scharr filter to one row of a source frame.
Definition: FrameFilterScharr.h:449
static void filterRow(const TSource *sourceRow, TTarget *targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int targetStrideElements)
Applies the horizontal, vertical, and diagonal Scharr filter to one row of a source frame.
Definition: FrameFilterScharr.h:536
static void filterHorizontalVerticalMaximumAbsolute8BitPerChannel(const uint8_t *source, TTarget *target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Determines the maximum of the absolute horizontal and vertical Scharr filter.
Definition: FrameFilterScharr.h:332
static void filterDiagonal8BitPerChannel(const uint8_t *source, TTarget *target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Diagonal (45 and 135 degree) Scharr filer for images.
Definition: FrameFilterScharr.h:302
static void filterMaximumAbsoluteRow(const TSource *sourceRow, TTarget *targetRow, const unsigned int width, const unsigned int height, unsigned int rowIndex, const unsigned int sourceStrideElements, const unsigned int targetStrideElements)
Applies the maximum of the absolute horizontal, vertical, and diagonal Scharr filter to one row of a ...
Definition: FrameFilterScharr.h:734
This class implements Ocean's image class.
Definition: Frame.h:1792
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