Ocean
Loading...
Searching...
No Matches
FrameShrinker.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_SHRINKER_H
9#define META_OCEAN_CV_FRAME_SHRINKER_H
10
11#include "ocean/cv/CV.h"
12#include "ocean/cv/NEON.h"
13#include "ocean/cv/SSE.h"
14
15#include "ocean/base/Frame.h"
16#include "ocean/base/Worker.h"
17
18#include "ocean/math/Numeric.h"
19
20namespace Ocean
21{
22
23namespace CV
24{
25
26/**
27 * This class implements function to downsize a frame.
28 * @ingroup cv
29 */
30class OCEAN_CV_EXPORT FrameShrinker
31{
32 protected:
33
34 /**
35 * Definition of a function pointer allowing to down sample a block of elements by using a 11 pattern.
36 * @param sourceRow0 The upper source row, must be valid
37 * @param sourceRow1 The lower source row, must be valid
38 * @param target The target receiving the down sampled data
39 */
40 typedef void (*DownsampleBlockByTwo8BitPerChannelFunction)(const uint8_t* const sourceRow0, const uint8_t* const sourceRow1, uint8_t* const target);
41
42 /**
43 * Definition of a function pointer allowing to down sample a binary block of elements by using a 11 pattern.
44 * @param sourceRow0 The upper source row, must be valid
45 * @param sourceRow1 The lower source row, must be valid
46 * @param target The target receiving the down sampled data
47 * @param threshold Minimal sum threshold of four pixels to result in a pixel with value 255
48 */
49 typedef void (*DownsampleBlockByTwoBinary8BitPerChannelFunction)(const uint8_t* const sourceRow0, const uint8_t* const sourceRow1, uint8_t* const target, const uint16_t threshold);
50
51 public:
52
53 /**
54 * Reduces the resolution of a given frame by two, applying a 1-1 downsampling.
55 * Each downsampled pixel is based on 2x2 (= four) corresponding pixels from the source image:
56 * <pre>
57 * | 1 1 |
58 * | 1 1 | * 1/4
59 * </pre>
60 * If the given source image has an odd frame dimension the last pixel row or the last pixel column is filtered together with the two valid rows or columns respectively.<br>
61 * If the type of the target frame does not match to the input frame the target frame (and image buffer) will be replaced by the correct one.
62 * @param source The source frame to resize, must be valid
63 * @param target The target frame receiving the down sampled frame data, can be invalid
64 * @param worker Optional worker object to distribute the computational load to several CPU cores
65 * @return True, if succeeded
66 */
67 static bool downsampleByTwo11(const Frame& source, Frame& target, Worker* worker = nullptr);
68
69 /**
70 * Reduces the resolution of a given binary mask by two, applying a 1-1 downsampling.
71 * Each downsampled pixel is based on 2x2 (= four) corresponding pixels from the source image:
72 * <pre>
73 * | 1 1 |
74 * | 1 1 | * 1/4
75 * </pre>
76 * If the given source image has an odd frame dimension the last pixel row or the last pixel column is filtered together with the two valid rows or columns respectively.<br>
77 * If the type of the target frame does not match to the input frame the target frame (and image buffer) will be replaced by the correct one.
78 * @param source The source mask to resize, must be valid
79 * @param target The target mask receiving the down sampled frame data, can be invalid
80 * @param threshold The threshold of the minimal sum of the four mask pixels values to result in a downsampled pixel with value 255, with range [0, 255 * 4]
81 * @param worker Optional worker object to distribute the computational load to several CPU cores
82 * @return True, if succeeded
83 */
84 static bool downsampleBinayMaskByTwo11(const Frame& source, Frame& target, const unsigned int threshold = 766u, Worker* worker = nullptr);
85
86 /**
87 * Reduces the resolution of a given frame by two, applying a 1-4-6-4-1 downsampling.
88 * Each downsampled pixel is based on 5x5 (= 25) corresponding pixels from the source image:
89 * <pre>
90 * | 1 4 6 4 1 |
91 * | 4 16 24 16 4 |
92 * | 6 24 36 24 6 | * 1/256
93 * | 4 16 24 16 4 |
94 * | 1 4 6 4 1 |
95 * </pre>
96 * The filter values are determined at even pixel coordinates (0, 2, 4, ...).
97 * If the type of the target frame does not match to the input frame the target frame (and image buffer) will be replaced by the correct one.<br>
98 * By default, the resolution of the target frame will be set to (source.width() / 2, source.height() / 2).
99 * @param source The source frame to resize, must be valid
100 * @param target The target frame receiving the down sampled frame data, with resolution [source.width() / 2, (source.width() + 1) / 2]x[source.height() / 2, (source.height() + 1) / 2], can be invalid
101 * @param worker Optional worker object to distribute the computational load to several CPU cores
102 * @return True, if succeeded
103 */
104 static bool downsampleByTwo14641(const Frame& source, Frame& target, Worker* worker = nullptr);
105
106 /**
107 * Reduces the resolution of a given frame by two, taking four pixel values into account.
108 * If the given source image has an odd frame dimension the last pixel row or the last pixel column is filtered together with the two valid rows or columns respectively.<br>
109 * @param frame The frame to down sample, must be valid
110 * @param worker Optional worker object to distribute the computational load to several CPU cores
111 * @return True, if succeeded
112 */
113 static inline bool downsampleByTwo11(Frame& frame, Worker* worker = nullptr);
114
115 /**
116 * Reduces the resolution of a given binary mask by two, taking 2x2 (= four) mask pixel values into account.
117 * @param mask The mask to down sample, must be valid
118 * @param threshold The threshold of the minimal sum of the four mask pixels values to result in a downsampled pixel with value 255, with range [0, 255 * 4]
119 * @param worker Optional worker object to distribute the computational load to several CPU cores
120 * @return True, if succeeded
121 */
122 static inline bool downsampleBinayMaskByTwo11(Frame& mask, const unsigned int threshold = 766u, Worker* worker = nullptr);
123
124 /**
125 * Reduces the resolution of a given frame by two, applying a 1-4-6-4-1 downsampling.
126 * Each downsampled pixel is based on 5x5 (= 25) corresponding pixels from the source image:
127 * <pre>
128 * | 1 4 6 4 1 |
129 * | 4 16 24 16 4 |
130 * | 6 24 36 24 6 | * 1/256
131 * | 4 16 24 16 4 |
132 * | 1 4 6 4 1 |
133 * </pre>
134 * The filter values are determined at even pixel coordinates (0, 2, 4, ...).<br>
135 * The resulting frame will have the resolution (frame.width() / 2, frame.height() / 2).
136 * @param frame The frame to down sample, must be valid
137 * @param worker Optional worker object to distribute the computational load to several CPU cores
138 * @return True, if succeeded
139 */
140 static inline bool downsampleByTwo14641(Frame& frame, Worker* worker = nullptr);
141
142 /**
143 * Fills the buffer of a pyramid frame for frames with 1 plane and data type DT_UNSIGNED_INTEGER_8.
144 * @param source The source frame buffer to be used, must be valid
145 * @param pyramidTarget The frame buffer of the frame pyramid, large enough for the requested layers, must be valid
146 * @param pyramidTargetSize The size of the pyramid target memory, in bytes, with range [1, infinity)
147 * @param layers The number of pyramid layers to be created, with range [1, infinity)
148 * @param copyFirstLayer True, to copy the first layer before processing the next finer layers; False, to start directly with the next coarser layer (the memory for pyramidTarget can then be correspondingly smaller)
149 * @param worker Optional worker object to distribute the computational load, nullptr otherwise
150 * @return True, if succeeded
151 */
152 static bool pyramidByTwo11(const Frame& source, uint8_t* const pyramidTarget, const size_t pyramidTargetSize, const unsigned int layers, const bool copyFirstLayer, Worker* worker);
153
154 /**
155 * Fills the buffer of a pyramid frame for frames with 1 plane and data type DT_UNSIGNED_INTEGER_8 applying a 1-1 downsampling.
156 * Each pixel of a coarser pyramid level is based on 2x2 pixels from the corresponding finer pyramid level.
157 * @param source The source frame buffer to be used, must be valid
158 * @param pyramidTarget The frame buffer of the frame pyramid, large enough for the requested layers, must be valid
159 * @param sourceWidth Width of the source frame in pixel, with range [1, infinity)
160 * @param sourceHeight Height of the source frame in pixel, with range [1, infinity)
161 * @param channels The number of data channel the frames have, with range [1, infinity)
162 * @param pyramidTargetSize The size of the pyramid target memory, in bytes, with range [1, infinity)
163 * @param layers The number of pyramid layers to be created, with range [1, infinity)
164 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
165 * @param copyFirstLayer True, to copy the first layer before processing the next finer layers; False, to start directly with the next coarser layer (the memory for pyramidTarget can then be correspondingly smaller)
166 * @param worker Optional worker object to distribute the computational load, nullptr otherwise
167 * @return True, if succeeded
168 */
169 static bool pyramidByTwo8BitPerChannel11(const uint8_t* source, uint8_t* pyramidTarget, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const size_t pyramidTargetSize, const unsigned int layers, const unsigned int sourcePaddingElements, const bool copyFirstLayer, Worker* worker);
170
171 /**
172 * Reduces the resolution of a given frame by two, applying a 1-1 downsampling.
173 * Each downsampled pixel is based on 2x2 (= four) corresponding pixels from the source image:
174 * <pre>
175 * | 1 1 |
176 * | 1 1 | * 1/4
177 * </pre>
178 * The target width and target height will be sourceWidth / 2, targetHeight / 2.<br>
179 * In case, the given source image has an odd frame resolution the last pixel row or the last pixel column is filtered together with the two valid rows or columns respectively.<br>
180 * However, in general, this function is meant to be used for images with even width and height.
181 * @param source The source frame buffer to resize, must be valid
182 * @param target The target frame buffer receiving the down sampled image information, must be valid
183 * @param sourceWidth Width of the source frame in pixel, with range [2, infinity)
184 * @param sourceHeight Height of the source frame in pixel, with range [2, infinity)
185 * @param channels The number of data channel the frames have, with range [1, infinity)
186 * @param sourcePaddingElements Optional padding at the end of each source row in elements, with range [0, infinity)
187 * @param targetPaddingElements Optional padding at the end of each target row in elements, with range [0, infinity)
188 * @param worker Optional worker object to distribute the computational load to several CPU cores
189 */
190 static inline void downsampleByTwo8BitPerChannel11(const uint8_t* source, uint8_t* target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
191
192 /**
193 * Reduces the resolution of a given binary frame with 8bit per pixel with values 0 and 255 by two, taking four pixel values into account.
194 * @param source Binary source frame buffer to resize
195 * @param target Binary target frame buffer
196 * @param sourceWidth Width of the source frame in pixel, with range [2, infinity)
197 * @param sourceHeight Height of the source frame in pixel, with range [2, infinity)
198 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
199 * @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
200 * @param threshold Minimal sum threshold of four pixels to result in a pixel with value 255
201 * @param worker Optional worker object to distribute the computational load to several CPU cores
202 */
203 static inline void downsampleBinayMaskByTwo8BitPerChannel11(const uint8_t* source, uint8_t* target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int threshold = 766u, Worker* worker = nullptr);
204
205 /**
206 * Reduces the resolution of a given frame by two, applying a 1-4-6-4-1 downsampling.
207 * Each downsampled pixel is based on 5x5 (= 25) corresponding pixels from the source image:
208 * <pre>
209 * | 1 4 6 4 1 |
210 * | 4 16 24 16 4 |
211 * | 6 24 36 24 6 | * 1/256
212 * | 4 16 24 16 4 |
213 * | 1 4 6 4 1 |
214 * </pre>
215 * The filter values are determined at even pixel coordinates.
216 * @param source The source frame to resize, must be valid
217 * @param target The target frame receiving the down sampled frame data, with memory for (targetWidth * targetHeight) pixels, must be valid
218 * @param sourceWidth The width of the source frame in pixel, with range [2, infinity)
219 * @param sourceHeight The height of the source frame in pixel, with range [2, infinity)
220 * @param targetWidth The width of the target frame in pixel, with range [sourceWidth / 2, (sourceWidth + 1) / 2]
221 * @param targetHeight The height of the target frame in pixel, with range [sourceHeight / 2, (sourceHeight + 1) / 2]
222 * @param channels The number of frame channels, with range [1, infinity)
223 * @param sourcePaddingElements Optional padding at the end of each source row in elements, with range [0, infinity)
224 * @param targetPaddingElements Optional padding at the end of each target row in elements, with range [0, infinity)
225 * @param worker Optional worker object to distribute the computational load to several CPU cores
226 */
227 static inline void downsampleByTwo8BitPerChannel14641(const uint8_t* const source, uint8_t* const target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int channels, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
228
229 protected:
230
231 /**
232 * Fills the buffer of a pyramid frame for frames with 1 plane and data type DT_UNSIGNED_INTEGER_8.
233 * @param source The source frame buffer from which the pyramid will be created, must be valid
234 * @param pyramidTarget The frame buffer of the frame pyramid, large enough for the requested layers, must be valid
235 * @param sourceWidth Width of the source frame in pixel, with range [1, infinity)
236 * @param sourceHeight Height of the source frame in pixel, with range [1, infinity)
237 * @param channels The number of frame channels the source frame has, with range [1, infinity)
238 * @param pyramidTargetSize The size of the pyramid target memory, in bytes, with range [1, infinity)
239 * @param layers The number of pyramid layers to be created, with range [1, infinity)
240 * @param copyFirstLayer True, to copy the first layer before processing the next finer layers; False, to start directly with the next coarser layer
241 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
242 * @param worker Optional worker object to distribute the computational load
243 * @param threads The number of threads to be used if a valid worker is defined, with range [1u, worker->threads()] and the following must hold: threads * 2^layers <= sourceHeight
244 * @return True, if succeeded
245 */
246 static bool pyramidByTwo8BitPerChannel11WithThreads(const uint8_t* source, uint8_t* pyramidTarget, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const size_t pyramidTargetSize, const unsigned int layers, const bool copyFirstLayer, const unsigned int sourcePaddingElements, const unsigned int threads, Worker* worker);
247
248 /**
249 * Fills a subset of the buffer of a pyramid frame for a given frame with 1 plane and data type DT_UNSIGNED_INTEGER_8.
250 * @param source The source frame buffer from which the pyramid will be created, must be valid
251 * @param pyramidTarget The frame buffer of the frame pyramid, large enough for the requested layers, must be valid
252 * @param sourceWidth Width of the source frame in pixel, with range [1, infinity)
253 * @param sourceHeight Height of the source frame in pixel, with range [1, infinity)
254 * @param channels The number of frame channels the source image has, with range [1, infinity)
255 * @param pyramidTargetSize The size of the pyramid target memory, in bytes, with range [1, infinity)
256 * @param layers The number of pyramid layers to be created, with range [1, infinity)
257 * @param copyFirstLayer True, to copy the first layer before processing the next finer layers; False, to start directly with the next coarser layer
258 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
259 * @param firstSubsetsSourceHeight The height of the first subsets on the finest pyramid layer, with range [1, sourceHeight]
260 * @param subsets The number of subsets which will be used in parallel (the number of threads executing the function in parallel)
261 * @param subsetIndex The index of the subset which is handled, with range [0, subsetIndex)
262 * @param valueOne The parameter must be 1
263 */
264 static void pyramidByTwo8BitPerChannel11WithThreadsSubset(const uint8_t* source, uint8_t* pyramidTarget, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const size_t pyramidTargetSize, const unsigned int layers, const bool copyFirstLayer, const unsigned int sourcePaddingElements, const unsigned int firstSubsetsSourceHeight, const unsigned int subsets, const unsigned int subsetIndex, const unsigned int valueOne);
265
266 /**
267 * Reduces the resolution of a given frame by two.
268 * @param source The source frame buffer to resize, must be valid
269 * @param target The target frame buffer receiving the down sampled image information, must be valid
270 * @param sourceWidth Width of the source frame in pixel, with range [2, infinity)
271 * @param sourceHeight Height of the source frame in pixel, with range [2, infinity)
272 * @param channels The number of data channel the frames have, with range [1, infinity)
273 * @param sourcePaddingElements Optional padding at the end of each source row in elements, with range [0, infinity)
274 * @param targetPaddingElements Optional padding at the end of each target row in elements, with range [0, infinity)
275 * @param firstTargetRow The first target row to be handled, with range [0, sourceHeight / 2 - 1]
276 * @param numberTargetRows The number of target rows to be handled, with range [1, sourceHeight / 2 - firstTargetRow]
277 */
278 static void downsampleByTwo8BitPerChannel11Subset(const uint8_t* source, uint8_t* target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstTargetRow, const unsigned int numberTargetRows);
279
280 /**
281 * Reduces the resolution of a given binary frame with 8bit per pixel with values 0 and 255 by two, taking four pixel values into account.
282 * @param source The binary source frame, must be valid
283 * @param target The binary target frame, must be valid
284 * @param sourceWidth Width of the source frame in pixel, with range [2, infinity)
285 * @param sourceHeight Height of the source frame in pixel, with range [2, infinity)
286 * @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
287 * @param targetPaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
288 * @param threshold The threshold of the minimal sum of the four mask pixels values to result in a downsampled pixel with value 255, with range [0, 255 * 4]
289 * @param firstTargetRow The first target row to be handled, with range [0, sourceHeight / 2 - 1]
290 * @param numberTargetRows The number of target rows to be handled, with range [1, sourceHeight / 2 - firstTargetRow]
291 */
292 static void downsampleBinayMaskByTwo8BitPerChannel11Subset(const uint8_t* source, uint8_t* target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int threshold, const unsigned int firstTargetRow, const unsigned int numberTargetRows);
293
294 /**
295 * Determines the function to down sample a block of pixel elements by two with a 11 filter pattern.
296 * This function will return the function able to handle the largest block of elements, if any function exists.
297 * @param sourceWidth The width of the source frame in pixel, with range [2, infinity)
298 * @param channels The number of frame channels, with range [1, infinity)
299 * @param downsampleBlockFunction The resulting function down sampling the block of elements, nullptr if no matching function could be determined
300 * @param sourceElementsPerBlock The resulting number of source elements which will be handled by the resulting down sampling function, 0 if no matching function could be determined
301 */
302 static void determineFunctionDownsampleBlockByTwo8Bit11(const unsigned int sourceWidth, const unsigned int channels, DownsampleBlockByTwo8BitPerChannelFunction& downsampleBlockFunction, unsigned int& sourceElementsPerBlock);
303
304 /**
305 * Downsamples an area of 2x3 pixels (two rows and three columns) to one pixel in a frame, applying a 1-2-1 down sampling filter.
306 * This function is typically handling the last pixel in a frame (if the frame has an odd width).
307 * @param source The location of the top left pixel in the source frame, must be valid
308 * @param target The location in the target frame, must be valid
309 * @param channels The number of channels the source (and target) frame have, with range [1, infinity)
310 * @param sourceStrideElements The number of elements between two successive rows in the source frame, in elements, with range [sourceWidth * channels, infinity)
311 */
312 OCEAN_PREVENT_INLINE static void downsampleByTwoOneRowThreeColumns8BitPerChannel121(const uint8_t* source, uint8_t* target, const unsigned int channels, const unsigned int sourceStrideElements);
313
314 /**
315 * Downsamples three rows to one row in a frame, applying a 2x3 [1-2-1, 1-2-1] down sampling filter.
316 * In case the width of the source rows is 1 pixel, a 1x3 [1-2-1] is applied.<br>
317 * In case the width of the source rows is not a multiple of two, a 3x3 [1-2-1, 2-4-2, 1-2-1] filter is applied to the last 3 pixels.
318 * @param source The location of the left pixel in the top source row, must be valid
319 * @param target The location in the left pixel target row, must be valid
320 * @param sourceWidth The number of pixels in the source frame, with range [1, infinity)
321 * @param channels The number of channels the source (and target) frame have, with range [1, infinity)
322 * @param sourceStrideElements The number of elements between two successive rows in the source frame, in elements, with range [sourceWidth * channels, infinity)
323 */
324 OCEAN_PREVENT_INLINE static void downsampleByTwoThreeRows8BitPerChannel121(const uint8_t* source, uint8_t* target, const unsigned int sourceWidth, const unsigned int channels, const unsigned int sourceStrideElements);
325
326 /**
327 * Applies a vertical 14641 filter to each pixel in a given row not applying any SIMD instructions.
328 * This function can be used to down sample an image e.g., by a factor of two.
329 * @param source The entire source frame holding the row to which the filter is applied, must be valid
330 * @param targetRow The target row receiving the filter results which are not normalized, must be valid
331 * @param sourceElements The number of elements in each row (pixels * channels), with range [1, infinity)
332 * @param sourceHeight The height of the source frame in pixel, with range [2, infinity)
333 * @param sourceStrideElements The stride of the source frame (the number of elements in each row - may including padding at the end of each row), with range [sourceElements, infinity)
334 * @param ySource The row within the source frame to which the filter will be applied, with range [0, sourceHeight)
335 * @see downsampleByTwoRowHorizontal8BitPerChannel14641().
336 */
337 static void downsampleByTwoRowVertical8BitPerChannel14641(const uint8_t* const source, uint16_t* targetRow, const unsigned int sourceElements, const unsigned int sourceHeight, const unsigned int sourceStrideElements, const unsigned int ySource);
338
339 /**
340 * Applies a horizontal 14641 filter to each second pixel in a given row not applying any SIMD instructions.
341 * Each second pixel is skipped so that the target row has a length half of the source row.<br>
342 * This function can be used to down sample an image e.g., by a factor of two.
343 * @param sourceRow The source row already holding the vertical filter responses to which now the horizontal filter will be applied, must be valid
344 * @param targetRow The target row receiving the filter results which will be normalized before assignment, must be valid
345 * @param targetWidth The width of the target row in pixel, with range [1, infinity)
346 * @param channels The number of channels the target row (and source row) has, with range [1, infinity)
347 * @see downsampleByTwoRowVertical8BitPerChannel14641().
348 */
349 static void downsampleByTwoRowHorizontal8BitPerChannel14641(const uint16_t* sourceRow, uint8_t* targetRow, const unsigned int targetWidth, const unsigned int channels);
350
351#if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
352
353 /**
354 * Applies a vertical 14641 filter to each pixel in a given row using SSE instructions.
355 * This function can be used to down sample an image e.g., by a factor of two.
356 * @param source The entire source frame holding the row to which the filter is applied, must be valid
357 * @param targetRow The target row receiving the filter results which are not normalized, must be valid
358 * @param sourceElements The number of elements in each row (pixels * channels), with range [1, infinity)
359 * @param sourceHeight The height of the source frame in pixel, with range [2, infinity)
360 * @param sourceStrideElements The stride of the source frame (the number of elements in each row - may including padding at the end of each row), with range [sourceElements, infinity)
361 * @param ySource The row within the source frame to which the filter will be applied, with range [0, sourceHeight)
362 * @see downsampleByTwoRowHorizontal8BitPerChannel14641NEON().
363 */
364 static void downsampleByTwoRowVertical8BitPerChannel14641SSE(const uint8_t* const source, uint16_t* targetRow, const unsigned int sourceElements, const unsigned int sourceHeight, const unsigned int sourceStrideElements, const unsigned int ySource);
365
366#endif // OCEAN_HARDWARE_SSE_VERSION >= 41
367
368#if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
369
370 /**
371 * Applies a vertical 14641 filter to each pixel in a given row using NEON instructions.
372 * This function can be used to down sample an image e.g., by a factor of two.
373 * @param source The entire source frame holding the row to which the filter is applied, must be valid
374 * @param targetRow The target row receiving the filter results which are not normalized, must be valid
375 * @param sourceElements The number of elements in each row (pixels * channels), with range [16, infinity)
376 * @param sourceHeight The height of the source frame in pixel, with range [2, infinity)
377 * @param sourceStrideElements The stride of the source frame (the number of elements in each row - may including padding at the end of each row), with range [sourceElements, infinity)
378 * @param ySource The row within the source frame to which the filter will be applied, with range [0, sourceHeight)
379 * @see downsampleByTwoRowHorizontal8BitPerChannel14641NEON().
380 */
381 static void downsampleByTwoRowVertical8BitPerChannel14641NEON(const uint8_t* const source, uint16_t* targetRow, const unsigned int sourceElements, const unsigned int sourceHeight, const unsigned int sourceStrideElements, const unsigned int ySource);
382
383 /**
384 * Applies a horizontal 14641 filter to each second pixel in a given row applying NEON instructions.
385 * Each second pixel is skipped so that the target row has a length half of the source row.<br>
386 * This function can be used to down sample an image e.g., by a factor of two.
387 * @param sourceRow The source row already holding the vertical filter responses to which now the horizontal filter will be applied, must be valid
388 * @param targetRow The target row receiving the filter results which will be normalized before assignment, must be valid
389 * @param targetWidth The width of the target row in pixel, with individual ranges depending on tChannels
390 * @param channels The number of frame channels the target row (and source row) has, with range [1, infinity)
391 * @see downsampleByTwoRowVertical8BitPerChannel14641NEON().
392 * @tparam tChannels The number of channels the target row (and source row) has, with range [1, 4]
393 */
394 template <unsigned int tChannels>
395 static void downsampleByTwoRowHorizontal8BitPerChannel14641NEON(const uint16_t* sourceRow, uint8_t* targetRow, const unsigned int targetWidth, const unsigned int channels);
396
397#endif // OCEAN_HARDWARE_NEON_VERSION >= 10
398
399 /**
400 * Reduces the resolution in a subregion of a given frame by two, taking 5x5 (= 25) pixel values into account.
401 * The filter values are determined at even pixel coordinates.
402 * @param source The source frame to resize, must be valid
403 * @param target The target frame receiving the down sample frame data, with memory for (targetWidth * targetHeight) pixels, must be valid
404 * @param sourceWidth The width of the source frame in pixel, with range [2, infinity)
405 * @param sourceHeight The height of the source frame in pixel, with range [2, infinity)
406 * @param targetWidth The width of the target frame in pixel, with range [sourceWidth / 2, (sourceWidth + 1) / 2]
407 * @param channels The number of frame channels, with range [1, infinity)
408 * @param sourceStrideElements The stride of the source frame in elements (sourceWidth * channels + optional padding), with range [sourceWidth * channels, infinity)
409 * @param targetStrideElements The stride of the target frame in elements (targetWidth * channels + optional padding), with range [targetWidth * channels, infinity)
410 * @param firstTargetRow The first target row to be handled, with range [0, targetHeight)
411 * @param numberTargetRows The number of target rows to be handled, with range [1, targetHeight - firstTargetRow]
412 */
413 static void downsampleByTwo8BitPerChannel14641Subset(const uint8_t* source, uint8_t* target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int targetWidth, const unsigned int channels, const unsigned int sourceStrideElements, const unsigned int targetStrideElements, const unsigned int firstTargetRow, const unsigned int numberTargetRows);
414
415 /**
416 * Mirrors a given value at the left border if necessary.
417 * The function provides a result as below:<br>
418 * <pre>
419 * Original: -3 -2 -1 | 0 1 2 3 4 5 6
420 * Result: 2 1 0 | 0 1 2 3 4 5 6
421 * </pre>
422 * @param value The value to be mirrored, with range (-infinity, infinity)
423 * @return Mirrored value
424 * @ingroup base
425 */
426 static inline unsigned int mirroredBorderLocationLeft(const int value);
427
428 /**
429 * Mirrors a given value at the right border if necessary.
430 * The values is mirrored according to a given size parameter.<br>
431 * The function provides a result as below:<br>
432 * <pre>
433 * Original: 4 5 6 ... s-2 s-1 | s s+1 s+2
434 * Result: 4 5 6 ... s-2 s-1 | s-1 s-2 s-3
435 * </pre>
436 * @param value The value to be mirrored, with range [0, 2*size)
437 * @param size Specified size defining the upper mirror border, with range [1, 2147483647]
438 * @return Mirrored value
439 * @ingroup base
440 */
441 static inline unsigned int mirroredBorderLocationRight(const unsigned int value, const unsigned int size);
442};
443
445{
446 Frame tmpFrame;
447 if (!downsampleByTwo11(frame, tmpFrame, worker))
448 {
449 return false;
450 }
451
452 tmpFrame.setTimestamp(frame.timestamp());
453 tmpFrame.setRelativeTimestamp(frame.relativeTimestamp());
454
455 frame = std::move(tmpFrame);
456 return true;
457}
458
459inline bool FrameShrinker::downsampleBinayMaskByTwo11(Frame& mask, const unsigned int threshold, Worker* worker)
460{
461 Frame tmpMask;
462 if (!downsampleBinayMaskByTwo11(mask, tmpMask, threshold, worker))
463 {
464 return false;
465 }
466
467 tmpMask.setTimestamp(mask.timestamp());
469
470 mask = std::move(tmpMask);
471 return true;
472}
473
475{
476 Frame tmpFrame;
477 if (!downsampleByTwo14641(frame, tmpFrame, worker))
478 {
479 return false;
480 }
481
482 tmpFrame.setTimestamp(frame.timestamp());
483 tmpFrame.setRelativeTimestamp(frame.relativeTimestamp());
484
485 frame = std::move(tmpFrame);
486 return true;
487}
488
489inline void FrameShrinker::downsampleBinayMaskByTwo8BitPerChannel11(const uint8_t* source, uint8_t* target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int threshold, Worker* worker)
490{
491 ocean_assert(source != nullptr && target != nullptr);
492 ocean_assert(sourceWidth >= 2u && sourceHeight >= 2u);
493 ocean_assert(threshold <= 255 * 4u);
494
495 const unsigned int targetHeight = sourceHeight / 2u;
496 ocean_assert(targetHeight > 0u);
497
498 if (worker)
499 {
500 worker->executeFunction(Worker::Function::createStatic(&downsampleBinayMaskByTwo8BitPerChannel11Subset, source, target, sourceWidth, sourceHeight, sourcePaddingElements, targetPaddingElements, threshold, 0u, 0u), 0u, targetHeight, 7u, 8u, 20u);
501 }
502 else
503 {
504 downsampleBinayMaskByTwo8BitPerChannel11Subset(source, target, sourceWidth, sourceHeight, sourcePaddingElements, targetPaddingElements, threshold, 0u, targetHeight);
505 }
506}
507
508inline void FrameShrinker::downsampleByTwo8BitPerChannel11(const uint8_t* source, uint8_t* target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
509{
510 ocean_assert(source != nullptr && target != nullptr);
511 ocean_assert(sourceWidth >= 2u && sourceHeight >= 1u);
512 ocean_assert(channels >= 1u);
513
514 const unsigned int targetHeight = sourceHeight / 2u;
515
516 if (worker)
517 {
518 worker->executeFunction(Worker::Function::createStatic(FrameShrinker::downsampleByTwo8BitPerChannel11Subset, source, target, sourceWidth, sourceHeight, channels, sourcePaddingElements, targetPaddingElements, 0u, 0u), 0u, targetHeight);
519 }
520 else
521 {
522 downsampleByTwo8BitPerChannel11Subset(source, target, sourceWidth, sourceHeight, channels, sourcePaddingElements, targetPaddingElements, 0u, targetHeight);
523 }
524}
525
526inline unsigned int FrameShrinker::mirroredBorderLocationLeft(const int value)
527{
528 // Outside | Inside
529 // Original: -3 -2 -1 | 0 1 2 3 4 5 6
530 // Result: 2 1 0 | 0 1 2 3 4 5 6
531
532 if (value >= 0)
533 {
534 return value;
535 }
536 else
537 {
538 return -value - 1;
539 }
540}
541
542inline unsigned int FrameShrinker::mirroredBorderLocationRight(const unsigned int value, const unsigned int size)
543{
544 ocean_assert(value < 2u * size);
545
546 // Inside | Outside
547 // Original: 4 5 6 ... s-2 s-1 | s s+1 s+2
548 // Result: 4 5 6 ... s-2 s-1 | s-1 s-2 s-3
549
550 if (value < size)
551 {
552 return value;
553 }
554 else
555 {
556 ocean_assert(size * 2u - value - 1u < size);
557 return size * 2u - value - 1u;
558 }
559}
560
561inline void FrameShrinker::downsampleByTwo8BitPerChannel14641(const uint8_t* const source, uint8_t* const target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int channels, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
562{
563 ocean_assert(source != nullptr && target != nullptr);
564 ocean_assert(sourceWidth >= 2u && sourceHeight >= 2u);
565 ocean_assert((sourceWidth + 0u) / 2u == targetWidth || (sourceWidth + 1u) / 2u == targetWidth);
566 ocean_assert((sourceHeight + 0u) / 2u == targetHeight || (sourceHeight + 1u) / 2u == targetHeight);
567 ocean_assert(channels != 0u);
568
569 const unsigned int sourceStrideElements = sourceWidth * channels + sourcePaddingElements;
570 const unsigned int targetStrideElements = targetWidth * channels + targetPaddingElements;
571
572 if (worker)
573 {
574 worker->executeFunction(Worker::Function::createStatic(downsampleByTwo8BitPerChannel14641Subset, source, target, sourceWidth, sourceHeight, targetWidth, channels, sourceStrideElements, targetStrideElements, 0u, 0u), 0u, targetHeight);
575 }
576 else
577 {
578 downsampleByTwo8BitPerChannel14641Subset(source, target, sourceWidth, sourceHeight, targetWidth, channels, sourceStrideElements, targetStrideElements, 0u, targetHeight);
579 }
580}
581
582}
583
584}
585
586#endif // META_OCEAN_CV_FRAME_SHRINKER_H
This class implements function to downsize a frame.
Definition FrameShrinker.h:31
static void downsampleBinayMaskByTwo8BitPerChannel11Subset(const uint8_t *source, uint8_t *target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int threshold, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
Reduces the resolution of a given binary frame with 8bit per pixel with values 0 and 255 by two,...
static void downsampleByTwoRowVertical8BitPerChannel14641(const uint8_t *const source, uint16_t *targetRow, const unsigned int sourceElements, const unsigned int sourceHeight, const unsigned int sourceStrideElements, const unsigned int ySource)
Applies a vertical 14641 filter to each pixel in a given row not applying any SIMD instructions.
static bool pyramidByTwo8BitPerChannel11(const uint8_t *source, uint8_t *pyramidTarget, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const size_t pyramidTargetSize, const unsigned int layers, const unsigned int sourcePaddingElements, const bool copyFirstLayer, Worker *worker)
Fills the buffer of a pyramid frame for frames with 1 plane and data type DT_UNSIGNED_INTEGER_8 apply...
static void downsampleByTwoRowVertical8BitPerChannel14641SSE(const uint8_t *const source, uint16_t *targetRow, const unsigned int sourceElements, const unsigned int sourceHeight, const unsigned int sourceStrideElements, const unsigned int ySource)
Applies a vertical 14641 filter to each pixel in a given row using SSE instructions.
static void downsampleBinayMaskByTwo8BitPerChannel11(const uint8_t *source, uint8_t *target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int threshold=766u, Worker *worker=nullptr)
Reduces the resolution of a given binary frame with 8bit per pixel with values 0 and 255 by two,...
Definition FrameShrinker.h:489
static bool pyramidByTwo8BitPerChannel11WithThreads(const uint8_t *source, uint8_t *pyramidTarget, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const size_t pyramidTargetSize, const unsigned int layers, const bool copyFirstLayer, const unsigned int sourcePaddingElements, const unsigned int threads, Worker *worker)
Fills the buffer of a pyramid frame for frames with 1 plane and data type DT_UNSIGNED_INTEGER_8.
static void downsampleByTwo8BitPerChannel11(const uint8_t *source, uint8_t *target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Reduces the resolution of a given frame by two, applying a 1-1 downsampling.
Definition FrameShrinker.h:508
static void downsampleByTwo8BitPerChannel11Subset(const uint8_t *source, uint8_t *target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
Reduces the resolution of a given frame by two.
static OCEAN_PREVENT_INLINE void downsampleByTwoThreeRows8BitPerChannel121(const uint8_t *source, uint8_t *target, const unsigned int sourceWidth, const unsigned int channels, const unsigned int sourceStrideElements)
Downsamples three rows to one row in a frame, applying a 2x3 [1-2-1, 1-2-1] down sampling filter.
static void downsampleByTwo8BitPerChannel14641(const uint8_t *const source, uint8_t *const target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int channels, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Reduces the resolution of a given frame by two, applying a 1-4-6-4-1 downsampling.
Definition FrameShrinker.h:561
static void downsampleByTwoRowHorizontal8BitPerChannel14641(const uint16_t *sourceRow, uint8_t *targetRow, const unsigned int targetWidth, const unsigned int channels)
Applies a horizontal 14641 filter to each second pixel in a given row not applying any SIMD instructi...
static void pyramidByTwo8BitPerChannel11WithThreadsSubset(const uint8_t *source, uint8_t *pyramidTarget, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int channels, const size_t pyramidTargetSize, const unsigned int layers, const bool copyFirstLayer, const unsigned int sourcePaddingElements, const unsigned int firstSubsetsSourceHeight, const unsigned int subsets, const unsigned int subsetIndex, const unsigned int valueOne)
Fills a subset of the buffer of a pyramid frame for a given frame with 1 plane and data type DT_UNSIG...
static bool downsampleByTwo11(const Frame &source, Frame &target, Worker *worker=nullptr)
Reduces the resolution of a given frame by two, applying a 1-1 downsampling.
static OCEAN_PREVENT_INLINE void downsampleByTwoOneRowThreeColumns8BitPerChannel121(const uint8_t *source, uint8_t *target, const unsigned int channels, const unsigned int sourceStrideElements)
Downsamples an area of 2x3 pixels (two rows and three columns) to one pixel in a frame,...
static bool pyramidByTwo11(const Frame &source, uint8_t *const pyramidTarget, const size_t pyramidTargetSize, const unsigned int layers, const bool copyFirstLayer, Worker *worker)
Fills the buffer of a pyramid frame for frames with 1 plane and data type DT_UNSIGNED_INTEGER_8.
static bool downsampleBinayMaskByTwo11(const Frame &source, Frame &target, const unsigned int threshold=766u, Worker *worker=nullptr)
Reduces the resolution of a given binary mask by two, applying a 1-1 downsampling.
static void downsampleByTwoRowVertical8BitPerChannel14641NEON(const uint8_t *const source, uint16_t *targetRow, const unsigned int sourceElements, const unsigned int sourceHeight, const unsigned int sourceStrideElements, const unsigned int ySource)
Applies a vertical 14641 filter to each pixel in a given row using NEON instructions.
static void downsampleByTwoRowHorizontal8BitPerChannel14641NEON(const uint16_t *sourceRow, uint8_t *targetRow, const unsigned int targetWidth, const unsigned int channels)
Applies a horizontal 14641 filter to each second pixel in a given row applying NEON instructions.
static void downsampleByTwo8BitPerChannel14641Subset(const uint8_t *source, uint8_t *target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int targetWidth, const unsigned int channels, const unsigned int sourceStrideElements, const unsigned int targetStrideElements, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
Reduces the resolution in a subregion of a given frame by two, taking 5x5 (= 25) pixel values into ac...
static bool downsampleByTwo14641(const Frame &source, Frame &target, Worker *worker=nullptr)
Reduces the resolution of a given frame by two, applying a 1-4-6-4-1 downsampling.
static void determineFunctionDownsampleBlockByTwo8Bit11(const unsigned int sourceWidth, const unsigned int channels, DownsampleBlockByTwo8BitPerChannelFunction &downsampleBlockFunction, unsigned int &sourceElementsPerBlock)
Determines the function to down sample a block of pixel elements by two with a 11 filter pattern.
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
void setRelativeTimestamp(const Timestamp &relative)
Sets the relative timestamp of this frame.
Definition Frame.h:4233
void setTimestamp(const Timestamp &timestamp)
Sets the timestamp of this frame.
Definition Frame.h:4228
const Timestamp & timestamp() const
Returns the timestamp of this frame.
Definition Frame.h:4218
const Timestamp & relativeTimestamp() const
Returns the relative timestamp of this frame.
Definition Frame.h:4223
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.
static unsigned int mirroredBorderLocationRight(const unsigned int value, const unsigned int size)
Mirrors a given value at the right border if necessary.
Definition FrameShrinker.h:542
static unsigned int mirroredBorderLocationLeft(const int value)
Mirrors a given value at the left border if necessary.
Definition FrameShrinker.h:526
The namespace covering the entire Ocean framework.
Definition Accessor.h:15