Ocean
FrameNormalizer.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_NORMALIZER_H
9 #define META_OCEAN_CV_FRAME_NORMALIZER_H
10 
11 #include "ocean/cv/CV.h"
12 #include "ocean/cv/FrameMinMax.h"
13 
14 #include "ocean/base/DataType.h"
15 #include "ocean/base/Frame.h"
16 #include "ocean/base/Utilities.h"
17 #include "ocean/base/Worker.h"
18 
19 #include "ocean/math/Numeric.h"
20 
21 #include <limits>
22 
23 namespace Ocean
24 {
25 
26 namespace CV
27 {
28 
29 /**
30  * This class implements functions normalizing frames.
31  * @ingroup cv
32  */
33 class OCEAN_CV_EXPORT FrameNormalizer
34 {
35  private:
36 
37  /**
38  * Helper struct allowing to determine the necessary float type for a given data type.
39  * @tparam T The data type for which the matching float type has to be found
40  */
41  template <typename T>
42  struct FloatType
43  {
44  /// The matching float type for `T`, is `double` if `T` is double, otherwise always `float`.
45  typedef float Type;
46  };
47 
48  /**
49  * Helper struct allowing to determine the type able to store data multiplied by 255
50  * @tparam T The data type for which the matching type has to be found
51  */
52  template <typename T>
54  {
55  /// The matching datatype which is able to store all values in T multiplied by 255
56  typedef typename NextLargerTyper<T>::Type Type;
57  };
58 
59  public:
60 
61  /**
62  * Normalizes a given 1-channel frame linearly to a uint8 image.
63  * The normalization is based on the following equation for each pixel individually:
64  * <pre>
65  * normalizedPixel = (pixel - minimalPixelValue) / (maximalPixelValue - minimalPixelValue) * 255
66  *
67  * with `minimalPixelValue` and `maximalPixelValue` the minimal (or maximal) pixel value within the entire image
68  * </pre>
69  * @param source The source frame to be normalized, must have one channel, must be valid
70  * @param target The resulting normalized frame with pixel format FORMAT_Y8
71  * @param worker Optional worker object to distribute the computation
72  * @return True, if succeeded
73  */
74  static bool normalizeToUint8(const Frame& source, Frame& target, Worker* worker = nullptr);
75 
76  /**
77  * Normalizes each channel of a frame linearly to a float32 image to the range [0, 1].
78  * The normalization is based on the following equation for each pixel individually:
79  * <pre>
80  * normalizedPixel[channel] = (pixel[channel] - minimalPixelValues[channel]) / (maximalPixelValues[channel] - minimalPixelValues[channel])
81  * </pre>
82  * with `minimalPixelValues[channel]` and `maximalPixelValues[channel]` being the minimum and maximum pixel values of a channel of the image.
83  * @param source The source frame to be normalized, must have one channel, must be valid
84  * @param target The resulting normalized frame; will have the same frame type as `source` but with data type `FrameType::DT_SIGNED_FLOAT_32`
85  * @param worker Optional worker object to distribute the computation
86  * @return True, if succeeded
87  */
88  static bool normalizeToFloat32(const Frame& source, Frame& target, Worker* worker = nullptr);
89 
90  /**
91  * Normalizes a given frame linearly to a float32 image.
92  * If both, `bias` and `scale` are valid, the normalization is based on the following equation for each pixel individually:
93  * <pre>
94  * normalizedPixel[channel] = (pixel[channel] + bias[channel]) * scale[channel]
95  * </pre>
96  * if either or both are `nullptr`, the normalization is as follows:
97  * <pre>
98  * normalizedPixel[channel] = (pixel[channel] - minimalPixelValues[channel]) / (maximalPixelValues[channel] - minimalPixelValues[channel])
99  * </pre>
100  * with `minimalPixelValues[channel]` and `maximalPixelValues[channel]` being the minimum and maximum pixel values of each channel of the image.
101  * @param source The source frame to be normalized, must have one channel, must be valid
102  * @param target The resulting normalized frame; will have the same frame type as `source` but with data type `FrameType::DT_SIGNED_FLOAT_32`
103  * @param bias The bias values, if valid it must have `source.channels()` elements
104  * @param scale The scale value, if valid it must have `source.channels()` elements
105  * @param worker Optional worker object to distribute the computation
106  * @return True, if succeeded
107  */
108  static bool normalizeToFloat32(const Frame& source, Frame& target, const float* bias, const float* scale, Worker* worker = nullptr);
109 
110  /**
111  * Normalizes a given frame logarithmically to a uint8 image.
112  * @param source The source frame to be normalized, must be valid
113  * @param target The target frame receiving the normalized values, will be adjusted to the correct frame type if it does not have the correct pixel format and pixel origin
114  * @param octaves Scalar that specifies the logarithmic display range, with range (0, 10]
115  * @param worker Optional worker object to distribute the computation
116  * @return True, if succeeded
117  */
118  static bool normalizeLogarithmToUint8(const Frame& source, Frame& target, const Scalar octaves = 5.0f, Worker* worker = nullptr);
119 
120  /**
121  * Normalizes a given frame logarithmically to a float32 image.
122  * @param source The source frame to be normalized, must be valid
123  * @param target The target frame receiving the normalized values, will be adjusted to the correct frame type if it does not have the correct pixel format and pixel origin
124  * @param octaves Scalar that specifies the logarithmic display range, with range (0, 10]
125  * @param worker Optional worker object to distribute the computation
126  * @return True, if succeeded
127  */
128  static bool normalizeLogarithmToFloat32(const Frame& source, Frame& target, const Scalar octaves = 5.0f, Worker* worker = nullptr);
129 
130  /**
131  * Normalizes a given 1-channel frame linearly to a uint8 image.
132  * The normalization is based on the following equation for each pixel individually:
133  * <pre>
134  * normalizedPixel = (pixel - minimalPixelValue) / (maximalPixelValue - minimalPixelValue) * 255
135  *
136  * with `minimalPixelValue` and `maximalPixelValue` the minimal (or maximal) pixel value within the entire image
137  * </pre>
138  * @param frame The frame to be normalized, must have one channel, must be valid
139  * @param worker Optional worker object to distribute the computation
140  * @return True, if succeeded
141  */
142  static bool normalizeToUint8(Frame& frame, Worker* worker = nullptr);
143 
144  /**
145  * Normalizes a given 1-channel frame linearly to a float32 image.
146  * The normalization is based on the following equation for each pixel individually:
147  * <pre>
148  * normalizedPixel = (pixel - minimalPixelValue) / (maximalPixelValue - minimalPixelValue) * 255
149  *
150  * with `minimalPixelValue` and `maximalPixelValue` the minimal (or maximal) pixel value within the entire image
151  * </pre>
152  * @param frame The frame to be normalized, must have one channel, must be valid
153  * @param worker Optional worker object to distribute the computation
154  * @return True, if succeeded
155  */
156  static bool normalizeToFloat32(Frame& frame, Worker* worker = nullptr);
157 
158  /**
159  * Normalizes a given frame linearly to a uint8 image.
160  * @param frame The frame to be normalized
161  * @param octaves Scalar that specifies the logarithmic display range, with range (0, 10]
162  * @param worker Optional worker object to distribute the computation
163  * @return True, if succeeded
164  */
165  static bool normalizeLogarithmToUint8(Frame& frame, const Scalar octaves = 5.0f, Worker* worker = nullptr);
166 
167  /**
168  * Normalizes a given frame linearly to a float32 image.
169  * @param frame The frame to be normalized
170  * @param octaves Scalar that specifies the logarithmic display range, with range (0, 10]
171  * @param worker Optional worker object to distribute the computation
172  * @return True, if succeeded
173  */
174  static bool normalizeLogarithmToFloat32(Frame& frame, const Scalar octaves = 5.0f, Worker* worker = nullptr);
175 
176  /**
177  * Normalizes a given 1 channel frame to the 8 bit value range [0, 255] linearly.
178  * The normalization is based on the following equation for each pixel individually:
179  * <pre>
180  * normalizedPixel = (pixel - minimalPixelValue) / (maximalPixelValue - minimalPixelValue) * 255
181  *
182  * with `minimalPixelValue` and `maximalPixelValue` the minimal (or maximal) pixel value within the entire image
183  * </pre>
184  * @param source The source frame to be normalized, must be valid
185  * @param target The normalized frame, must be valid
186  * @param width The width of the frame in pixel, with range [1, infinity)
187  * @param height The height of the frame in pixel, with range [1, infinity)
188  * @param sourcePaddingElements Optional number of padding elements at the end of each source row, in elements, with range [0, infinity)
189  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
190  * @param worker Optional worker object to distribute the computation
191  * @tparam T The data type of each source pixel
192  * @see normalizeLogarithm1ChannelToUint8(), normalizeToFloat().
193  */
194  template <typename T>
195  static void normalize1ChannelToUint8(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
196 
197  /**
198  * Normalizes a frame to float values by using predefined per-channel bias and scaling values.
199  * If both, `bias` and `scale` are valid, the normalization is based on the following equation for each pixel individually:
200  * <pre>
201  * normalizedPixel[channel] = (pixel[channel] + bias[channel]) * scale[channel]
202  * </pre>
203  * if either or both are `nullptr`, the normalization is as follows:
204  * <pre>
205  * normalizedPixel[channel] = (pixel[channel] - minimalPixelValues[channel]) / (maximalPixelValues[channel] - minimalPixelValues[channel])
206  * </pre>
207  * with `minimalPixelValues[channel]` and `maximalPixelValues[channel]` being the minimum and maximum pixel values of each channel of the image.
208  * @param source The source frame to be normalized, must be valid
209  * @param target The normalized frame, must be valid
210  * @param width The width of the frame in pixels, with range [1, infinity)
211  * @param height The height of the frame in pixels, with range [1, infinity)
212  * @param bias The bias values, must be valid and have `tChannels` elements
213  * @param scale The scale value, must be valid and have `tChannels` elements
214  * @param sourcePaddingElements Optional number of padding elements at the end of each source row, in elements, with range [0, infinity)
215  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
216  * @param worker Optional worker object to distribute the computation
217  * @tparam TSource The data type of each source pixel, can be an integer or floating point data type
218  * @tparam TTarget The data type of each target pixel, must be a floating point data type
219  * @tparam tChannels Number of channels of the frame, with range [1, infinity)
220  */
221  template <typename TSource, typename TTarget, unsigned int tChannels>
222  static void normalizeToFloat(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const TTarget* bias, const TTarget* scale, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
223 
224  /**
225  * Normalizes a given 1 channel frame to the 8 bit value range [0, 255] logarithmically.
226  * @param source The source frame to be normalized, must be valid
227  * @param target The target frame receiving the normalized frame, must be valid
228  * @param width The width of the frame in pixel, with range [1, infinity)
229  * @param height The height of the frame in pixel, with range [1, infinity)
230  * @param octaves Scalar that specifies the logarithmic display range, with range (0, 10]
231  * @param sourcePaddingElements Optional number of padding elements at the end of each source row, in elements, with range [0, infinity)
232  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
233  * @param worker Optional worker object to distribute the computation
234  * @tparam T Data type of each pixel
235  * @see normalize1ChannelToUint8().
236  */
237  template <typename T>
238  static void normalizeLogarithm1ChannelToUint8(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const Scalar octaves, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
239 
240  /**
241  * Normalizes a given 1 channel frame to float values with value range [0, 1] logarithmically.
242  * @param source The source frame to be normalized, must be valid
243  * @param target The target frame with floating point precision receiving the normalized frame, must be valid
244  * @param width The width of the frame in pixel, with range [1, infinity)
245  * @param height The height of the frame in pixel, with range [1, infinity)
246  * @param octaves Scalar that specifies the logarithmic display range, with range (0, 10]
247  * @param sourcePaddingElements Optional number of padding elements at the end of each source row, in elements, with range [0, infinity)
248  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
249  * @param worker Optional worker object to distribute the computation
250  * @tparam TSource The data type of each source pixel, can be an integer or floating point data type
251  * @tparam TTarget The data type of each target pixel, must be a floating point data type
252  */
253  template <typename TSource, typename TTarget>
254  static void normalizeLogarithm1ChannelToFloat(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const Scalar octaves, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
255 
256  private:
257 
258  /**
259  * Normalizes a given 1 channel integer frame to the 8 bit value range [0, 255] linearly.
260  * @param source The source frame to be normalized, must be valid
261  * @param target The normalized frame, must be valid
262  * @param width The width of the frame in pixel, with range [1, infinity)
263  * @param height The height of the frame in pixel, with range [1, infinity)
264  * @param sourcePaddingElements Optional number of padding elements at the end of each source row, in elements, with range [0, infinity)
265  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
266  * @param worker Optional worker object to distribute the computation
267  * @tparam T The data type of each source pixel, must be an integer type
268  */
269  template <typename T>
270  static inline void normalize1ChannelIntegerToUint8(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
271 
272  /**
273  * Normalizes a given 1 channel float frame to the 8 bit value range [0, 255] linearly.
274  * @param source The source frame to be normalized, must be valid
275  * @param target The normalized frame, must be valid
276  * @param width The width of the frame in pixel, with range [1, infinity)
277  * @param height The height of the frame in pixel, with range [1, infinity)
278  * @param sourcePaddingElements Optional number of padding elements at the end of each source row, in elements, with range [0, infinity)
279  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
280  * @param worker Optional worker object to distribute the computation
281  * @tparam T The data type of each source pixel, must be a floating point type
282  */
283  template <typename T>
284  static inline void normalize1ChannelFloatToUint8(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
285 
286  /**
287  * Normalizes a frame to float values by using predefined per-channel bias and scaling values.
288  * If both, `bias` and `scale` are valid, the normalization is based on the following equation for each pixel individually:
289  * <pre>
290  * normalizedPixel[channel] = (pixel[channel] + bias[channel]) * scale[channel]
291  * </pre>
292  * if either or both are `nullptr`, the normalization is as follows:
293  * <pre>
294  * normalizedPixel[channel] = (pixel[channel] - minimalPixelValues[channel]) / (maximalPixelValues[channel] - minimalPixelValues[channel])
295  * </pre>
296  * with `minimalPixelValues[channel]` and `maximalPixelValues[channel]` being the minimum and maximum pixel values of each channel of the image.
297  * @param source The source frame to be normalized, must be valid
298  * @param target The normalized frame, must be valid
299  * @param width The width of the frame in pixels, with range [1, infinity)
300  * @param height The height of the frame in pixels, with range [1, infinity)
301  * @param channels Number of channels of the frame, with range [1, infinity)
302  * @param bias The bias values, must be valid and have `channels` elements
303  * @param scale The scale value, must be valid and have `channels` elements
304  * @param sourcePaddingElements Optional number of padding elements at the end of each source row, in elements, with range [0, infinity)
305  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
306  * @param worker Optional worker object to distribute the computation
307  * @return True if the normalization was successful, otherwise false
308  * @tparam TSource The data type of each source pixel, can be an integer or floating point data type
309  * @tparam TTarget The data type of each target pixel, must be a floating point data type
310  */
311  template <typename TSource, typename TTarget>
312  static bool normalizeToFloat(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int channels, const TTarget* bias, const TTarget* scale, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);
313 
314  /**
315  * Normalizes a subset of a given 1 channel frame to the 8 bit value range [0, 255] linearly.
316  * @param source The source frame to be normalized, must be valid
317  * @param target The normalized frame, must be valid
318  * @param width The width of the frame in pixel, with range [1, infinity)
319  * @param height The height of the frame in pixel, with range [1, infinity)
320  * @param minimalValue Minimal value that have been determined already
321  * @param range The range between maximal and minimal value [maximalValue - minimalValue]
322  * @param sourcePaddingElements Optional number of padding elements at the end of each source row, in elements, with range [0, infinity)
323  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
324  * @param firstRow First row to be handled, with range [0, height - 1]
325  * @param numberRows Number rows to be handled, with range [1, height - firstRow]
326  * @tparam T Data type of each pixel, must be an integer type
327  */
328  template <typename T>
329  static void normalize1ChannelIntegerToUint8Subset(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const T minimalValue, const typename UnsignedTyper<T>::Type range, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows);
330 
331  /**
332  * Normalizes a subset of a given 1 channel frame to the 8 bit value range [0, 255] linearly.
333  * @param source The source frame to be normalized, must be valid
334  * @param target The normalized frame, must be valid
335  * @param width The width of the frame in pixel, with range [1, infinity)
336  * @param height The height of the frame in pixel, with range [1, infinity)
337  * @param minimalValue Minimal value that have been determined already
338  * @param range The range between maximal and minimal value [maximalValue - minimalValue]
339  * @param sourcePaddingElements Optional number of padding elements at the end of each source row, in elements, with range [0, infinity)
340  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
341  * @param firstRow First row to be handled, with range [0, height - 1]
342  * @param numberRows Number rows to be handled, with range [1, height - firstRow]
343  * @tparam T Data type of each pixel, must be a floating point type
344  * @tparam TRange The data type of the range value, either 'float' or 'double'
345  */
346  template <typename T, typename TRange>
347  static void normalize1ChannelFloatToUint8Subset(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const T minimalValue, const TRange range, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows);
348 
349  /**
350  * Normalizes a subset of rows of a frame to float values by using predefined per-channel bias and scaling values.
351  * @param source The source frame to be normalized, must be valid
352  * @param target The normalized frame with floating point precision, must be valid
353  * @param width The width of the frame in pixel, with range [1, infinity)
354  * @param height The height of the frame in pixel, with range [1, infinity)
355  * @param bias The bias values, must be valid and have `tChannels` elements
356  * @param scale The scale value, must be valid and have `tChannels` elements
357  * @param sourcePaddingElements Optional number of padding elements at the end of each source row, in elements, with range [0, infinity)
358  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
359  * @param firstRow First row to be handled, with range [0, height - 1]
360  * @param numberRows Number rows to be handled, with range [1, height - firstRow]
361  * @tparam TSource The data type of each source pixel, can be an integer or floating point data type
362  * @tparam TTarget The data type of each target pixel, must be a floating point data type
363  * @tparam tChannels Number of channels of the frame, with range [1, infinity)
364  */
365  template <typename TSource, typename TTarget, unsigned int tChannels>
366  static void normalizeToFloatSubset(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const TTarget* bias, const TTarget* scale, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows);
367 
368  /**
369  * Normalizes a subset of a given 1 channel frame to the 8 bit value range [0, 255] logarithmically.
370  * @param source The source frame to be normalizes, must be valid
371  * @param target The target frame receiving the normalized frame, must be valid
372  * @param width The width of the frame in pixel, with range [1, infinity)
373  * @param height The height of the frame in pixel, with range [1, infinity)
374  * @param octaves Scalar that specifies the logarithmic display range, with range (0, 10]
375  * @param minimalValue Minimal value that have been determined already
376  * @param range The range between maximal and minimal value [maximal - minimal]
377  * @param sourcePaddingElements Optional number of padding elements at the end of each source row, in elements, with range [0, infinity)
378  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
379  * @param firstRow First row to be handled, with range [0, height - 1]
380  * @param numberRows Number rows to be handled, with range [1, height - firstRow]
381  * @tparam T Data type of each pixel
382  * @tparam TRange The data type of the range value, either 'float' or 'double'
383  */
384  template <typename T, typename TRange>
385  static void normalizeLogarithm1ChannelToUint8Subset(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const Scalar octaves, const T minimalValue, const TRange range, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows);
386 
387  /**
388  * Normalizes a subset of a given 1 channel frame to the value range [0, 1] logarithmically.
389  * @param source The source frame to be normalizes, must be valid
390  * @param target The target frame with floating point precision receiving the normalized frame, must be valid
391  * @param width The width of the frame in pixel, with range [1, infinity)
392  * @param height The height of the frame in pixel, with range [1, infinity)
393  * @param octaves Scalar that specifies the logarithmic display range, with range (0, 10]
394  * @param minimalValue Minimal value that have been determined already
395  * @param range The range between maximal and minimal value [maximal - minimal]
396  * @param sourcePaddingElements Optional number of padding elements at the end of each source row, in elements, with range [0, infinity)
397  * @param targetPaddingElements Optional number of padding elements at the end of each target row, in elements, with range [0, infinity)
398  * @param firstRow First row to be handled, with range [0, height - 1]
399  * @param numberRows Number rows to be handled, with range [1, height - firstRow]
400  * @tparam TSource The data type of each source pixel, can be an integer or floating point data type
401  * @tparam TTarget The data type of each target pixel, must be a floating point data type
402  */
403  template <typename TSource, typename TTarget>
404  static void normalizeLogarithm1ChannelToFloatSubset(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const Scalar octaves, const TTarget minimalValue, const TTarget range, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows);
405 
406  /**
407  * Returns the smallest epsilon larger than zero for a specific data type.
408  * @return Requested epsilon
409  * @tparam T Data type for that the epsilon is requested
410  */
411  template <typename T>
412  static inline T epsilon();
413 };
414 
415 /**
416  * Specialization of the helper struct.
417  */
418 template <>
420 {
421  typedef double Type;
422 };
423 
424 template <>
426 {
427  typedef double Type;
428 };
429 
430 template <>
432 {
433  typedef float Type;
434 };
435 
436 template <typename T>
437 void FrameNormalizer::normalize1ChannelToUint8(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
438 {
439  normalize1ChannelIntegerToUint8<T>(source, target, width, height, sourcePaddingElements, targetPaddingElements, worker);
440 }
441 
442 template <typename TSource, typename TTarget, unsigned int tChannels>
443 void FrameNormalizer::normalizeToFloat(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const TTarget* bias, const TTarget* scale, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
444 {
445  static_assert(std::is_floating_point<TTarget>::value, "Invalid data type!");
446  static_assert(tChannels != 0u, "Invalid number of channels");
447 
448  ocean_assert(source != nullptr && target != nullptr);
449  ocean_assert(width >= 1u && height >= 1u);
450 
451  TTarget localBias[tChannels];
452  TTarget localScale[tChannels];
453 
454  const TTarget* biasPtr = nullptr;
455  const TTarget* scalePtr = nullptr;
456 
457  if (bias != nullptr && scale != nullptr)
458  {
459  biasPtr = bias;
460  scalePtr = scale;
461  }
462  else
463  {
464  TSource minimalValues[tChannels];
465  TSource maximalValues[tChannels];
466 
467  FrameMinMax::determineMinMaxValues<TSource, tChannels, true /*tIgnoreInfinity*/>(source, width, height, sourcePaddingElements, minimalValues, maximalValues, worker);
468 
469  for (unsigned int c = 0u; c < tChannels; ++c)
470  {
471  localBias[c] = -TTarget(minimalValues[c]);
472  localScale[c] = TTarget(1) / max(epsilon<TTarget>(), TTarget(maximalValues[c]) - TTarget(minimalValues[c]));
473  }
474 
475  biasPtr = localBias;
476  scalePtr = localScale;
477  }
478 
479  ocean_assert(biasPtr != nullptr && scalePtr != nullptr);
480 
481  if (worker != nullptr)
482  {
483  worker->executeFunction(Worker::Function::createStatic(normalizeToFloatSubset<TSource, TTarget, tChannels>, source, target, width, height, biasPtr, scalePtr, sourcePaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 8u, 9u, 20u);
484  }
485  else
486  {
487  normalizeToFloatSubset<TSource, TTarget, tChannels>(source, target, width, height, biasPtr, scalePtr, sourcePaddingElements, targetPaddingElements, 0u, height);
488  }
489 }
490 
491 template <>
492 inline void FrameNormalizer::normalize1ChannelToUint8<float>(const float* source, uint8_t* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
493 {
494  normalize1ChannelFloatToUint8<float>(source, target, width, height, sourcePaddingElements, targetPaddingElements, worker);
495 }
496 
497 template <>
498 inline void FrameNormalizer::normalize1ChannelToUint8<double>(const double* source, uint8_t* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
499 {
500  normalize1ChannelFloatToUint8<double>(source, target, width, height, sourcePaddingElements, targetPaddingElements, worker);
501 }
502 
503 template <typename T>
504 void FrameNormalizer::normalizeLogarithm1ChannelToUint8(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const Scalar octaves, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
505 {
506  ocean_assert(source != nullptr && target != nullptr);
507  ocean_assert(octaves > 0 && octaves <= 10);
508 
509  T minimalValue = NumericT<T>::maxValue();
510  T maximalValue = NumericT<T>::minValue();
511 
512  FrameMinMax::determineMinMaxValues<T, 1u, true /*tIgnoreInfinity*/>(source, width, height, sourcePaddingElements, &minimalValue, &maximalValue, worker);
513 
514  if (std::is_same<T, double>::value || double(maximalValue) - double(minimalValue) >= 1.0e6)
515  {
516  const double range = max(epsilon<double>(), double(maximalValue) - double(minimalValue));
517 
518  if (worker != nullptr)
519  {
520  worker->executeFunction(Worker::Function::createStatic(normalizeLogarithm1ChannelToUint8Subset<T, double>, source, target, width, height, minmax(Numeric::eps(), octaves, Scalar(10)), minimalValue, range, sourcePaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 9u, 10u, 20u);
521  }
522  else
523  {
524  normalizeLogarithm1ChannelToUint8Subset<T, double>(source, target, width, height, minmax(Numeric::eps(), octaves, Scalar(10)), minimalValue, range, sourcePaddingElements, targetPaddingElements, 0u, height);
525  }
526  }
527  else
528  {
529  const T range = max(epsilon<T>(), T(maximalValue - minimalValue));
530 
531  if (worker != nullptr)
532  {
533  worker->executeFunction(Worker::Function::createStatic(normalizeLogarithm1ChannelToUint8Subset<T, T>, source, target, width, height, minmax(Numeric::eps(), octaves, Scalar(10)), minimalValue, range, sourcePaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 9u, 10u, 20u);
534  }
535  else
536  {
537  normalizeLogarithm1ChannelToUint8Subset<T, T>(source, target, width, height, minmax(Numeric::eps(), octaves, Scalar(10)), minimalValue, range, sourcePaddingElements, targetPaddingElements, 0u, height);
538  }
539  }
540 }
541 
542 template <typename TSource, typename TTarget>
543 void FrameNormalizer::normalizeLogarithm1ChannelToFloat(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const Scalar octaves, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
544 {
545  static_assert(std::is_floating_point<TTarget>::value, "Invalid data type!");
546 
547  ocean_assert(source != nullptr && target != nullptr);
548  ocean_assert(octaves > 0 && octaves <= 10);
549 
550  TSource minimalValue = NumericT<TSource>::maxValue();
551  TSource maximalValue = NumericT<TSource>::minValue();
552 
553  FrameMinMax::determineMinMaxValues<TSource, 1u, true /*tIgnoreInfinity*/>(source, width, height, sourcePaddingElements, &minimalValue, &maximalValue, worker);
554 
555  const TTarget range = max(epsilon<TTarget>(), TTarget(maximalValue) - TTarget(minimalValue));
556 
557  if (worker != nullptr)
558  {
559  worker->executeFunction(Worker::Function::createStatic(normalizeLogarithm1ChannelToFloatSubset<TSource, TTarget>, source, target, width, height, minmax(Numeric::eps(), octaves, Scalar(10)), TTarget(minimalValue), range, sourcePaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 9u, 10u, 20u);
560  }
561  else
562  {
563  normalizeLogarithm1ChannelToFloatSubset<TSource, TTarget>(source, target, width, height, minmax(Numeric::eps(), octaves, Scalar(10)), TTarget(minimalValue), range, sourcePaddingElements, targetPaddingElements, 0u, height);
564  }
565 }
566 
567 template <typename T>
568 inline void FrameNormalizer::normalize1ChannelIntegerToUint8(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
569 {
570  static_assert(!std::is_floating_point<T>::value, "Invalid data type!");
571 
572  ocean_assert(source != nullptr && target != nullptr);
573  ocean_assert(width >= 1u && height >= 1u);
574 
575  T minimalValue = NumericT<T>::maxValue();
576  T maximalValue = NumericT<T>::minValue();
577 
578  FrameMinMax::determineMinMaxValues<T, 1u>(source, width, height, sourcePaddingElements, &minimalValue, &maximalValue, worker);
579 
580  if (NumericT<T>::isEqual(minimalValue, maximalValue))
581  {
582  Frame targetFrame(FrameType(width, height, FrameType::FORMAT_Y8, FrameType::ORIGIN_UPPER_LEFT), target, Frame::CM_USE_KEEP_LAYOUT, targetPaddingElements);
583  targetFrame.setValue(0x00);
584  }
585  else
586  {
587  const typename UnsignedTyper<T>::Type range = typename UnsignedTyper<T>::Type(typename NextLargerTyper<T>::Type(maximalValue) - typename NextLargerTyper<T>::Type(minimalValue));
588 
589  if (worker != nullptr)
590  {
591  worker->executeFunction(Worker::Function::createStatic(normalize1ChannelIntegerToUint8Subset<T>, source, target, width, height, minimalValue, range, sourcePaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 8u, 9u, 20u);
592  }
593  else
594  {
595  normalize1ChannelIntegerToUint8Subset<T>(source, target, width, height, minimalValue, range, sourcePaddingElements, targetPaddingElements, 0u, height);
596  }
597  }
598 }
599 
600 template <typename T>
601 inline void FrameNormalizer::normalize1ChannelFloatToUint8(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
602 {
603  static_assert(std::is_floating_point<T>::value, "Invalid data type!");
604 
605  ocean_assert(source != nullptr && target != nullptr);
606  ocean_assert(width >= 1u && height >= 1u);
607 
608  T minimalValue = NumericT<T>::maxValue();
609  T maximalValue = NumericT<T>::minValue();
610 
611  FrameMinMax::determineMinMaxValues<T, 1u, true /*tIgnoreInfinity*/>(source, width, height, sourcePaddingElements, &minimalValue, &maximalValue, worker);
612 
613  if (std::is_same<T, double>::value || double(maximalValue) - double(minimalValue) >= 1.0e6)
614  {
615  const double range = max(epsilon<double>(), double(maximalValue) - double(minimalValue));
616 
617  if (worker != nullptr)
618  {
619  worker->executeFunction(Worker::Function::createStatic(normalize1ChannelFloatToUint8Subset<T, double>, source, target, width, height, minimalValue, range, sourcePaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 8u, 9u, 20u);
620  }
621  else
622  {
623  normalize1ChannelFloatToUint8Subset<T, double>(source, target, width, height, minimalValue, range, sourcePaddingElements, targetPaddingElements, 0u, height);
624  }
625  }
626  else
627  {
628  const T range = max(epsilon<T>(), T(maximalValue - minimalValue));
629 
630  if (worker != nullptr)
631  {
632  worker->executeFunction(Worker::Function::createStatic(normalize1ChannelFloatToUint8Subset<T, T>, source, target, width, height, minimalValue, range, sourcePaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 8u, 9u, 20u);
633  }
634  else
635  {
636  normalize1ChannelFloatToUint8Subset<T, T>(source, target, width, height, minimalValue, range, sourcePaddingElements, targetPaddingElements, 0u, height);
637  }
638  }
639 }
640 
641 template <typename TSource, typename TTarget>
642 bool FrameNormalizer::normalizeToFloat(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const unsigned int channels, const TTarget* bias, const TTarget* scale, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
643 {
644  ocean_assert(channels != 0u && channels <= 4u);
645 
646  switch (channels)
647  {
648  case 1u:
649  normalizeToFloat<TSource, TTarget, 1u>(source, target, width, height, bias, scale, sourcePaddingElements, targetPaddingElements, worker);
650  return true;
651 
652  case 2u:
653  normalizeToFloat<TSource, TTarget, 2u>(source, target, width, height, bias, scale, sourcePaddingElements, targetPaddingElements, worker);
654  return true;
655 
656  case 3u:
657  normalizeToFloat<TSource, TTarget, 3u>(source, target, width, height, bias, scale, sourcePaddingElements, targetPaddingElements, worker);
658  return true;
659 
660  case 4u:
661  normalizeToFloat<TSource, TTarget, 4u>(source, target, width, height, bias, scale, sourcePaddingElements, targetPaddingElements, worker);
662  return true;
663 
664  default:
665  ocean_assert(false && "Invalid number of channels!");
666  return false;
667  }
668 
669  ocean_assert(false && "Should never be here");
670  return false;
671 }
672 
673 template <typename T>
674 void FrameNormalizer::normalize1ChannelIntegerToUint8Subset(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const T minimalValue, const typename UnsignedTyper<T>::Type range, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
675 #if defined(OCEAN_CLANG_VERSION) && OCEAN_CLANG_VERSION > 0
676  __attribute__((no_sanitize("signed-integer-overflow")))
677 #endif
678 {
679  static_assert(!std::is_floating_point<T>::value, "Invalid data type!");
680 
681  ocean_assert(source != nullptr && target != nullptr);
682  ocean_assert_and_suppress_unused(firstRow + numberRows <= height, height);
683 
684  const unsigned int sourceStrideElements = width + sourcePaddingElements;
685  const unsigned int targetStrideElements = width + targetPaddingElements;
686 
687  typedef typename UnsignedTyper<T>::Type UnsignedType;
688  typedef typename DataTypeMultiple255<UnsignedType>::Type NextLargerUnsignedType;
689 
690  const NextLargerUnsignedType range_2 = NextLargerUnsignedType(range) / NextLargerUnsignedType(2);
691 
692  source += firstRow * sourceStrideElements;
693  target += firstRow * targetStrideElements;
694 
695  for (unsigned int nRow = firstRow; nRow < firstRow + numberRows; ++nRow)
696  {
697  for (unsigned int x = 0u; x < width; ++x)
698  {
699  ocean_assert((std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value) || (double(*source) >= double(minimalValue) && double(*source) <= double(minimalValue) + double(range)));
700  ocean_assert(double(NextLargerUnsignedType(UnsignedType(*source - minimalValue)) * NextLargerUnsignedType(0xFF) + range_2) / double(NextLargerUnsignedType(range)) >= 0.0);
701  ocean_assert(double(NextLargerUnsignedType(UnsignedType(*source - minimalValue)) * NextLargerUnsignedType(0xFF) + range_2) / double(NextLargerUnsignedType(range)) < 256.0);
702 
703  *target++ = uint8_t((NextLargerUnsignedType(UnsignedType(*source++ - minimalValue)) * NextLargerUnsignedType(0xFF) + range_2) / NextLargerUnsignedType(range));
704  }
705 
706  source += sourcePaddingElements;
707  target += targetPaddingElements;
708  }
709 }
710 
711 template <typename T, typename TRange>
712 void FrameNormalizer::normalize1ChannelFloatToUint8Subset(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const T minimalValue, const TRange range, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
713 {
714  static_assert(std::is_floating_point<TRange>::value, "Invalid data type!");
715  static_assert(sizeof(T) <= sizeof(TRange), "TRange range must not be smaller than T");
716 
717  ocean_assert(source != nullptr && target != nullptr);
718  ocean_assert_and_suppress_unused(firstRow + numberRows <= height, height);
719 
720  const unsigned int sourceStrideElements = width + sourcePaddingElements;
721  const unsigned int targetStrideElements = width + targetPaddingElements;
722 
723  /*
724  * Value range mapping:
725  *
726  * [minValue, maxValue], maxValue = minValue + range
727  * [ 0 | 1 | 2 | ... ... | 254 | 255 ]
728  */
729 
730  const TRange invRange = TRange(255.999) / range; // generously staying below 256 to avoid that we run out of the value range [0, 256) below
731 
732  const TRange maxValueThreshold = TRange(minimalValue) + range + range * TRange(0.0001);
733 
734  source += firstRow * sourceStrideElements;
735  target += firstRow * targetStrideElements;
736 
737  for (unsigned int nRow = firstRow; nRow < firstRow + numberRows; ++nRow)
738  {
739  for (unsigned int x = 0u; x < width; ++x)
740  {
741  if (std::is_floating_point<T>::value && NumericT<T>::isInf(*source)) // +/- inf is ignored, so mapping -inf to 0, and +inf to 255
742  {
743  if (*source > T(0))
744  {
745  *target = uint8_t(255);
746  }
747  else
748  {
749  *target = uint8_t(0);
750  }
751  }
752  else
753  {
754  ocean_assert_and_suppress_unused(*source >= minimalValue && *source <= maxValueThreshold, maxValueThreshold);
755 
756  const TRange normalizedValue = TRange(*source - minimalValue) * invRange;
757 
758  ocean_assert(normalizedValue >= TRange(0));
759  ocean_assert(normalizedValue < TRange(256));
760 
761  *target = uint8_t(normalizedValue);
762  }
763 
764  ++target;
765  ++source;
766  }
767 
768  source += sourcePaddingElements;
769  target += targetPaddingElements;
770  }
771 }
772 
773 template <typename TSource, typename TTarget, unsigned int tChannels>
774 void FrameNormalizer::normalizeToFloatSubset(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const TTarget* bias, const TTarget* scale, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
775 {
776  static_assert(std::is_floating_point<TTarget>::value, "Invalid data type!");
777  static_assert(tChannels != 0u, "Invalid number of channels");
778 
779  ocean_assert(source != nullptr && target != nullptr);
780  ocean_assert(width >= 1u && height >= 1u);
781  ocean_assert(bias != nullptr && scale != nullptr);
782  ocean_assert_and_suppress_unused(firstRow + numberRows <= height, height);
783 
784  const unsigned int sourceStrideElements = width * tChannels + sourcePaddingElements;
785  const unsigned int targetStrideElements = width * tChannels + targetPaddingElements;
786 
787  source += firstRow * sourceStrideElements;
788  target += firstRow * targetStrideElements;
789 
790  for (unsigned int nRow = firstRow; nRow < firstRow + numberRows; ++nRow)
791  {
792  for (unsigned int x = 0u; x < width; ++x)
793  {
794  for (unsigned int c = 0u; c < tChannels; ++c)
795  {
796  if (std::is_floating_point<TSource>::value && NumericT<TSource>::isInf(*source)) // +/- inf is ignored, so we preserve the value
797  {
798  *target = TTarget(*source);
799  }
800  else
801  {
802  *target = (TTarget(*source) + bias[c]) * scale[c];
803  }
804 
805  ++target;
806  ++source;
807  }
808  }
809 
810  source += sourcePaddingElements;
811  target += targetPaddingElements;
812  }
813 }
814 
815 template <typename T, typename TRange>
816 void FrameNormalizer::normalizeLogarithm1ChannelToUint8Subset(const T* source, uint8_t* target, const unsigned int width, const unsigned int height, const Scalar octaves, const T minimalValue, const TRange range, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
817 {
818  ocean_assert(octaves > 0 && octaves <= 10);
819  ocean_assert(source && target);
820  ocean_assert_and_suppress_unused(firstRow + numberRows <= height, height);
821 
822  typedef typename FloatType<TRange>::Type FloatType;
823 
824  const unsigned int sourceStrideElements = width + sourcePaddingElements;
825  const unsigned int targetStrideElements = width + targetPaddingElements;
826 
827  const FloatType factor = FloatType(Numeric::pow(10, octaves) - 1) / FloatType(range);
828  const FloatType normalization = FloatType(255.999) / FloatType(octaves); // generously staying below 256 to avoid that we run out of the value range [0, 256) below, see normalize1ChannelFloatToUint8Subset()
829 
830  source += firstRow * sourceStrideElements;
831  target += firstRow * targetStrideElements;
832 
833  for (unsigned int nRow = firstRow; nRow < firstRow + numberRows; ++nRow)
834  {
835  for (unsigned int x = 0u; x < width; ++x)
836  {
837  if (std::is_floating_point<T>::value && NumericT<T>::isInf(*source)) // +/- inf is ignored, so mapping -inf to 0, and +inf to 255
838  {
839  if (*source > T(0))
840  {
841  *target = uint8_t(255);
842  }
843  else
844  {
845  *target = uint8_t(0);
846  }
847  }
848  else
849  {
850  ocean_assert(*source >= minimalValue && FloatType(*source) <= FloatType(minimalValue) + FloatType(range) + NumericT<FloatType>::eps());
851  ocean_assert(NumericT<FloatType>::log10(FloatType(1 + FloatType(*source - minimalValue) * factor)) * normalization >= FloatType(0));
852  ocean_assert(NumericT<FloatType>::log10(FloatType(1 + FloatType(*source - minimalValue) * factor)) * normalization < FloatType(256));
853 
854  *target = (uint8_t)(NumericT<FloatType>::log10(FloatType(1 + FloatType(*source - minimalValue) * factor)) * normalization);
855  }
856 
857  ++target;
858  ++source;
859  }
860 
861  source += sourcePaddingElements;
862  target += targetPaddingElements;
863  }
864 }
865 
866 template <typename TSource, typename TTarget>
867 void FrameNormalizer::normalizeLogarithm1ChannelToFloatSubset(const TSource* source, TTarget* target, const unsigned int width, const unsigned int height, const Scalar octaves, const TTarget minimalValue, const TTarget range, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
868 {
869  static_assert(std::is_floating_point<TTarget>::value, "Invalid data type!");
870 
871  ocean_assert(octaves > 0 && octaves <= 10);
872  ocean_assert(source && target);
873  ocean_assert_and_suppress_unused(firstRow + numberRows <= height, height);
874 
875  const unsigned int sourceStrideElements = width + sourcePaddingElements;
876  const unsigned int targetStrideElements = width + targetPaddingElements;
877 
878  const TTarget factor = TTarget(Numeric::pow(10, octaves) - 1) / TTarget(range);
879  const TTarget normalization = TTarget(1) / TTarget(octaves);
880 
881  source += firstRow * sourceStrideElements;
882  target += firstRow * targetStrideElements;
883 
884  for (unsigned int nRow = firstRow; nRow < firstRow + numberRows; ++nRow)
885  {
886  for (unsigned int x = 0u; x < width; ++x)
887  {
888  if (std::is_floating_point<TSource>::value && NumericT<TSource>::isInf(*source)) // +/- inf is ignored, so we preserve the value
889  {
890  *target = TTarget(*source);
891  }
892  else
893  {
894  ocean_assert(TTarget(*source) >= minimalValue && TTarget(*source) <= minimalValue + range + NumericT<TTarget>::eps());
895  ocean_assert(NumericT<TTarget>::log10(TTarget(1) + (TTarget(*source) - minimalValue) * factor) * normalization >= TTarget(0));
896  ocean_assert(NumericT<TTarget>::log10(TTarget(1) + (TTarget(*source) - minimalValue) * factor) * normalization <= TTarget(1) + NumericT<TTarget>::eps());
897 
898  *target = NumericT<TTarget>::log10(TTarget(1) + (TTarget(*source) - minimalValue) * factor) * normalization;
899  }
900 
901  ++target;
902  ++source;
903  }
904 
905  source += sourcePaddingElements;
906  target += targetPaddingElements;
907  }
908 }
909 
910 template <typename T>
912 {
913  return T(1);
914 }
915 
916 template <>
917 inline float FrameNormalizer::epsilon<float>()
918 {
919  return NumericT<float>::eps();
920 }
921 
922 template <>
923 inline double FrameNormalizer::epsilon<double>()
924 {
925  return NumericT<double>::eps();
926 }
927 
928 }
929 
930 }
931 
932 #endif // META_OCEAN_CV_FRAME_NORMALIZER_H
static void determineMinMaxValues(const T *frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, T *minimalValues, T *maximalValues, Worker *worker=nullptr)
Determines the minimal and maximal pixel values in a given frame.
Definition: FrameMinMax.h:544
This class implements functions normalizing frames.
Definition: FrameNormalizer.h:34
static bool normalizeToUint8(Frame &frame, Worker *worker=nullptr)
Normalizes a given 1-channel frame linearly to a uint8 image.
static void normalizeLogarithm1ChannelToFloat(const TSource *source, TTarget *target, const unsigned int width, const unsigned int height, const Scalar octaves, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Normalizes a given 1 channel frame to float values with value range [0, 1] logarithmically.
Definition: FrameNormalizer.h:543
static bool normalizeToFloat32(const Frame &source, Frame &target, Worker *worker=nullptr)
Normalizes each channel of a frame linearly to a float32 image to the range [0, 1].
static void normalize1ChannelFloatToUint8(const T *source, uint8_t *target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Normalizes a given 1 channel float frame to the 8 bit value range [0, 255] linearly.
Definition: FrameNormalizer.h:601
static void normalizeLogarithm1ChannelToUint8Subset(const T *source, uint8_t *target, const unsigned int width, const unsigned int height, const Scalar octaves, const T minimalValue, const TRange range, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
Normalizes a subset of a given 1 channel frame to the 8 bit value range [0, 255] logarithmically.
Definition: FrameNormalizer.h:816
static void normalize1ChannelIntegerToUint8(const T *source, uint8_t *target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Normalizes a given 1 channel integer frame to the 8 bit value range [0, 255] linearly.
Definition: FrameNormalizer.h:568
static void normalize1ChannelIntegerToUint8Subset(const T *source, uint8_t *target, const unsigned int width, const unsigned int height, const T minimalValue, const typename UnsignedTyper< T >::Type range, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
Normalizes a subset of a given 1 channel frame to the 8 bit value range [0, 255] linearly.
Definition: FrameNormalizer.h:674
static void normalize1ChannelToUint8(const T *source, uint8_t *target, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Normalizes a given 1 channel frame to the 8 bit value range [0, 255] linearly.
Definition: FrameNormalizer.h:437
static bool normalizeToFloat32(const Frame &source, Frame &target, const float *bias, const float *scale, Worker *worker=nullptr)
Normalizes a given frame linearly to a float32 image.
static T epsilon()
Returns the smallest epsilon larger than zero for a specific data type.
Definition: FrameNormalizer.h:911
static void normalizeToFloat(const TSource *source, TTarget *target, const unsigned int width, const unsigned int height, const TTarget *bias, const TTarget *scale, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Normalizes a frame to float values by using predefined per-channel bias and scaling values.
Definition: FrameNormalizer.h:443
static bool normalizeLogarithmToFloat32(Frame &frame, const Scalar octaves=5.0f, Worker *worker=nullptr)
Normalizes a given frame linearly to a float32 image.
static bool normalizeToFloat32(Frame &frame, Worker *worker=nullptr)
Normalizes a given 1-channel frame linearly to a float32 image.
static void normalizeToFloatSubset(const TSource *source, TTarget *target, const unsigned int width, const unsigned int height, const TTarget *bias, const TTarget *scale, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
Normalizes a subset of rows of a frame to float values by using predefined per-channel bias and scali...
Definition: FrameNormalizer.h:774
static bool normalizeLogarithmToUint8(Frame &frame, const Scalar octaves=5.0f, Worker *worker=nullptr)
Normalizes a given frame linearly to a uint8 image.
static bool normalizeLogarithmToUint8(const Frame &source, Frame &target, const Scalar octaves=5.0f, Worker *worker=nullptr)
Normalizes a given frame logarithmically to a uint8 image.
static void normalizeLogarithm1ChannelToUint8(const T *source, uint8_t *target, const unsigned int width, const unsigned int height, const Scalar octaves, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Normalizes a given 1 channel frame to the 8 bit value range [0, 255] logarithmically.
Definition: FrameNormalizer.h:504
static bool normalizeToUint8(const Frame &source, Frame &target, Worker *worker=nullptr)
Normalizes a given 1-channel frame linearly to a uint8 image.
static bool normalizeLogarithmToFloat32(const Frame &source, Frame &target, const Scalar octaves=5.0f, Worker *worker=nullptr)
Normalizes a given frame logarithmically to a float32 image.
static void normalizeLogarithm1ChannelToFloatSubset(const TSource *source, TTarget *target, const unsigned int width, const unsigned int height, const Scalar octaves, const TTarget minimalValue, const TTarget range, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
Normalizes a subset of a given 1 channel frame to the value range [0, 1] logarithmically.
Definition: FrameNormalizer.h:867
static void normalize1ChannelFloatToUint8Subset(const T *source, uint8_t *target, const unsigned int width, const unsigned int height, const T minimalValue, const TRange range, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
Normalizes a subset of a given 1 channel frame to the 8 bit value range [0, 255] linearly.
Definition: FrameNormalizer.h:712
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:1760
@ CM_USE_KEEP_LAYOUT
The source memory is used only, no copy is created, the padding layout is preserved.
Definition: Frame.h:1769
bool setValue(const uint8_t value, const unsigned int planeIndex=0u, const bool skipPaddingData=true)
Sets the memory of the frame to a specified byte value (the memory of one plane).
Definition of a frame type composed by the frame dimension, pixel format and pixel origin.
Definition: Frame.h:30
@ FORMAT_Y8
Pixel format for grayscale images with byte order Y and 8 bits per pixel.
Definition: Frame.h:594
@ ORIGIN_UPPER_LEFT
The first pixel lies in the upper left corner, the last pixel in the lower right corner.
Definition: Frame.h:1018
T Type
Definition of the data type for the next larger data type.
Definition: DataType.h:255
This class provides basic numeric functionalities.
Definition: Numeric.h:57
static constexpr T minValue()
Returns the min scalar value.
Definition: Numeric.h:3250
static T pow(const T x, const T y)
Returns x raised to the power of y.
Definition: Numeric.h:1860
static T log10(const T value)
Returns the logarithm to base 10 of a given value.
Definition: Numeric.h:1711
static constexpr T eps()
Returns a small epsilon.
static constexpr T maxValue()
Returns the max scalar value.
Definition: Numeric.h:3244
T Type
Definition of the unsigned data type, if existing.
Definition: DataType.h:339
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.
T minmax(const T &lowerBoundary, const T &value, const T &upperBoundary)
This function fits a given parameter into a specified value range.
Definition: base/Utilities.h:903
float Scalar
Definition of a scalar type.
Definition: Math.h:128
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15
float Type
Definition: FrameNormalizer.h:433
double Type
Definition: FrameNormalizer.h:427
Helper struct allowing to determine the type able to store data multiplied by 255.
Definition: FrameNormalizer.h:54
NextLargerTyper< T >::Type Type
The matching datatype which is able to store all values in T multiplied by 255.
Definition: FrameNormalizer.h:56
double Type
Definition: FrameNormalizer.h:421
Helper struct allowing to determine the necessary float type for a given data type.
Definition: FrameNormalizer.h:43
float Type
The matching float type for T, is double if T is double, otherwise always float.
Definition: FrameNormalizer.h:45