Ocean
Loading...
Searching...
No Matches
FrameFilterMedian.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_MEDIAN_H
9#define META_OCEAN_CV_FRAME_FILTER_MEDIAN_H
10
11#include "ocean/cv/CV.h"
13
14#include "ocean/base/Frame.h"
15#include "ocean/base/Median.h"
16#include "ocean/base/Memory.h"
17#include "ocean/base/Worker.h"
18
19#include "ocean/math/Numeric.h"
20
21namespace Ocean
22{
23
24namespace CV
25{
26
27/**
28 * This class implements a median filter.
29 * @ingroup cv
30 */
31class OCEAN_CV_EXPORT FrameFilterMedian : protected FrameFilterSorted
32{
33 public:
34
35 /**
36 * The following comfort class provides comfortable functions simplifying prototyping applications but also increasing binary size of the resulting applications.
37 * Best practice is to avoid using these functions if binary size matters,<br>
38 * as for every comfort function a corresponding function exists with specialized functionality not increasing binary size significantly.<br>
39 */
40 class OCEAN_CV_EXPORT Comfort
41 {
42 public:
43
44 /**
45 * Filters a frame with a median filter with arbitrary size (a square patch).
46 * @param source The source image to be filtered, must be valid
47 * @param target The target frame with same size and pixel format receiving the filtered result, must be valid
48 * @param filterSize Size of the filter edge in pixel, must be odd with range [1, infinity)
49 * @param worker Optional worker object to distribute the computation
50 * @return True, if succeeded
51 */
52 static bool filter(const Frame& source, Frame& target, const unsigned int filterSize, Worker* worker);
53
54 /**
55 * Filters a frame with a median filter with arbitrary size (a square patch).
56 * @param frame The image to be filtered, must be valid
57 * @param filterSize Size of the filter edge in pixel, must be odd with range [1, infinity)
58 * @param worker Optional worker object to distribute the computation
59 * @return True, if succeeded
60 */
61 static bool filter(Frame& frame, const unsigned int filterSize, Worker* worker);
62 };
63
64 public:
65
66 /**
67 * Filters a frame with a median filter with arbitrary size (a square patch).
68 * @param source The source image to be filtered, must be valid
69 * @param target The target frame with same size and pixel format receiving the filtered result, must be valid
70 * @param width The width of the input frame in pixel, with range [filterSize / 2, infinity)
71 * @param height The height of the input frame in pixel, with range [filterSize / 2, infinity)
72 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
73 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
74 * @param filterSize Size of the filter edge in pixel, must be odd with range [1, infinity)
75 * @param worker Optional worker object to distribute the computation
76 * @tparam T Data type of the data elements
77 * @tparam tChannels Number of data channels, with range [1, infinity)
78 */
79 template <typename T, unsigned int tChannels>
80 static void filter(const T* source, T* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int filterSize, Worker* worker = nullptr);
81
82 /**
83 * Filters a frame with a median filter with arbitrary size (a square patch).
84 * @param frame The image to be filtered, must be valid
85 * @param width The width of the input frame in pixel, with range [filterSize / 2, infinity)
86 * @param height The height of the input frame in pixel, with range [filterSize / 2, infinity)
87 * @param framePaddingElements The number of padding elements at the end of each frame row, in elements, with range [0, infinity)
88 * @param filterSize Size of the filter edge in pixel, must be odd with range [1, infinity)
89 * @param worker Optional worker object to distribute the computation
90 * @tparam T Data type of the data elements
91 * @tparam tChannels Number of data channels, with range [1, infinity)
92 */
93 template <typename T, unsigned int tChannels>
94 static void filter(T* frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const unsigned int filterSize, Worker* worker = nullptr);
95
96 protected:
97
98 /**
99 * Filters a subset of an integer frame with a median filter with arbitrary size.
100 * @param source The source image to be filtered, must be valid
101 * @param target The target frame with same size and pixel format receiving the filtered result, must be valid
102 * @param width The width of the input frame in pixel, with range [filterSize / 2, infinity)
103 * @param height The height of the input frame in pixel, with range [filterSize / 2, infinity)
104 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
105 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
106 * @param filterSize Size of the filter edge in pixel, must be odd with range [1, infinity)
107 * @param firstRow First row to be handled, with range [0, height - 1]
108 * @param numberRows Number of rows to be handled, with range [1, height - firstRow]
109 * @tparam T Data type of the data elements, must be an integer data type
110 * @tparam tChannels Number of data channels, with range [1, infinity)
111 */
112 template <typename T, unsigned int tChannels, typename THistogram>
113 static void filterIntegerSubset(const T* source, T* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int filterSize, const unsigned int firstRow, const unsigned int numberRows);
114
115 /**
116 * Filters a subset of a floating point frame with a median filter with arbitrary size.
117 * @param source The source image to be filtered, must be valid
118 * @param target The target frame with same size and pixel format receiving the filtered result, must be valid
119 * @param width The width of the input frame in pixel, with range [filterSize / 2, infinity)
120 * @param height The height of the input frame in pixel, with range [filterSize / 2, infinity)
121 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
122 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
123 * @param filterSize Size of the filter edge in pixel, must be odd with range [1, infinity)
124 * @param firstRow First row to be handled, with range [0, height - 1]
125 * @param numberRows Number of rows to be handled, with range [1, height - firstRow]
126 * @tparam T Data type of the data elements, must be a valid data type
127 * @tparam tChannels Number of data channels, with range [1, infinity)
128 */
129 template <typename T, unsigned int tChannels>
130 static void filterFloatSubset(const T* source, T* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int filterSize, const unsigned int firstRow, const unsigned int numberRows);
131};
132
133template <typename T, unsigned int tChannels>
134void FrameFilterMedian::filter(const T* source, T* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int filterSize, Worker* worker)
135{
136 static_assert(tChannels != 0u, "Invalid channel number!");
137
138 ocean_assert(source != nullptr && target != nullptr && source != target);
139 ocean_assert(filterSize / 2u <= width && filterSize / 2u <= height);
140
141 if constexpr (std::is_floating_point<T>::value || sizeof(T) > sizeof(uint16_t))
142 {
143 if (worker)
144 {
145 worker->executeFunction(Worker::Function::createStatic(&filterFloatSubset<T, tChannels>, source, target, width, height, sourcePaddingElements, targetPaddingElements, filterSize, 0u, 0u), 0u, height, 7u, 8u, 20u);
146 }
147 else
148 {
149 filterFloatSubset<T, tChannels>(source, target, width, height, sourcePaddingElements, targetPaddingElements, filterSize, 0u, height);
150 }
151 }
152 else
153 {
154 ocean_assert(uint64_t(filterSize * filterSize) < uint64_t(NumericT<uint16_t>::maxValue()));
155
156 constexpr size_t histogramElements = 1 << sizeof(T) * 8;
157
158 ocean_assert(sizeof(T) != sizeof(uint8_t) || histogramElements == 256);
159 ocean_assert(sizeof(T) != sizeof(uint16_t) || histogramElements == 65536);
160
162
163 if (worker)
164 {
165 worker->executeFunction(Worker::Function::createStatic(&filterIntegerSubset<T, tChannels, Histogram>, source, target, width, height, sourcePaddingElements, targetPaddingElements, filterSize, 0u, 0u), 0u, height, 7u, 8u, 20u);
166 }
167 else
168 {
169 filterIntegerSubset<T, tChannels, Histogram>(source, target, width, height, sourcePaddingElements, targetPaddingElements, filterSize, 0u, height);
170 }
171 }
172}
173
174template <typename T, unsigned int tChannels>
175void FrameFilterMedian::filter(T* frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const unsigned int filterSize, Worker* worker)
176{
177 static_assert(tChannels != 0u, "Invalid channel number!");
178
179 ocean_assert(frame != nullptr);
180 ocean_assert(filterSize / 2u <= width && filterSize / 2u <= height);
181
182 Memory memory(width * height * sizeof(T) * tChannels);
183
184 constexpr unsigned int memoryPaddingElements = 0u;
185 filter<T, tChannels>(frame, memory.data<T>(), width, height, framePaddingElements, memoryPaddingElements, filterSize, worker);
186
187 if (framePaddingElements == 0u)
188 {
189 memcpy(frame, memory.data(), memory.size());
190 }
191 else
192 {
193 const T* memoryData = memory.data<T>();
194
195 for (unsigned int y = 0u; y < height; ++y)
196 {
197 memcpy(frame, memoryData, width * tChannels * sizeof(T));
198
199 frame += width * tChannels + framePaddingElements;
200 memoryData += width * tChannels + memoryPaddingElements;
201 }
202 }
203}
204
205template <typename T, unsigned int tChannels, typename THistogram>
206void FrameFilterMedian::filterIntegerSubset(const T* source, T* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int filterSize, const unsigned int firstRow, const unsigned int numberRows)
207{
208 static_assert(!std::is_floating_point<T>::value, "Invalid data type!");
209 static_assert(tChannels != 0u, "Invalid channel number");
210
211 ocean_assert(source != nullptr && target != nullptr);
212
213 ocean_assert(filterSize >= 3u && filterSize % 2u == 1u);
214
215 const unsigned int filterSize_2 = filterSize / 2u;
216 ocean_assert(filterSize_2 <= width && filterSize_2 <= height);
217
218 const unsigned int endRow = firstRow + numberRows;
219
220 const unsigned int sourceStrideElements = width * tChannels + sourcePaddingElements;
221 const unsigned int targetStrideElements = width * tChannels + targetPaddingElements;
222
223 THistogram medianHistograms[tChannels];
224
225 // fill initial histogram
226
227 for (unsigned int y = clampLower(firstRow, filterSize_2); y <= clampUpper(firstRow, filterSize_2, height); ++y)
228 {
229 const T* sourceRow = source + y * sourceStrideElements;
230
231 for (unsigned int x = 0u; x <= filterSize_2; ++x)
232 {
233 for (unsigned int n = 0u; n < tChannels; ++n)
234 {
235 medianHistograms[n].pushValue(*sourceRow++);
236 }
237 }
238 }
239
240 ocean_assert(medianHistograms[0].values() >= (filterSize_2 + 1u) * (filterSize_2 + 1u));
241 ocean_assert(medianHistograms[0].values() <= (filterSize_2 + 1u) * filterSize);
242
243 THistogram previousMedianHistograms[tChannels];
244
245 for (unsigned int y = firstRow; y < endRow; ++y)
246 {
247 T* targetRow = target + y * targetStrideElements;
248
249 // making a copy which we can use when we start with the next row
250 for (unsigned int n = 0u; n < tChannels; ++n)
251 {
252 previousMedianHistograms[n] = medianHistograms[n];
253 }
254
255 for (unsigned int x = 0u; x < width; ++x)
256 {
257 for (unsigned int n = 0u; n < tChannels; ++n)
258 {
259 ocean_assert(medianHistograms[n]);
260 *targetRow++ = medianHistograms[n].medianValue();
261 }
262
263 if (x != width - 1u)
264 {
265 ocean_assert(x + 1u < width);
266
267 // horizontal histogram update
268
269 for (unsigned int yy = clampLower(y, filterSize_2); yy <= clampUpper(y, filterSize_2, height); ++yy)
270 {
271 const T* sourceRow = source + yy * sourceStrideElements;
272
273 const unsigned int xxLeft = x - filterSize_2;
274 const unsigned int xxRight = x + filterSize_2 + 1u;
275
276 if (xxLeft < width) // handling negative cases: int(xxLeft) < 0
277 {
278 for (unsigned int n = 0u; n < tChannels; ++n)
279 {
280 const T popValue = sourceRow[xxLeft * tChannels + n];
281
282 ocean_assert(medianHistograms[n].hasValue(popValue));
283 medianHistograms[n].popValue(popValue);
284 }
285 }
286
287 if (xxRight < width)
288 {
289 for (unsigned int n = 0u; n < tChannels; ++n)
290 {
291 const T pushValue = sourceRow[xxRight * tChannels + n];
292
293 medianHistograms[n].pushValue(pushValue);
294 }
295 }
296 }
297 }
298
299 ocean_assert(medianHistograms[0].values() <= filterSize * filterSize);
300 }
301
302 if (y != endRow - 1u)
303 {
304 ocean_assert(y + 1u < endRow);
305
306 // vertical histogram update at the beginning of the row
307
308 for (unsigned int n = 0u; n < tChannels; ++n)
309 {
310 medianHistograms[n] = previousMedianHistograms[n];
311 }
312
313 const unsigned int yyTop = y - filterSize_2;
314 const unsigned int yyBottom = y + filterSize_2 + 1u;
315
316 if (yyTop < height) // handling negative cases: int(yyTop) < 0
317 {
318 const T* sourceRow = source + yyTop * sourceStrideElements;
319
320 for (unsigned int x = 0u; x <= filterSize_2; ++x)
321 {
322 for (unsigned int n = 0u; n < tChannels; ++n)
323 {
324 const T popValue = sourceRow[x * tChannels + n];
325
326 ocean_assert(medianHistograms[n].hasValue(popValue));
327 medianHistograms[n].popValue(popValue);
328 }
329 }
330 }
331
332 if (yyBottom < height)
333 {
334 const T* sourceRow = source + yyBottom * sourceStrideElements;
335
336 for (unsigned int x = 0u; x <= filterSize_2; ++x)
337 {
338 for (unsigned int n = 0u; n < tChannels; ++n)
339 {
340 const T pushValue = sourceRow[x * tChannels + n];
341
342 medianHistograms[n].pushValue(pushValue);
343 }
344 }
345 }
346 }
347 }
348}
349
350#if 0 // keeping code for demonstration purpose
351
352template <typename T, unsigned int tChannels>
353void FrameFilterMedian::filterFloatSubset(const T* source, T* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int filterSize, const unsigned int firstRow, const unsigned int numberRows)
354{
355 static_assert(tChannels != 0u, "Invalid channel number");
356
357 ocean_assert(source != nullptr && target != nullptr);
358
359 ocean_assert(filterSize >= 3u && filterSize % 2u == 1u);
360
361 const unsigned int filterSize_2 = filterSize / 2u;
362 ocean_assert(filterSize_2 <= width && filterSize_2 <= height);
363
364 const unsigned int endRow = firstRow + numberRows;
365
366 const unsigned int sourceStrideElements = width * tChannels + sourcePaddingElements;
367 const unsigned int targetStrideElements = width * tChannels + targetPaddingElements;
368
369 SortedElements<T> sortedElements[tChannels];
370
371 // fill initial histogram
372
373 for (unsigned int y = clampLower(firstRow, filterSize_2); y <= clampUpper(firstRow, filterSize_2, height); ++y)
374 {
375 const T* sourceRow = source + y * sourceStrideElements;
376
377 for (unsigned int x = 0u; x <= filterSize_2; ++x)
378 {
379 for (unsigned int n = 0u; n < tChannels; ++n)
380 {
381 sortedElements[n].pushValue(*sourceRow++);
382 }
383 }
384 }
385
386 ocean_assert(sortedElements[0].size() >= (filterSize_2 + 1u) * (filterSize_2 + 1u));
387 ocean_assert(sortedElements[0].size() <= (filterSize_2 + 1u) * filterSize);
388
389 SortedElements<T> previousSortedElements[tChannels];
390
391 for (unsigned int y = firstRow; y < endRow; ++y)
392 {
393 T* targetRow = target + y * targetStrideElements;
394
395 // making a copy which we can use when we start with the next row
396 for (unsigned int n = 0u; n < tChannels; ++n)
397 {
398 previousSortedElements[n] = sortedElements[n];
399 }
400
401 for (unsigned int x = 0u; x < width; ++x)
402 {
403 for (unsigned int n = 0u; n < tChannels; ++n)
404 {
405 ocean_assert(sortedElements[n].size() != 0);
406 *targetRow++ = sortedElements[n].medianValue();
407 }
408
409 if (x != width - 1u)
410 {
411 ocean_assert(x + 1u < width);
412
413 // horizontal histogram update
414
415 for (unsigned int yy = clampLower(y, filterSize_2); yy <= clampUpper(y, filterSize_2, height); ++yy)
416 {
417 const T* sourceRow = source + yy * sourceStrideElements;
418
419 const unsigned int xxLeft = x - filterSize_2;
420 const unsigned int xxRight = x + filterSize_2 + 1u;
421
422 if (xxLeft < width && xxRight < width)
423 {
424 for (unsigned int n = 0u; n < tChannels; ++n)
425 {
426 const T pushValue = sourceRow[xxRight * tChannels + n];
427 const T popValue = sourceRow[xxLeft * tChannels + n];
428
429 sortedElements[n].exchange(pushValue, popValue);
430 }
431 }
432 else
433 {
434 if (xxLeft < width) // handling negative cases: int(xxLeft) < 0
435 {
436 for (unsigned int n = 0u; n < tChannels; ++n)
437 {
438 const T popValue = sourceRow[xxLeft * tChannels + n];
439
440 sortedElements[n].popValue(popValue);
441 }
442 }
443
444 if (xxRight < width)
445 {
446 for (unsigned int n = 0u; n < tChannels; ++n)
447 {
448 const T pushValue = sourceRow[xxRight * tChannels + n];
449
450 sortedElements[n].pushValue(pushValue);
451 }
452 }
453 }
454 }
455 }
456
457 ocean_assert(sortedElements[0].size() <= filterSize * filterSize);
458 }
459
460 if (y != endRow - 1u)
461 {
462 ocean_assert(y + 1u < endRow);
463
464 // vertical histogram update at the beginning of the row
465
466 for (unsigned int n = 0u; n < tChannels; ++n)
467 {
468 sortedElements[n] = previousSortedElements[n];
469 }
470
471 const unsigned int yyTop = y - filterSize_2;
472 const unsigned int yyBottom = y + filterSize_2 + 1u;
473
474 if (yyTop < height && yyBottom < height)
475 {
476 const T* sourceRowTop = source + yyTop * sourceStrideElements;
477 const T* sourceRowBottom = source + yyBottom * sourceStrideElements;
478
479 for (unsigned int x = 0u; x <= filterSize_2; ++x)
480 {
481 for (unsigned int n = 0u; n < tChannels; ++n)
482 {
483 const T pushValue = sourceRowBottom[x * tChannels + n];
484 const T popValue = sourceRowTop[x * tChannels + n];
485
486 sortedElements[n].exchange(pushValue, popValue);
487 }
488 }
489 }
490 else
491 {
492 if (yyTop < height) // handling negative cases: int(yyTop) < 0
493 {
494 const T* sourceRow = source + yyTop * sourceStrideElements;
495
496 for (unsigned int x = 0u; x <= filterSize_2; ++x)
497 {
498 for (unsigned int n = 0u; n < tChannels; ++n)
499 {
500 const T popValue = sourceRow[x * tChannels + n];
501
502 sortedElements[n].popValue(popValue);
503 }
504 }
505 }
506
507 if (yyBottom < height)
508 {
509 const T* sourceRow = source + yyBottom * sourceStrideElements;
510
511 for (unsigned int x = 0u; x <= filterSize_2; ++x)
512 {
513 for (unsigned int n = 0u; n < tChannels; ++n)
514 {
515 const T pushValue = sourceRow[x * tChannels + n];
516
517 sortedElements[n].pushValue(pushValue);
518 }
519 }
520 }
521 }
522 }
523 }
524}
525
526#endif
527
528template <typename T, unsigned int tChannels>
529void FrameFilterMedian::filterFloatSubset(const T* source, T* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int filterSize, const unsigned int firstRow, const unsigned int numberRows)
530{
531 static_assert(std::is_floating_point<T>::value, "Invalid data type!");
532 static_assert(tChannels != 0u, "Invalid channel number");
533
534 ocean_assert(source != nullptr && target != nullptr);
535 ocean_assert(firstRow + numberRows <= height);
536
537 const unsigned int sourceStrideElements = width * tChannels + sourcePaddingElements;
538 const unsigned int targetStrideElements = width * tChannels + targetPaddingElements;
539
540 const unsigned int filterSize_2 = filterSize / 2u;
541
542 std::vector<T> elements;
543 elements.reserve(filterSize * filterSize);
544
545 for (unsigned int y = firstRow; y < firstRow + numberRows; ++y)
546 {
547 T* targetRow = target + y * targetStrideElements;
548
549 for (unsigned int x = 0u; x < width; ++x)
550 {
551 for (unsigned int n = 0u; n < tChannels; ++n)
552 {
553 elements.clear();
554
555 for (unsigned int xx = max(0, int(x) - int(filterSize_2)); xx < min(x + filterSize_2 + 1u, width); ++xx)
556 {
557 for (unsigned int yy = max(0, int(y) - int(filterSize_2)); yy < min(y + filterSize_2 + 1u, height); ++yy)
558 {
559 ocean_assert(xx < width && yy < height);
560
561 elements.emplace_back(source[yy * sourceStrideElements + xx * tChannels + n]);
562 }
563 }
564
565 *targetRow++ = Median::median<T>(elements.data(), elements.size());
566 }
567 }
568 }
569}
570
571}
572
573}
574
575#endif // META_OCEAN_CV_FRAME_FILTER_MEDIAN_H
The following comfort class provides comfortable functions simplifying prototyping applications but a...
Definition FrameFilterMedian.h:41
static bool filter(Frame &frame, const unsigned int filterSize, Worker *worker)
Filters a frame with a median filter with arbitrary size (a square patch).
static bool filter(const Frame &source, Frame &target, const unsigned int filterSize, Worker *worker)
Filters a frame with a median filter with arbitrary size (a square patch).
This class implements a median filter.
Definition FrameFilterMedian.h:32
static void filter(const T *source, T *target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int filterSize, Worker *worker=nullptr)
Filters a frame with a median filter with arbitrary size (a square patch).
Definition FrameFilterMedian.h:134
static void filterIntegerSubset(const T *source, T *target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int filterSize, const unsigned int firstRow, const unsigned int numberRows)
Filters a subset of an integer frame with a median filter with arbitrary size.
Definition FrameFilterMedian.h:206
static void filterFloatSubset(const T *source, T *target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int filterSize, const unsigned int firstRow, const unsigned int numberRows)
Filters a subset of a floating point frame with a median filter with arbitrary size.
Definition FrameFilterMedian.h:353
This class implements a histogram for integer values.
Definition FrameFilterSorted.h:42
This class implements a container holding sorted elements.
Definition FrameFilterSorted.h:115
void pushValue(const T &value)
Pushes a new value into the container.
Definition FrameFilterSorted.h:327
void exchange(const T &pushValue, const T &popValue)
Exchanges a value with another value.
Definition FrameFilterSorted.h:345
void popValue(const T &value)
Pops a value from the container.
Definition FrameFilterSorted.h:336
T medianValue() const
Returns the median value of this histogram.
Definition FrameFilterSorted.h:406
This class implements the base class for all filters relying on sorted filter values.
Definition FrameFilterSorted.h:31
static unsigned int clampLower(const unsigned int index, const unsigned int lowerOffset)
Returns the lower clamped offset to an index.
Definition FrameFilterSorted.h:428
static unsigned int clampUpper(const unsigned int index, const unsigned int upperOffset, const unsigned int size)
Returns the upper clamped offset to an index.
Definition FrameFilterSorted.h:433
This class implements an image histogram.
Definition Histogram.h:32
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
This class implements an object able to allocate memory.
Definition base/Memory.h:22
size_t size() const
Returns the size of the memory in bytes.
Definition base/Memory.h:386
void * data()
Returns the pointer to the writable memory which is allocated by this object.
Definition base/Memory.h:303
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
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