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);
125 template <
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;
196 template <
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;
267 template <
unsigned int tChannels>
270 ocean_assert(frame !=
nullptr && buffer !=
nullptr);
271 ocean_assert(patchSize >= 1u && patchSize % 2u == 1u);
273 const unsigned int patchSize_2 = patchSize / 2u;
275 ocean_assert(position.
x() >=
Scalar(0) && position.
y() >=
Scalar(0));
276 ocean_assert(position.
x() <
Scalar(width) && position.
y() <
Scalar(height));
278 const int left = int(position.
x()) - int(patchSize_2);
279 const int top = int(position.
y()) - int(patchSize_2);
282 ocean_assert(tx >= 0 && tx <= 1);
283 const unsigned int txi = (
unsigned int)(tx *
Scalar(128) +
Scalar(0.5));
284 const unsigned int txi_ = 128u - txi;
287 ocean_assert(ty >= 0 && ty <= 1);
288 const unsigned int tyi = (
unsigned int)(ty *
Scalar(128) +
Scalar(0.5));
289 const unsigned int tyi_ = 128u - tyi;
291 const unsigned int tx_y_ = txi_ * tyi_;
292 const unsigned int txy_ = txi * tyi_;
293 const unsigned int tx_y = txi_ * tyi;
294 const unsigned int txy = txi * tyi;
296 const int frameStrideElements = int(width * tChannels + framePaddingElements);
298 const uint8_t* frameTop = frame + top * frameStrideElements + left * int(tChannels);
299 const uint8_t* frameBottom = frameTop + frameStrideElements;
301 for (
unsigned int y = 0u; y < patchSize; ++y)
304 const uint8_t* pixelBottom = frameBottom +
CVUtilities::mirrorOffset(y + (
unsigned int)(top) + 1u, height) * frameStrideElements;
306 for (
int xSigned = left; xSigned < left + int(patchSize); ++xSigned)
308 const unsigned int x = (
unsigned int)(xSigned);
310 if (x < width && (x + 1u) < width)
314 for (
unsigned int n = 0u; n < tChannels; ++n)
316 buffer[n] = uint8_t((pixelTop[0] * tx_y_ + pixelTop[tChannels] * txy_ + pixelBottom[0] * tx_y + pixelBottom[tChannels] * txy + 8192u) >> 14u);
326 ocean_assert(x + 1u >= width);
330 for (
unsigned int n = 0u; n < tChannels; ++n)
332 buffer[n] = uint8_t((pixelTop[0] * tx_y_ + *(pixelTop + offset) * txy_ + pixelBottom[0] * tx_y + *(pixelBottom + offset) * txy + 8192u) >> 14u);
338 else if (x + 1u < width)
342 ocean_assert(x >= width);
346 for (
unsigned int n = 0u; n < tChannels; ++n)
348 buffer[n] = uint8_t((*(pixelTop + 0 + offset) * tx_y_ + pixelTop[tChannels] * txy_ + *(pixelBottom + 0 + offset) * tx_y + pixelBottom[tChannels] * txy + 8192u) >> 14u);
358 ocean_assert(x >= width && x + 1u >= width);
363 for (
unsigned int n = 0u; n < tChannels; ++n)
365 buffer[n] = uint8_t((*(pixelTop + 0 + offsetLeft) * tx_y_ + *(pixelTop + offsetRight) * txy_ + *(pixelBottom + 0 + offsetLeft) * tx_y + *(pixelBottom + offsetRight) * txy + 8192u) >> 14u);
375 frameTop += frameStrideElements;
376 frameBottom += frameStrideElements;
380 template <
unsigned int tChannels,
unsigned int tPatchSize>
383 static_assert(tChannels >= 1u,
"Invalid channel number!");
384 static_assert(tPatchSize >= 1u && tPatchSize % 2u == 1u,
"The patch size must be odd!");
386 ocean_assert(frame !=
nullptr && buffer !=
nullptr);
388 constexpr
unsigned int tPatchSize_2 = tPatchSize / 2u;
390 ocean_assert(position.
x() >= 0 && position.
y() >= 0);
391 ocean_assert(position.
x() <
Scalar(width) && position.
y() <
Scalar(height));
393 const int left = int(position.
x()) - int(tPatchSize_2);
394 const int top = int(position.
y()) - int(tPatchSize_2);
397 ocean_assert(tx >= 0 && tx <= 1);
398 const unsigned int txi = (
unsigned int)(tx *
Scalar(128) +
Scalar(0.5));
399 const unsigned int txi_ = 128u - txi;
402 ocean_assert(ty >= 0 && ty <= 1);
403 const unsigned int tyi = (
unsigned int)(ty *
Scalar(128) +
Scalar(0.5));
404 const unsigned int tyi_ = 128u - tyi;
406 const unsigned int tx_y_ = txi_ * tyi_;
407 const unsigned int txy_ = txi * tyi_;
408 const unsigned int tx_y = txi_ * tyi;
409 const unsigned int txy = txi * tyi;
411 const int frameStrideElements = int(width * tChannels + framePaddingElements);
413 const uint8_t* frameTop = frame + top * frameStrideElements + left * int(tChannels);
414 const uint8_t* frameBottom = frameTop + frameStrideElements;
416 for (
unsigned int y = 0u; y < tPatchSize; ++y)
419 const uint8_t* pixelBottom = frameBottom +
CVUtilities::mirrorOffset(y + (
unsigned int)(top) + 1u, height) * frameStrideElements;
421 for (
int xSigned = left; xSigned < left + int(tPatchSize); ++xSigned)
423 const unsigned int x = (
unsigned int)(xSigned);
425 if (x < width && (x + 1u) < width)
429 for (
unsigned int n = 0u; n < tChannels; ++n)
431 buffer[n] = uint8_t((pixelTop[0] * tx_y_ + pixelTop[tChannels] * txy_ + pixelBottom[0] * tx_y + pixelBottom[tChannels] * txy + 8192u) >> 14u);
441 ocean_assert(x + 1u >= width);
445 for (
unsigned int n = 0u; n < tChannels; ++n)
447 buffer[n] = uint8_t((pixelTop[0] * tx_y_ + *(pixelTop + offset) * txy_ + pixelBottom[0] * tx_y + *(pixelBottom + offset) * txy + 8192u) >> 14u);
453 else if (x + 1u < width)
457 ocean_assert(x >= width);
461 for (
unsigned int n = 0u; n < tChannels; ++n)
463 buffer[n] = uint8_t((*(pixelTop + 0 + offset) * tx_y_ + pixelTop[tChannels] * txy_ + *(pixelBottom + 0 + offset) * tx_y + pixelBottom[tChannels] * txy + 8192u) >> 14u);
473 ocean_assert(x >= width && x + 1u >= width);
478 for (
unsigned int n = 0u; n < tChannels; ++n)
480 buffer[n] = uint8_t((*(pixelTop + 0 + offsetLeft) * tx_y_ + *(pixelTop + offsetRight) * txy_ + *(pixelBottom + 0 + offsetLeft) * tx_y + *(pixelBottom + offsetRight) * txy + 8192u) >> 14u);
490 frameTop += frameStrideElements;
491 frameBottom += frameStrideElements;
495 template <
unsigned int tChannels>
498 ocean_assert(sourceTopLeft && target);
499 ocean_assert(xFactor <= 128u && yFactor <= 128u);
501 interpolatePixel8BitPerChannel<tChannels>(sourceTopLeft, sourceBottomLeft, target, (128u - xFactor) * (128u - yFactor), xFactor * (128u - yFactor), (128u - xFactor) * yFactor, xFactor * yFactor);
504 template <
unsigned int tChannels>
507 ocean_assert(sourceTopLeft && target);
508 ocean_assert(tx_ty_ + txty_ + tx_ty + txty == 128u * 128u);
510 for (
unsigned int n = 0u; n < tChannels; ++n)
512 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:496
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:381
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 int mirrorOffset(const unsigned int index, const unsigned int elements)
Deprecated.
Definition: CVUtilities.h:446
This class implements a vector with two elements.
Definition: Vector2.h:96
const T & x() const noexcept
Returns the x value.
Definition: Vector2.h:698
const T & y() const noexcept
Returns the y value.
Definition: Vector2.h:710
@ 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:128
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15