Ocean
Loading...
Searching...
No Matches
FrameNorm.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_NORM_H
9#define META_OCEAN_CV_FRAME_NORM_H
10
11#include "ocean/cv/CV.h"
12
13#include "ocean/math/Numeric.h"
14
15namespace Ocean
16{
17
18namespace CV
19{
20
21/**
22 * This class implements functions allowing to determine norms of images e.g, a L2 norm.
23 * @ingroup cv
24 */
25class OCEAN_CV_EXPORT FrameNorm
26{
27 public:
28
29 /**
30 * Determines the L2 norm (square root of summed squares) of given data.
31 * This function is actually a wrapper around normL2() - and applies the sqrt calculation in addition.
32 * @param data The data for which the norm value will be determined, must be valid
33 * @param size The size of the given data in elements, with range [1, infinity)
34 * @return The resulting L2 norm
35 * @tparam T Data type of each value, e.g., 'uint8_t' or 'float'
36 * @tparam TNorm The data type of the resulting norm (and the intermediate sum), e.g., 'uint32_t' or 'double'
37 * @see squaredNormL2().
38 */
39 template <typename T, typename TNorm>
40 static TNorm normL2(const T* data, const size_t size);
41
42 /**
43 * Determines the L2 norm (square root of summed squares) of a given frame allowing to specify a padding to enable the application of e.g., sub-frames.
44 * This function is actually a wrapper around normL2() - and applies the sqrt calculation in addition.
45 * @param frame The data of the frame for which the norm value will be determined, must be valid
46 * @param width The width of the given frame in pixel, with range [1, infinity)
47 * @param height The height of the given frame in pixel, with range [1, infinity)
48 * @param framePaddingElements The number of padding elements at the end of each row, in elements, with range [0, infinity)
49 * @return The resulting L2 norm
50 * @tparam T Data type of each value, e.g., 'unsigned char' or 'float'
51 * @tparam TNorm The data type of the resulting norm (and the intermediate sum), e.g., 'unsigned int' or 'double'
52 * @see squaredNormL2().
53 */
54 template <typename T, typename TNorm>
55 static TNorm normL2(const T* frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements);
56
57 /**
58 * Determines the squared L2 norm (summed squares) of given data.
59 * @param data The data for which the norm value will be determined, must be valid
60 * @param size The size of the given data in elements, with range [1, infinity)
61 * @return The resulting L2 norm
62 * @tparam T Data type of each value, e.g., 'uint8_t' or 'float'
63 * @tparam TNorm The data type of the resulting norm (and the intermediate sum), e.g., 'uint32_t' or 'double'
64 * @see normL2().
65 */
66 template <typename T, typename TNorm>
67 static TNorm squaredNormL2(const T* data, const size_t size);
68
69 /**
70 * Determines the squared L2 norm (summed squares) of a given frame allowing to specify a padding to enable the application of e.g., sub-frames.
71 * @param frame The data of the frame for which the norm value will be determined, must be valid
72 * @param width The width of the given frame in pixel, with range [1, infinity)
73 * @param height The height of the given frame in pixel, with range [1, infinity)
74 * @param framePaddingElements The number of padding elements at the end of each row, in elements, with range [0, infinity)
75 * @return The resulting L2 norm
76 * @tparam T Data type of each value, e.g., 'unsigned char' or 'float'
77 * @tparam TNorm The data type of the resulting norm (and the intermediate sum), e.g., 'unsigned int' or 'double'
78 * @see normL2().
79 */
80 template <typename T, typename TNorm>
81 static TNorm squaredNormL2(const T* frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements);
82};
83
84template <typename T, typename TNorm>
85TNorm FrameNorm::normL2(const T* data, const size_t size)
86{
87 ocean_assert(data != nullptr);
88 ocean_assert(size != 0);
89
90 return NumericT<TNorm>::sqrt(squaredNormL2<T, TNorm>(data, size));
91}
92
93template <typename T, typename TNorm>
94TNorm FrameNorm::normL2(const T* frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements)
95{
96 ocean_assert(frame != nullptr);
97 ocean_assert(width != 0u && height != 0u);
98
99 return NumericT<TNorm>::sqrt(squaredNormL2<T, TNorm>(frame, width, height, framePaddingElements));
100}
101
102template <typename T, typename TNorm>
103TNorm FrameNorm::squaredNormL2(const T* data, const size_t size)
104{
105 ocean_assert(data != nullptr);
106 ocean_assert(size != 0);
107
108 // we will calculate four values in parallel
109 // thus, the compiler will have a direct hint to use SSE/NEON
110 // so that we can avoid to make individual implementations...
111
112 TNorm result0 = TNorm(0);
113 TNorm result1 = TNorm(0);
114 TNorm result2 = TNorm(0);
115 TNorm result3 = TNorm(0);
116
117 ocean_assert(NumericT<ptrdiff_t>::isInsideValueRange(size));
118
119 ptrdiff_t n = 0;
120
121 for (n = 0; n < ptrdiff_t(size) - 3; n += 4)
122 {
123 result0 += TNorm(data[n + 0] * data[n + 0]);
124 result1 += TNorm(data[n + 1] * data[n + 1]);
125 result2 += TNorm(data[n + 2] * data[n + 2]);
126 result3 += TNorm(data[n + 3] * data[n + 3]);
127 }
128
129 TNorm result = result0 + result1 + result2 + result3;
130
131 // now we have to handle the last (at most) three elements
132
133 while (n < ptrdiff_t(size))
134 {
135 result += TNorm(data[n] * data[n]);
136
137 ++n;
138 }
139
140 return result;
141}
142
143template <typename T, typename TNorm>
144TNorm FrameNorm::squaredNormL2(const T* frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements)
145{
146 ocean_assert(frame != nullptr);
147 ocean_assert(width != 0u && height != 0u);
148
149 if (framePaddingElements == 0u)
150 {
151 return squaredNormL2<T, TNorm>(frame, width * height);
152 }
153
154 // we will calculate four values in parallel
155 // thus, the compiler will have a direct hint to use SSE/NEON
156 // so that we can avoid to make individual implementations...
157
158 TNorm result0 = TNorm(0);
159 TNorm result1 = TNorm(0);
160 TNorm result2 = TNorm(0);
161 TNorm result3 = TNorm(0);
162
163 ptrdiff_t x;
164
165 for (unsigned int y = 0u; y < height; ++y)
166 {
167 for (x = 0; x < ptrdiff_t(width) - 3; x += 4)
168 {
169 result0 += TNorm(frame[x + 0] * frame[x + 0]);
170 result1 += TNorm(frame[x + 1] * frame[x + 1]);
171 result2 += TNorm(frame[x + 2] * frame[x + 2]);
172 result3 += TNorm(frame[x + 3] * frame[x + 3]);
173 }
174
175 if (x + 0 < ptrdiff_t(width))
176 {
177 result0 += TNorm(frame[x + 0] * frame[x + 0]);
178 }
179
180 if (x + 1 < ptrdiff_t(width))
181 {
182 result1 += TNorm(frame[x + 1] * frame[x + 1]);
183 }
184
185 if (x + 2 < ptrdiff_t(width))
186 {
187 result2 += TNorm(frame[x + 2] * frame[x + 2]);
188 }
189
190 frame += width + framePaddingElements;
191 }
192
193 return result0 + result1 + result2 + result3;
194}
195
196}
197
198}
199
200#endif // META_OCEAN_CV_FRAME_NORM_H
This class implements functions allowing to determine norms of images e.g, a L2 norm.
Definition FrameNorm.h:26
static TNorm normL2(const T *data, const size_t size)
Determines the L2 norm (square root of summed squares) of given data.
Definition FrameNorm.h:85
static TNorm squaredNormL2(const T *data, const size_t size)
Determines the squared L2 norm (summed squares) of given data.
Definition FrameNorm.h:103
This class provides basic numeric functionalities.
Definition Numeric.h:57
static T sqrt(const T value)
Returns the square root of a given value.
Definition Numeric.h:1533
The namespace covering the entire Ocean framework.
Definition Accessor.h:15