8#ifndef META_OCEAN_CV_ADVANCED_ADVANCED_FRAME_INTERPOLATOR_BILINEAR_BASE_H
9#define META_OCEAN_CV_ADVANCED_ADVANCED_FRAME_INTERPOLATOR_BILINEAR_BASE_H
48 template <
unsigned int tChannels,
unsigned int tPatchSize, PixelCenter tPixelCenter = PC_TOP_LEFT,
typename TScalar = Scalar>
65 template <
unsigned int tChannels, PixelCenter tPixelCenter = PC_TOP_LEFT,
typename TScalar = Scalar>
66 static void interpolatePatch8BitPerChannel(
const uint8_t*
const image,
const unsigned int width,
const unsigned int imagePaddingElements, uint8_t* buffer,
const VectorT2<TScalar>& position,
const unsigned int patchWidth,
const unsigned int patchHeight);
80 template <
unsigned int tChannels>
95 template <
unsigned int tChannels,
unsigned int tPatchSize>
107 template <
unsigned int tChannels>
108 static inline void interpolatePixel8BitPerChannel(
const uint8_t* sourceTopLeft,
const uint8_t* sourceBottomLeft, uint8_t* target,
const unsigned int xFactor,
const unsigned int yFactor);
121 template <
unsigned int tChannels>
122 static inline void interpolatePixel8BitPerChannel(
const uint8_t* sourceTopLeft,
const uint8_t* sourceBottomLeft, uint8_t* target,
const unsigned int tx_ty_,
const unsigned int txty_,
const unsigned int tx_ty,
const unsigned int txty);
125template <
unsigned int tChannels,
unsigned int tPatchSize, PixelCenter tPixelCenter,
typename TScalar>
128 static_assert(tChannels >= 1u,
"Invalid channel number!");
129 static_assert(tPatchSize % 2u == 1u,
"The patch size must be odd!");
131 ocean_assert(image !=
nullptr && buffer !=
nullptr);
132 ocean_assert(tPatchSize + 1u <= width);
134 constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
136 const unsigned int imageStrideElements = width * tChannels + imagePaddingElements;
140 ocean_assert(shiftedPosition.
x() >= TScalar(tPatchSize_2) && shiftedPosition.
y() >= TScalar(tPatchSize_2));
141 ocean_assert(shiftedPosition.
x() < TScalar(width - tPatchSize_2 - 1u));
143 const unsigned int left = (
unsigned int)(shiftedPosition.
x()) - tPatchSize_2;
144 const unsigned int top = (
unsigned int)(shiftedPosition.
y()) - tPatchSize_2;
146 ocean_assert(left + tPatchSize < width);
148 const TScalar tx = shiftedPosition.
x() - TScalar(
int(shiftedPosition.
x()));
149 ocean_assert(tx >= TScalar(0) && tx <= TScalar(1));
150 const unsigned int factorRight = (
unsigned int)(tx * TScalar(128) + TScalar(0.5));
151 const unsigned int factorLeft = 128u - factorRight;
153 const TScalar ty = shiftedPosition.
y() - TScalar(
int(shiftedPosition.
y()));
154 ocean_assert(ty >= 0 && ty <= 1);
155 const unsigned int factorBottom = (
unsigned int)(ty * TScalar(128) + TScalar(0.5));
156 const unsigned int factorTop = 128u - factorBottom;
158 const unsigned int factorTopLeft = factorLeft * factorTop;
159 const unsigned int factorTopRight = factorRight * factorTop;
160 const unsigned int factorBottomLeft = factorLeft * factorBottom;
161 const unsigned int factorBottomRight = factorRight * factorBottom;
163 const uint8_t* imageTop = image + top * imageStrideElements + left * tChannels;
164 const uint8_t* imageBottom = imageTop + imageStrideElements;
166 const uint8_t*
const imageEnd = imageTop + imageStrideElements * tPatchSize;
168 const unsigned int imageRowOffset = imageStrideElements - tChannels * tPatchSize;
170 while (imageTop != imageEnd)
172 ocean_assert(imageTop < imageEnd);
173 ocean_assert((imageTop - image) % imageStrideElements == tChannels * left);
175 const uint8_t*
const imageEndRow = imageTop + tChannels * tPatchSize;
177 while (imageTop != imageEndRow)
179 ocean_assert(imageTop < imageEnd);
180 ocean_assert(imageTop < imageEndRow);
182 for (
unsigned int n = 0u; n < tChannels; ++n)
184 *buffer++ = uint8_t((imageTop[n] * factorTopLeft + imageTop[n + tChannels] * factorTopRight + imageBottom[n] * factorBottomLeft + imageBottom[n + tChannels] * factorBottomRight + 8192u) / 16384u);
187 imageTop += tChannels;
188 imageBottom += tChannels;
191 imageTop += imageRowOffset;
192 imageBottom += imageRowOffset;
196template <
unsigned int tChannels, PixelCenter tPixelCenter,
typename TScalar>
199 static_assert(tChannels >= 1u,
"Invalid channel number!");
201 ocean_assert(image !=
nullptr && buffer !=
nullptr);
202 ocean_assert(patchWidth + 1u <= width);
204 const unsigned int patchWidth_2 = patchWidth / 2u;
205 const unsigned int patchHeight_2 = patchHeight / 2u;
207 const unsigned int imageStrideElements = width * tChannels + imagePaddingElements;
211 ocean_assert(shiftedPosition.
x() >= TScalar(patchWidth_2) && shiftedPosition.
y() >= TScalar(patchHeight_2));
212 ocean_assert(shiftedPosition.
x() < TScalar(width - patchWidth_2 - 1u));
214 const unsigned int left = (
unsigned int)(shiftedPosition.
x()) - patchWidth_2;
215 const unsigned int top = (
unsigned int)(shiftedPosition.
y()) - patchHeight_2;
217 ocean_assert(left + patchWidth < width);
219 const TScalar tx = shiftedPosition.
x() - TScalar(
int(shiftedPosition.
x()));
220 ocean_assert(tx >= TScalar(0) && tx <= TScalar(1));
221 const unsigned int factorRight = (
unsigned int)(tx * TScalar(128) + TScalar(0.5));
222 const unsigned int factorLeft = 128u - factorRight;
224 const TScalar ty = shiftedPosition.
y() - TScalar(
int(shiftedPosition.
y()));
225 ocean_assert(ty >= 0 && ty <= 1);
226 const unsigned int factorBottom = (
unsigned int)(ty * TScalar(128) + TScalar(0.5));
227 const unsigned int factorTop = 128u - factorBottom;
229 const unsigned int factorTopLeft = factorLeft * factorTop;
230 const unsigned int factorTopRight = factorRight * factorTop;
231 const unsigned int factorBottomLeft = factorLeft * factorBottom;
232 const unsigned int factorBottomRight = factorRight * factorBottom;
234 const uint8_t* imageTop = image + top * imageStrideElements + left * tChannels;
235 const uint8_t* imageBottom = imageTop + imageStrideElements;
237 const uint8_t*
const imageEnd = imageTop + imageStrideElements * patchHeight;
239 const unsigned int imageRowOffset = imageStrideElements - tChannels * patchWidth;
241 while (imageTop != imageEnd)
243 ocean_assert(imageTop < imageEnd);
244 ocean_assert((imageTop - image) % imageStrideElements == tChannels * left);
246 const uint8_t*
const imageEndRow = imageTop + tChannels * patchWidth;
248 while (imageTop != imageEndRow)
250 ocean_assert(imageTop < imageEnd);
251 ocean_assert(imageTop < imageEndRow);
253 for (
unsigned int n = 0u; n < tChannels; ++n)
255 *buffer++ = uint8_t((imageTop[n] * factorTopLeft + imageTop[n + tChannels] * factorTopRight + imageBottom[n] * factorBottomLeft + imageBottom[n + tChannels] * factorBottomRight + 8192u) / 16384u);
258 imageTop += tChannels;
259 imageBottom += tChannels;
262 imageTop += imageRowOffset;
263 imageBottom += imageRowOffset;
267template <
unsigned int tChannels>
270 static_assert(tChannels >= 1u,
"Invalid channel number!");
272 ocean_assert(frame !=
nullptr && buffer !=
nullptr);
273 ocean_assert(patchSize >= 1u && patchSize % 2u == 1u);
275 const unsigned int patchSize_2 = patchSize / 2u;
277 ocean_assert(width >= patchSize_2 + 1u && height >= patchSize_2 + 1u);
278 ocean_assert(position.
x() >=
Scalar(0) && position.
y() >=
Scalar(0));
279 ocean_assert(position.
x() <
Scalar(width) && position.
y() <
Scalar(height));
281 const int left = int(position.
x()) - int(patchSize_2);
282 const int top = int(position.
y()) - int(patchSize_2);
285 ocean_assert(tx >= 0 && tx <= 1);
286 const unsigned int txi = (
unsigned int)(tx *
Scalar(128) +
Scalar(0.5));
287 const unsigned int txi_ = 128u - txi;
290 ocean_assert(ty >= 0 && ty <= 1);
291 const unsigned int tyi = (
unsigned int)(ty *
Scalar(128) +
Scalar(0.5));
292 const unsigned int tyi_ = 128u - tyi;
294 const unsigned int tx_y_ = txi_ * tyi_;
295 const unsigned int txy_ = txi * tyi_;
296 const unsigned int tx_y = txi_ * tyi;
297 const unsigned int txy = txi * tyi;
299 const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
301 for (
unsigned int y = 0u; y < patchSize; ++y)
303 const int yTop = top + int(y);
304 const int yBottom = yTop + 1;
309 for (
unsigned int x = 0u; x < patchSize; ++x)
311 const int xLeft = left + int(x);
312 const int xRight = xLeft + 1;
314 unsigned int xLeftIndex;
315 unsigned int xRightIndex;
317 if ((
unsigned int)(xLeft) < width && (
unsigned int)(xRight) < width)
319 xLeftIndex = (
unsigned int)(xLeft);
320 xRightIndex = (
unsigned int)(xRight);
328 const uint8_t*
const pixelTopLeft = rowTop + xLeftIndex * tChannels;
329 const uint8_t*
const pixelTopRight = rowTop + xRightIndex * tChannels;
330 const uint8_t*
const pixelBottomLeft = rowBottom + xLeftIndex * tChannels;
331 const uint8_t*
const pixelBottomRight = rowBottom + xRightIndex * tChannels;
333 for (
unsigned int n = 0u; n < tChannels; ++n)
335 buffer[n] = uint8_t((pixelTopLeft[n] * tx_y_ + pixelTopRight[n] * txy_ + pixelBottomLeft[n] * tx_y + pixelBottomRight[n] * txy + 8192u) >> 14u);
343template <
unsigned int tChannels,
unsigned int tPatchSize>
346 static_assert(tChannels >= 1u,
"Invalid channel number!");
347 static_assert(tPatchSize >= 1u && tPatchSize % 2u == 1u,
"The patch size must be odd!");
349 ocean_assert(frame !=
nullptr && buffer !=
nullptr);
351 constexpr unsigned int tPatchSize_2 = tPatchSize / 2u;
353 ocean_assert(width >= tPatchSize_2 + 1u && height >= tPatchSize_2 + 1u);
354 ocean_assert(position.
x() >= 0 && position.
y() >= 0);
355 ocean_assert(position.
x() <
Scalar(width) && position.
y() <
Scalar(height));
357 const int left = int(position.
x()) - int(tPatchSize_2);
358 const int top = int(position.
y()) - int(tPatchSize_2);
361 ocean_assert(tx >= 0 && tx <= 1);
362 const unsigned int txi = (
unsigned int)(tx *
Scalar(128) +
Scalar(0.5));
363 const unsigned int txi_ = 128u - txi;
366 ocean_assert(ty >= 0 && ty <= 1);
367 const unsigned int tyi = (
unsigned int)(ty *
Scalar(128) +
Scalar(0.5));
368 const unsigned int tyi_ = 128u - tyi;
370 const unsigned int tx_y_ = txi_ * tyi_;
371 const unsigned int txy_ = txi * tyi_;
372 const unsigned int tx_y = txi_ * tyi;
373 const unsigned int txy = txi * tyi;
375 const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
377 for (
unsigned int y = 0u; y < tPatchSize; ++y)
379 const int yTop = top + int(y);
380 const int yBottom = yTop + 1;
385 for (
unsigned int x = 0u; x < tPatchSize; ++x)
387 const int xLeft = left + int(x);
388 const int xRight = xLeft + 1;
390 unsigned int xLeftIndex;
391 unsigned int xRightIndex;
393 if ((
unsigned int)(xLeft) < width && (
unsigned int)(xRight) < width)
395 xLeftIndex = (
unsigned int)(xLeft);
396 xRightIndex = (
unsigned int)(xRight);
404 const uint8_t*
const pixelTopLeft = rowTop + xLeftIndex * tChannels;
405 const uint8_t*
const pixelTopRight = rowTop + xRightIndex * tChannels;
406 const uint8_t*
const pixelBottomLeft = rowBottom + xLeftIndex * tChannels;
407 const uint8_t*
const pixelBottomRight = rowBottom + xRightIndex * tChannels;
409 for (
unsigned int n = 0u; n < tChannels; ++n)
411 buffer[n] = uint8_t((pixelTopLeft[n] * tx_y_ + pixelTopRight[n] * txy_ + pixelBottomLeft[n] * tx_y + pixelBottomRight[n] * txy + 8192u) >> 14u);
419template <
unsigned int tChannels>
422 ocean_assert(sourceTopLeft && target);
423 ocean_assert(xFactor <= 128u && yFactor <= 128u);
425 interpolatePixel8BitPerChannel<tChannels>(sourceTopLeft, sourceBottomLeft, target, (128u - xFactor) * (128u - yFactor), xFactor * (128u - yFactor), (128u - xFactor) * yFactor, xFactor * yFactor);
428template <
unsigned int tChannels>
431 ocean_assert(sourceTopLeft && target);
432 ocean_assert(tx_ty_ + txty_ + tx_ty + txty == 128u * 128u);
434 for (
unsigned int n = 0u; n < tChannels; ++n)
436 target[n] = uint8_t((sourceTopLeft[n] * tx_ty_ + sourceTopLeft[tChannels + n] * txty_ + sourceBottomLeft[n] * tx_ty + sourceBottomLeft[tChannels + n] * txty + 8192u) >> 14u);
This class implements several advanced bilinear frame interpolator functions based e....
Definition AdvancedFrameInterpolatorBilinearBase.h:33
static void interpolatePatch8BitPerChannel(const uint8_t *const image, const unsigned int width, const unsigned int imagePaddingElements, uint8_t *buffer, const VectorT2< TScalar > &position, const unsigned int patchWidth, const unsigned int patchHeight)
Interpolates the content of an image patch with sub-pixel accuracy inside a given image and stores th...
Definition AdvancedFrameInterpolatorBilinearBase.h:197
static void interpolatePixel8BitPerChannel(const uint8_t *sourceTopLeft, const uint8_t *sourceBottomLeft, uint8_t *target, const unsigned int xFactor, const unsigned int yFactor)
Interpolates the content of 2x2 pixels to one pixel.
Definition AdvancedFrameInterpolatorBilinearBase.h:420
static void interpolateSquareMirroredBorderTemplate8BitPerChannel(const uint8_t *frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, uint8_t *buffer, const Vector2 &position)
Interpolates the content of a square region inside a given frame into a buffer with size of the squar...
Definition AdvancedFrameInterpolatorBilinearBase.h:344
static void interpolateSquarePatch8BitPerChannelTemplate(const uint8_t *const image, const unsigned int width, const unsigned int imagePaddingElements, uint8_t *buffer, const VectorT2< TScalar > &position)
Interpolates the content of a square image patch with sub-pixel accuracy inside a given image and sto...
Definition AdvancedFrameInterpolatorBilinearBase.h:126
static void interpolateSquareMirroredBorder8BitPerChannel(const uint8_t *frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, uint8_t *buffer, const Vector2 &position, const unsigned int patchSize)
Interpolates the content of a square image patch with sub-pixel accuracy inside a given image and sto...
Definition AdvancedFrameInterpolatorBilinearBase.h:268
static OCEAN_FORCE_INLINE unsigned int mirrorIndex(const int index, const unsigned int elements)
Returns the mirrored index for a given index.
Definition CVUtilities.h:459
This class implements a vector with two elements.
Definition Vector2.h:96
const T & x() const noexcept
Returns the x value.
Definition Vector2.h:703
const T & y() const noexcept
Returns the y value.
Definition Vector2.h:715
@ PC_TOP_LEFT
The center of a pixel is in the upper-left corner of each pixel's square.
Definition CV.h:133
float Scalar
Definition of a scalar type.
Definition Math.h:129
The namespace covering the entire Ocean framework.
Definition Accessor.h:15