8#ifndef META_OCEAN_CV_FRAME_INTERPOLATOR_NEAREST_PIXEL_H
9#define META_OCEAN_CV_FRAME_INTERPOLATOR_NEAREST_PIXEL_H
71 static inline bool resize(
Frame& frame,
const unsigned int targetWidth,
const unsigned int targetHeight,
Worker* worker =
nullptr);
160 static inline bool rotate90(
const Frame& input,
Frame& output,
const bool clockwise,
Worker* worker =
nullptr);
170 static inline bool rotate180(
const Frame& input,
Frame& output,
Worker* worker =
nullptr);
181 static bool rotate(
const Frame& input,
Frame& output,
const int angle,
Worker* worker =
nullptr);
218 template <
typename T,
unsigned int tChannels>
219 static inline void resize(
const T* source, T* target,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const unsigned int targetWidth,
const unsigned int targetHeight,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
Worker* worker =
nullptr);
239 template <
unsigned int tChannels>
240 static inline void affine8BitPerChannel(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const SquareMatrix3& input_A_output,
const uint8_t* borderColor, uint8_t* output,
const PixelPositionI& outputOrigin,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int inputPaddingElements,
const unsigned int outputPaddingElements,
Worker* worker =
nullptr);
262 template <
typename T,
unsigned int tChannels>
263 static inline void homography(
const T* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const SquareMatrix3& input_H_output,
const T* borderColor, T* output,
const PixelPositionI& outputOrigin,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int inputPaddingElements,
const unsigned int outputPaddingElements,
Worker* worker =
nullptr);
286 template <
unsigned int tChannels>
287 static inline void homographyMask8BitPerChannel(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const SquareMatrix3& input_H_output, uint8_t* output,
const unsigned int outputPaddingElements, uint8_t* outputMask,
const unsigned int outputMaskPaddingElements,
const PixelPositionI& outputOrigin,
const unsigned int outputWidth,
const unsigned int outputHeight,
Worker* worker =
nullptr,
const uint8_t maskValue = 0xFF);
304 template <
unsigned int tChannels>
305 static inline void transform8BitPerChannel(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const LookupTable& lookupTable,
const bool offset,
const uint8_t* borderColor, uint8_t* output,
const unsigned int inputPaddingElements,
const unsigned int outputPaddingElements,
Worker* worker =
nullptr);
325 template <
unsigned int tChannels>
326 static inline void transformMask8BitPerChannel(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const LookupTable& lookupTable,
const bool offset, uint8_t* output,
const unsigned int outputPaddingElements, uint8_t* outputMask,
const unsigned int outputMaskPaddingElements,
Worker* worker =
nullptr,
const uint8_t maskValue = 0xFF);
341 template <
typename TElementType,
unsigned int tChannels>
342 static inline void rotate90(
const TElementType* source, TElementType* target,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const bool clockwise,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
Worker* worker =
nullptr);
355 static bool coversHomographyInputFrame(
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int outputWidth,
const unsigned int outputHeight,
const SquareMatrix3& input_H_output,
const int outputOriginX = 0,
const int outputOriginY = 0);
374 template <
typename T,
unsigned int tChannels>
375 static void resizeSubset(
const T* source, T* target,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const unsigned int targetWidth,
const unsigned int targetHeight,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
const unsigned int firstTargetRow,
const unsigned int numberTargetRows);
393 template <
unsigned int tChannels>
394 static void affine8BitPerChannelSubset(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const SquareMatrix3* affineTransform,
const uint8_t* borderColor, uint8_t* output,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int outputPaddingElements,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows);
413 template <
typename T,
unsigned int tChannels>
414 static void homographySubset(
const T* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const SquareMatrix3* input_H_output,
const T* borderColor, T* output,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int inputPaddingElements,
const unsigned int outputPaddingElements,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows);
416 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
436 template <
unsigned int tChannels>
437 static inline void affine8BitPerChannelSSESubset(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const SquareMatrix3* affineTransform,
const uint8_t* borderColor, uint8_t* output,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int outputPaddingElements,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows);
456 template <
typename T,
unsigned int tChannels>
457 static void homographySSESubset(
const T* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const SquareMatrix3* input_H_output,
const T* borderColor, T* output,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int inputPaddingElements,
const unsigned int outputPaddingElements,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows);
461 #if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
479 template <
unsigned int tChannels>
480 static inline void affine8BitPerChannelIntegerNEONSubset(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const SquareMatrix3* affineTransform,
const uint8_t* borderColor, uint8_t* output,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int outputPaddingElements,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows);
501 template <
typename T,
unsigned int tChannels>
502 static inline void homographyNEONSubset(
const T* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const SquareMatrix3* input_H_output,
const T* borderColor, T* output,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int inputPaddingElements,
const unsigned int outputPaddingElements,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows);
526 template <
unsigned int tChannels>
527 static inline void homographyMask8BitPerChannelSubset(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const SquareMatrix3* input_H_output, uint8_t* output,
const unsigned int outputPaddingElements, uint8_t* outputMask,
const unsigned int outputMaskPaddingElements,
const uint8_t maskValue,
const int outputOriginX,
const int outputOriginY,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows);
545 template <
unsigned int tChannels>
546 static void transform8BitPerChannelSubset(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const LookupTable* lookupTable,
const bool offset,
const uint8_t* borderColor, uint8_t* output,
const unsigned int inputPaddingElements,
const unsigned int outputPaddingElements,
const unsigned int firstRow,
const unsigned int numberRows);
567 template <
unsigned int tChannels>
568 static void transformMask8BitPerChannelSubset(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const LookupTable* lookupTable,
const bool offset, uint8_t* output,
const unsigned int outputPaddingElements, uint8_t* outputMask,
const unsigned int outputMaskPaddingElements,
const uint8_t maskValue,
const unsigned int firstRow,
const unsigned int numberRows);
573 ocean_assert(frame && targetWidth >= 1u && targetHeight >= 1u);
577 if (!
resize(frame, tmpFrame, worker))
585 frame = std::move(tmpFrame);
604template <
typename T,
unsigned int tChannels>
605inline void FrameInterpolatorNearestPixel::resize(
const T* source, T* target,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const unsigned int targetWidth,
const unsigned int targetHeight,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
Worker* worker)
607 ocean_assert(source && target);
611 worker->
executeFunction(
Worker::Function::createStatic(&FrameInterpolatorNearestPixel::resizeSubset<T, tChannels>, source, target, sourceWidth, sourceHeight, targetWidth, targetHeight, sourcePaddingElements, targetPaddingElements, 0u, 0u), 0u, targetHeight);
615 resizeSubset<T, tChannels>(source, target, sourceWidth, sourceHeight, targetWidth, targetHeight, sourcePaddingElements, targetPaddingElements, 0u, targetHeight);
619template <
unsigned int tChannels>
620inline void FrameInterpolatorNearestPixel::affine8BitPerChannel(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const SquareMatrix3& affineTransform,
const uint8_t* borderColor, uint8_t* output,
const PixelPositionI& outputOrigin,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int inputPaddingElements,
const unsigned int outputPaddingElements,
Worker* worker)
627 if (outputWidth >= 4u)
629#if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
630 worker->
executeFunction(
Worker::Function::createStatic(&FrameInterpolatorNearestPixel::affine8BitPerChannelSSESubset<tChannels>, input, inputWidth, inputHeight, inputPaddingElements, &adjustedAffineTransform, borderColor, output, outputWidth, outputHeight, outputPaddingElements, 0u, 0u), 0, outputHeight, 10u, 11u, 20u);
632#elif defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
633 if (inputWidth <= 65535u && inputHeight <= 65535u && outputWidth <= 65535u && outputHeight <= 65535u)
635 worker->
executeFunction(
Worker::Function::createStatic(&FrameInterpolatorNearestPixel::affine8BitPerChannelIntegerNEONSubset<tChannels>, input, inputWidth, inputHeight, inputPaddingElements, &adjustedAffineTransform, borderColor, output, outputWidth, outputHeight, outputPaddingElements, 0u, 0u), 0, outputHeight, 10u, 11u, 32u);
641 worker->
executeFunction(
Worker::Function::createStatic(&FrameInterpolatorNearestPixel::affine8BitPerChannelSubset<tChannels>, input, inputWidth, inputHeight, inputPaddingElements, &adjustedAffineTransform, borderColor, output, outputWidth, outputHeight, outputPaddingElements, 0u, 0u), 0, outputHeight, 10u, 11u, 20u);
645 if (outputWidth >= 4u)
647#if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
648 affine8BitPerChannelSSESubset<tChannels>(input, inputWidth, inputHeight, inputPaddingElements, &adjustedAffineTransform, borderColor, output, outputWidth, outputHeight, outputPaddingElements, 0u, outputHeight);
650#elif defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
651 if (inputWidth <= 65535u && inputHeight <= 65535u && outputWidth <= 65535u && outputHeight <= 65535u)
653 affine8BitPerChannelIntegerNEONSubset<tChannels>(input, inputWidth, inputHeight, inputPaddingElements, &adjustedAffineTransform, borderColor, output, outputWidth, outputHeight, outputPaddingElements, 0u, outputHeight);
659 affine8BitPerChannelSubset<tChannels>(input, inputWidth, inputHeight, inputPaddingElements, &adjustedAffineTransform, borderColor, output, outputWidth, outputHeight, outputPaddingElements, 0u, outputHeight);
663template <
typename T,
unsigned int tChannels>
664inline void FrameInterpolatorNearestPixel::homography(
const T* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const SquareMatrix3& input_H_output,
const T* borderColor, T* output,
const PixelPositionI& outputOrigin,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int inputPaddingElements,
const unsigned int outputPaddingElements,
Worker* worker)
666 static_assert(tChannels >= 1u,
"Invalid channel number!");
675 if (outputWidth >= 4u)
677#if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
678 worker->
executeFunction(
Worker::Function::createStatic(&FrameInterpolatorNearestPixel::homographySSESubset<MappedTypeT, tChannels>, (
const MappedTypeT*)(input), inputWidth, inputHeight, &input_H_adjustedOutput, (
const MappedTypeT*)(borderColor), (MappedTypeT*)(output), outputWidth, outputHeight, inputPaddingElements, outputPaddingElements, 0u, 0u), 0, outputHeight, 10u, 11u, 20u);
680#elif defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
681 worker->
executeFunction(
Worker::Function::createStatic(&FrameInterpolatorNearestPixel::homographyNEONSubset<MappedTypeT, tChannels>, (
const MappedTypeT*)(input), inputWidth, inputHeight, &input_H_adjustedOutput, (
const MappedTypeT*)(borderColor), (MappedTypeT*)(output), outputWidth, outputHeight, inputPaddingElements, outputPaddingElements, 0u, 0u), 0, outputHeight, 10u, 11u, 20u);
686 worker->
executeFunction(
Worker::Function::createStatic(&FrameInterpolatorNearestPixel::homographySubset<MappedTypeT, tChannels>, (
const MappedTypeT*)(input), inputWidth, inputHeight, &input_H_adjustedOutput, (
const MappedTypeT*)(borderColor), (MappedTypeT*)(output), outputWidth, outputHeight, inputPaddingElements, outputPaddingElements, 0u, 0u), 0, outputHeight, 10u, 11u, 20u);
690 if (outputWidth >= 4u)
692#if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
693 homographySSESubset<MappedTypeT, tChannels>((
const MappedTypeT*)(input), inputWidth, inputHeight, &input_H_adjustedOutput, (
const MappedTypeT*)(borderColor), (MappedTypeT*)(output), outputWidth, outputHeight, inputPaddingElements, outputPaddingElements, 0u, outputHeight);
695#elif defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
696 homographyNEONSubset<MappedTypeT, tChannels>((
const MappedTypeT*)(input), inputWidth, inputHeight, &input_H_adjustedOutput, (
const MappedTypeT*)(borderColor), (MappedTypeT*)(output), outputWidth, outputHeight, inputPaddingElements, outputPaddingElements, 0u, outputHeight);
701 homographySubset<MappedTypeT, tChannels>((
const MappedTypeT*)(input), inputWidth, inputHeight, &input_H_adjustedOutput, (
const MappedTypeT*)(borderColor), (MappedTypeT*)(output), outputWidth, outputHeight, inputPaddingElements, outputPaddingElements, 0u, outputHeight);
705template <
unsigned int tChannels>
706inline void FrameInterpolatorNearestPixel::homographyMask8BitPerChannel(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const SquareMatrix3& input_H_output, uint8_t* output,
const unsigned int outputPaddingElements, uint8_t* outputMask,
const unsigned int outputMaskPaddingElements,
const PixelPositionI& outputOrigin,
const unsigned int outputWidth,
const unsigned int outputHeight,
Worker* worker,
const uint8_t maskValue)
710 worker->
executeFunction(
Worker::Function::createStatic(&FrameInterpolatorNearestPixel::homographyMask8BitPerChannelSubset<tChannels>, input, inputWidth, inputHeight, inputPaddingElements, &input_H_output, output, outputPaddingElements, outputMask, outputMaskPaddingElements, maskValue, outputOrigin.
x(), outputOrigin.
y(), outputWidth, outputHeight, 0u, 0u), 0u, outputHeight, 14u, 15u, 20u);
714 homographyMask8BitPerChannelSubset<tChannels>(input, inputWidth, inputHeight, inputPaddingElements, &input_H_output, output, outputPaddingElements, outputMask, outputMaskPaddingElements, maskValue, outputOrigin.
x(), outputOrigin.
y(), outputWidth, outputHeight, 0u, outputHeight);
718template <
unsigned int tChannels>
723 worker->
executeFunction(
Worker::Function::createStatic(&FrameInterpolatorNearestPixel::transform8BitPerChannelSubset<tChannels>, input, inputWidth, inputHeight, &lookupTable, offset, borderColor, output, inputPaddingElements, outputPaddingElements, 0u, 0u), 0u, (
unsigned int)(lookupTable.
sizeY()), 9u, 10u, 20u);
727 transform8BitPerChannelSubset<tChannels>(input, inputWidth, inputHeight, &lookupTable, offset, borderColor, output, inputPaddingElements, outputPaddingElements, 0u, (
unsigned int)(lookupTable.
sizeY()));
731template <
unsigned int tChannels>
732inline void FrameInterpolatorNearestPixel::transformMask8BitPerChannel(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const LookupTable& lookupTable,
const bool offset, uint8_t* output,
const unsigned int outputPaddingElements, uint8_t* outputMask,
const unsigned int outputMaskPaddingElements,
Worker* worker,
const uint8_t maskValue)
736 worker->
executeFunction(
Worker::Function::createStatic(&FrameInterpolatorNearestPixel::transformMask8BitPerChannelSubset<tChannels>, input, inputWidth, inputHeight, inputPaddingElements, &lookupTable, offset, output, outputPaddingElements, outputMask, outputMaskPaddingElements, maskValue, 0u, 0u), 0u, (
unsigned int)(lookupTable.
sizeY()), 11u, 12u, 20u);
740 transformMask8BitPerChannelSubset<tChannels>(input, inputWidth, inputHeight, inputPaddingElements, &lookupTable, offset, output, outputPaddingElements, outputMask, outputMaskPaddingElements, maskValue, 0u, (
unsigned int)lookupTable.
sizeY());
744template <
typename TElementType,
unsigned int tChannels>
745inline void FrameInterpolatorNearestPixel::rotate90(
const TElementType* source, TElementType* target,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const bool clockwise,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
Worker* worker)
747 static_assert(tChannels >= 1u,
"Invalid channel number!");
749 ocean_assert(source !=
nullptr && target !=
nullptr);
750 ocean_assert(source != target);
751 ocean_assert(sourceWidth >= 1u && sourceHeight >= 1u);
753 FrameTransposer::rotate90<TElementType, tChannels>(source, target, sourceWidth, sourceHeight, clockwise, sourcePaddingElements, targetPaddingElements, worker);
756template <
typename T,
unsigned int tChannels>
757void FrameInterpolatorNearestPixel::resizeSubset(
const T* source, T* target,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const unsigned int targetWidth,
const unsigned int targetHeight,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
const unsigned int firstTargetRow,
const unsigned int numberTargetRows)
759 static_assert(tChannels > 0u,
"Invalid channel number!");
760 static_assert(
sizeof(T) != 0,
"Invalid data type!");
762 ocean_assert(source !=
nullptr && target !=
nullptr);
763 ocean_assert(sourceWidth != 0u && sourceHeight != 0u);
764 ocean_assert(targetWidth != 0u && targetHeight != 0u);
766 ocean_assert(firstTargetRow + numberTargetRows <= targetHeight);
768 const unsigned int sourceStrideElements = sourceWidth * tChannels + sourcePaddingElements;
769 const unsigned int targetStrideElements = targetWidth * tChannels + targetPaddingElements;
771 Memory memoryHorizontalLookups = Memory::create<unsigned int>(targetWidth);
772 unsigned int* horizontalLookups = memoryHorizontalLookups.
data<
unsigned int>();
774 for (
unsigned int tx = 0u; tx < targetWidth; ++tx)
776 const unsigned int sx = tx * sourceWidth / targetWidth;
777 ocean_assert(sx < sourceWidth);
779 horizontalLookups[tx] = sx * tChannels;
782 target += firstTargetRow * targetStrideElements;
784 for (
unsigned int ty = firstTargetRow; ty < firstTargetRow + numberTargetRows; ++ty)
786 const unsigned int sy = ty * sourceHeight / targetHeight;
787 ocean_assert(sy < sourceHeight);
789 const T*
const sourceRow = source + sy * sourceStrideElements;
791 for (
unsigned int tx = 0; tx < targetWidth; ++tx)
793 const T*
const sourcePointer = sourceRow + horizontalLookups[tx];
795 for (
unsigned int n = 0u; n < tChannels; ++n)
797 *target++ = sourcePointer[n];
801 target += targetPaddingElements;
805template <
unsigned int tChannels>
806void FrameInterpolatorNearestPixel::affine8BitPerChannelSubset(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const SquareMatrix3* affineTransform,
const uint8_t* borderColor, uint8_t* output,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int outputPaddingElements,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows)
808 static_assert(tChannels >= 1u,
"Invalid channel number!");
810 ocean_assert(input !=
nullptr && output !=
nullptr);
811 ocean_assert(inputWidth > 0u && inputHeight > 0u);
812 ocean_assert_and_suppress_unused(outputWidth > 0u && outputHeight > 0u, outputHeight);
813 ocean_assert(affineTransform);
816 ocean_assert(firstOutputRow + numberOutputRows <= outputHeight);
820 const uint8_t zeroColor[tChannels] = {uint8_t(0)};
821 const PixelType*
const bColor = borderColor ? (PixelType*)borderColor : (PixelType*)zeroColor;
823 PixelType* outputData = (PixelType*)(output + firstOutputRow * (outputWidth * tChannels + outputPaddingElements));
825 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
851 for (
unsigned int x = 0u; x < outputWidth; ++x)
856 const Scalar debugX = (*affineTransform)[0] *
Scalar(x) + (*affineTransform)[3] *
Scalar(y) + (*affineTransform)[6];
857 const Scalar debugY = (*affineTransform)[1] *
Scalar(x) + (*affineTransform)[4] *
Scalar(y) + (*affineTransform)[7];
864 if (inputX < inputWidth && inputY < inputHeight)
866 *outputData = *(PixelType*)(input + inputY * (inputWidth * tChannels + inputPaddingElements) + inputX * tChannels);
870 *outputData = *bColor;
876 outputData = (PixelType*)((uint8_t*)outputData + outputPaddingElements);
880template <
typename T,
unsigned int tChannels>
881void FrameInterpolatorNearestPixel::homographySubset(
const T* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const SquareMatrix3* input_H_output,
const T* borderColor, T* output,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int inputPaddingElements,
const unsigned int outputPaddingElements,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows)
883 static_assert(tChannels > 0u,
"Invalid channel number!");
885 ocean_assert(input !=
nullptr && output !=
nullptr);
886 ocean_assert(inputWidth > 0u && inputHeight > 0u);
887 ocean_assert(outputWidth > 0u && outputHeight > 0u);
888 ocean_assert(input_H_output !=
nullptr && !input_H_output->
isSingular());
890 ocean_assert_and_suppress_unused(firstOutputRow + numberOutputRows <= outputHeight, outputHeight);
892 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
893 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
897 const T zeroColor[tChannels] = {T(0)};
898 const PixelType bColor = borderColor ? *(
const PixelType*)(borderColor) : *(
const PixelType*)(zeroColor);
900 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
902 PixelType* outputData = (PixelType*)(output + y * outputStrideElements);
904 for (
unsigned int x = 0u; x < outputWidth; ++x)
907 const Vector2 inputPosition(*input_H_output * outputPosition);
912 if (inputX < inputWidth && inputY < inputHeight)
914 *outputData = *((
const PixelType*)(input + inputY * inputStrideElements) + inputX);
918 *outputData = bColor;
926#if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
928template <
unsigned int tChannels>
929inline void FrameInterpolatorNearestPixel::affine8BitPerChannelSSESubset(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const SquareMatrix3* affineTransform,
const uint8_t* borderColor, uint8_t* output,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int outputPaddingElements,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows)
931 static_assert(tChannels >= 1u,
"Invalid channel number!");
933 ocean_assert(input && output);
934 ocean_assert(inputWidth > 0u && inputHeight > 0u);
935 ocean_assert(outputWidth >= 4u && outputHeight > 0u);
936 ocean_assert(affineTransform);
939 ocean_assert_and_suppress_unused(firstOutputRow + numberOutputRows <= outputHeight, outputHeight);
943 const uint8_t zeroColor[tChannels] = {uint8_t(0)};
944 const PixelType*
const bColor = borderColor ? (PixelType*)borderColor : (PixelType*)zeroColor;
946 PixelType* outputPixelData = (PixelType*)(output + firstOutputRow * (outputWidth * tChannels + outputPaddingElements));
949 unsigned int nearestNeighbours[4];
952 const __m128 m128_f_X0 = _mm_set_ps1(
float((*affineTransform)(0, 0)));
953 const __m128 m128_f_X1 = _mm_set_ps1(
float((*affineTransform)(1, 0)));
956 const __m128i m128_i_inputStrideElements = _mm_set1_epi32(inputWidth * tChannels + inputPaddingElements);
959 const __m128i m128_i_channels = _mm_set1_epi32(tChannels);
962 const __m128i m128_i_inputWidth_1 = _mm_set1_epi32(inputWidth - 1u);
965 const __m128i m128_i_inputHeight_1 = _mm_set1_epi32(inputHeight - 1u);
968 const __m128i m128_i_zero = _mm_setzero_si128();
971 const unsigned int inputElementsEnd = inputHeight * inputWidth * tChannels + (inputHeight - 1u) * inputPaddingElements;
973 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
995 const __m128 m128_f_C0 = _mm_set_ps1(
float((*affineTransform)(0, 1) *
Scalar(y) + (*affineTransform)(0, 2)));
996 const __m128 m128_f_C1 = _mm_set_ps1(
float((*affineTransform)(1, 1) *
Scalar(y) + (*affineTransform)(1, 2)));
998 for (
unsigned int x = 0u; x < outputWidth; x += 4u)
1000 if (x + 4u > outputWidth)
1005 ocean_assert(x >= 4u && outputWidth > 4u);
1006 const unsigned int newX = outputWidth - 4u;
1008 ocean_assert(x > newX);
1009 outputPixelData -= x - newX;
1014 ocean_assert(!(x + 4u < outputWidth));
1019 const __m128 m128_f_x_0123 = _mm_set_ps(
float(x + 3u),
float(x + 2u),
float(x + 1u),
float(x + 0u));
1022 const __m128 m128_f_inputX = _mm_add_ps(_mm_mul_ps(m128_f_X0, m128_f_x_0123), m128_f_C0);
1023 const __m128 m128_f_inputY = _mm_add_ps(_mm_mul_ps(m128_f_X1, m128_f_x_0123), m128_f_C1);
1026 const __m128i m128_i_inputX = _mm_cvtps_epi32(_mm_round_ps(m128_f_inputX, _MM_FROUND_TO_NEAREST_INT));
1027 const __m128i m128_i_inputY = _mm_cvtps_epi32(_mm_round_ps(m128_f_inputY, _MM_FROUND_TO_NEAREST_INT));
1044 const __m128i m128_i_isOutsideImage = _mm_or_si128(
1045 _mm_or_si128(_mm_cmplt_epi32(m128_i_inputX, m128_i_zero), _mm_cmplt_epi32(m128_i_inputY, m128_i_zero)),
1046 _mm_or_si128(_mm_cmpgt_epi32(m128_i_inputX, m128_i_inputWidth_1), _mm_cmpgt_epi32(m128_i_inputY, m128_i_inputHeight_1)));
1050 const __m128i m_128_i_nearestNeighborElements = _mm_or_si128(m128_i_isOutsideImage, _mm_add_epi32(_mm_mullo_epi32(m128_i_inputY, m128_i_inputStrideElements), _mm_mullo_epi32(m128_i_inputX, m128_i_channels)));
1051 _mm_store_si128((__m128i*)nearestNeighbours, m_128_i_nearestNeighborElements);
1054 outputPixelData[0] = nearestNeighbours[0] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighbours[0]) : *bColor;
1055 outputPixelData[1] = nearestNeighbours[1] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighbours[1]) : *bColor;
1056 outputPixelData[2] = nearestNeighbours[2] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighbours[2]) : *bColor;
1057 outputPixelData[3] = nearestNeighbours[3] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighbours[3]) : *bColor;
1059 outputPixelData += 4u;
1062 outputPixelData = (PixelType*)((uint8_t*)outputPixelData + outputPaddingElements);
1066template <
typename T,
unsigned int tChannels>
1067void FrameInterpolatorNearestPixel::homographySSESubset(
const T* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const SquareMatrix3* input_H_output,
const T* borderColor, T* output,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int inputPaddingElements,
const unsigned int outputPaddingElements,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows)
1069 static_assert(tChannels > 0u,
"Invalid channel number!");
1071 ocean_assert(input !=
nullptr && output !=
nullptr);
1072 ocean_assert(inputWidth > 0u && inputHeight > 0u);
1073 ocean_assert(outputWidth >= 4u && outputHeight > 0u);
1074 ocean_assert(input_H_output !=
nullptr && !input_H_output->
isSingular());
1076 ocean_assert_and_suppress_unused(firstOutputRow + numberOutputRows <= outputHeight, outputHeight);
1078 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1079 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1083 const T zeroColor[tChannels] = {T(0)};
1084 const PixelType bColor = borderColor ? *(
const PixelType*)(borderColor) : *(
const PixelType*)(zeroColor);
1086 OCEAN_ALIGN_DATA(16)
unsigned int nearestNeighbourElementOffsets[4];
1114 const __m128 m128_f_X0 = _mm_set_ps1((
float)(*input_H_output)(0, 0));
1115 const __m128 m128_f_X1 = _mm_set_ps1((
float)(*input_H_output)(1, 0));
1116 const __m128 m128_f_X2 = _mm_set_ps1((
float)(*input_H_output)(2, 0));
1119 const __m128i m128_i_inputStrideElements = _mm_set1_epi32(inputStrideElements);
1121 const unsigned int inputPixelElementIndexEnd = inputHeight * inputStrideElements;
1124 const __m128i m128_i_inputWidth_1 = _mm_set1_epi32(inputWidth - 1u);
1127 const __m128i m128_i_inputHeight_1 = _mm_set1_epi32(inputHeight - 1u);
1130 const __m128i m128_i_channels = _mm_set1_epi32(tChannels);
1133 const __m128i m128_i_zero = _mm_setzero_si128();
1135 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
1137 PixelType* outputPixelData = (PixelType*)(output + y * outputStrideElements);
1140 const __m128 m128_f_C0 = _mm_set_ps1((
float)((*input_H_output)(0, 1) *
Scalar(y) + ((*input_H_output)(0, 2))));
1141 const __m128 m128_f_C1 = _mm_set_ps1((
float)((*input_H_output)(1, 1) *
Scalar(y) + ((*input_H_output)(1, 2))));
1142 const __m128 m128_f_C2 = _mm_set_ps1((
float)((*input_H_output)(2, 1) *
Scalar(y) + ((*input_H_output)(2, 2))));
1144 for (
unsigned int x = 0u; x < outputWidth; x += 4u)
1146 if (x + 4u > outputWidth)
1151 ocean_assert(x >= 4u && outputWidth > 4u);
1152 const unsigned int newX = outputWidth - 4u;
1154 ocean_assert(x > newX);
1155 outputPixelData -= x - newX;
1160 ocean_assert(!(x + 4u < outputWidth));
1165 const __m128 m128_f_x_0123 = _mm_set_ps(
float(x + 3u),
float(x + 2u),
float(x + 1u),
float(x + 0u));
1168 const __m128 m128_f_xx = _mm_add_ps(_mm_mul_ps(m128_f_X0, m128_f_x_0123), m128_f_C0);
1169 const __m128 m128_f_yy = _mm_add_ps(_mm_mul_ps(m128_f_X1, m128_f_x_0123), m128_f_C1);
1170 const __m128 m128_f_zz = _mm_add_ps(_mm_mul_ps(m128_f_X2, m128_f_x_0123), m128_f_C2);
1172#ifdef USE_APPROXIMATED_INVERSE_OF_ZZ
1177 const __m128 inv_zz_128 = _mm_rcp_ps(m128_f_zz);
1180 const __m128 m128_f_inputX = _mm_mul_ps(m128_f_xx, inv_zz_128);
1181 const __m128 m128_f_inputY = _mm_mul_ps(m128_f_yy, inv_zz_128);
1186 const __m128 m128_f_inputX = _mm_div_ps(m128_f_xx, m128_f_zz);
1187 const __m128 m128_f_inputY = _mm_div_ps(m128_f_yy, m128_f_zz);
1192 const __m128i m128_i_inputX = _mm_cvtps_epi32(_mm_round_ps(m128_f_inputX, _MM_FROUND_TO_NEAREST_INT));
1193 const __m128i m128_i_inputY = _mm_cvtps_epi32(_mm_round_ps(m128_f_inputY, _MM_FROUND_TO_NEAREST_INT));
1210 const __m128i m128_i_isOutsideImage = _mm_or_si128(
1211 _mm_or_si128(_mm_cmplt_epi32(m128_i_inputX, m128_i_zero), _mm_cmplt_epi32(m128_i_inputY, m128_i_zero)),
1212 _mm_or_si128(_mm_cmpgt_epi32(m128_i_inputX, m128_i_inputWidth_1), _mm_cmpgt_epi32(m128_i_inputY, m128_i_inputHeight_1)));
1216 const __m128i m_128_i_nearestNeighbors = _mm_or_si128(m128_i_isOutsideImage, _mm_add_epi32(_mm_mullo_epi32(m128_i_inputY, m128_i_inputStrideElements), _mm_mullo_epi32(m128_i_inputX, m128_i_channels)));
1217 _mm_store_si128((__m128i*)nearestNeighbourElementOffsets, m_128_i_nearestNeighbors);
1220 outputPixelData[0] = nearestNeighbourElementOffsets[0] < inputPixelElementIndexEnd ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[0]) : bColor;
1221 outputPixelData[1] = nearestNeighbourElementOffsets[1] < inputPixelElementIndexEnd ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[1]) : bColor;
1222 outputPixelData[2] = nearestNeighbourElementOffsets[2] < inputPixelElementIndexEnd ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[2]) : bColor;
1223 outputPixelData[3] = nearestNeighbourElementOffsets[3] < inputPixelElementIndexEnd ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[3]) : bColor;
1225 outputPixelData += 4u;
1232#if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
1234template <
unsigned int tChannels>
1235void FrameInterpolatorNearestPixel::affine8BitPerChannelIntegerNEONSubset(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const SquareMatrix3* affineTransform,
const uint8_t* borderColor, uint8_t* output,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int outputPaddingElements,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows)
1287 static_assert(tChannels >= 1u,
"Invalid channel number!");
1289 constexpr unsigned int fractionalBits = 15u;
1290 constexpr unsigned int totalBits = (
unsigned int)(CHAR_BIT *
sizeof(
int));
1292 static_assert((fractionalBits + 1u ) < totalBits,
"Number of fractional bits exceeds number of total bits");
1294 constexpr unsigned int maxImageEdgeLength = 1u << (totalBits - fractionalBits - 1u );
1297 constexpr Scalar fixedPointScale =
Scalar(1u << fractionalBits);
1300 constexpr unsigned int pixelsPerIteration = 4u;
1302 ocean_assert(input && output);
1303 ocean_assert_and_suppress_unused(inputWidth > 0u && inputHeight > 0u && inputWidth <= maxImageEdgeLength && inputHeight <= maxImageEdgeLength, maxImageEdgeLength);
1304 ocean_assert_and_suppress_unused(outputWidth >= pixelsPerIteration && outputHeight > 0u && outputWidth <= maxImageEdgeLength && outputHeight <= maxImageEdgeLength, maxImageEdgeLength);
1305 ocean_assert(affineTransform);
1308 ocean_assert(firstOutputRow + numberOutputRows <= outputHeight);
1312 const uint8_t zeroColor[tChannels] = {uint8_t(0)};
1313 const PixelType*
const bColor = borderColor ? (PixelType*)borderColor : (PixelType*)zeroColor;
1315 PixelType* outputPixelData = (PixelType*)(output + firstOutputRow * (outputWidth * tChannels + outputPaddingElements));
1317 const unsigned int outputRowEnd = firstOutputRow + numberOutputRows;
1320 unsigned int nearestNeighboursElements[4];
1323 const unsigned int inputElementsEnd = inputHeight * inputWidth * tChannels + (inputHeight - 1u) * inputPaddingElements;
1326 const uint32x4_t m128_u_inputWidth = vdupq_n_u32(inputWidth);
1327 const uint32x4_t m128_u_inputHeight = vdupq_n_u32(inputHeight);
1330 const uint32x4_t m128_u_inputStrideElements = vdupq_n_u32(inputWidth * tChannels + inputPaddingElements);
1333 const uint32x4_t m128_u_channels = vdupq_n_u32(tChannels);
1336 const int offsets_0123[4] = { 0, 1, 2, 3 };
1337 const int32x4_t m128_s_offsets_0123 = vld1q_s32(offsets_0123);
1340 const float32x4_t m128_f_pixelsPerIteration = vdupq_n_f32((
float)pixelsPerIteration);
1346 const float32x4_t m128_f_X0 = vdupq_n_f32(
float(fixedPointScale * (*affineTransform)(0, 0)));
1347 const float32x4_t m128_f_X1 = vdupq_n_f32(
float(fixedPointScale * (*affineTransform)(1, 0)));
1351 const int32x4_t m128_s_q_X0x_increment = vcvtq_s32_f32(vmulq_f32(m128_f_X0, m128_f_pixelsPerIteration));
1352 const int32x4_t m128_s_q_X1x_increment = vcvtq_s32_f32(vmulq_f32(m128_f_X1, m128_f_pixelsPerIteration));
1355 constexpr unsigned int blockSize = 64u;
1356 constexpr unsigned int blockElements = blockSize * blockSize;
1357 const unsigned int blockWidth = std::min(blockElements / std::min(numberOutputRows, blockSize), outputWidth);
1358 const unsigned int blockHeight = std::min(blockElements / blockWidth, numberOutputRows);
1359 ocean_assert(blockWidth > 0u && blockWidth <= outputWidth);
1360 ocean_assert(blockHeight > 0u && blockHeight <= numberOutputRows);
1366 const unsigned int lastMultipleNeonPixelBlockStart = outputWidth - pixelsPerIteration;
1369 const float32x4_t m128_f_lastMultipleNeonPixelBlockStart = vcvtq_f32_s32(vaddq_s32(vdupq_n_s32((
int)lastMultipleNeonPixelBlockStart), m128_s_offsets_0123));
1372 const int32x4_t m128_s_q_X0x_lastMultipleNeonPixelBlockStart = vcvtq_s32_f32(vmulq_f32(m128_f_X0, m128_f_lastMultipleNeonPixelBlockStart));
1373 const int32x4_t m128_s_q_X1x_lastMultipleNeonPixelBlockStart = vcvtq_s32_f32(vmulq_f32(m128_f_X1, m128_f_lastMultipleNeonPixelBlockStart));
1375 for (
unsigned int blockYStart = firstOutputRow; blockYStart < outputRowEnd; blockYStart += blockHeight)
1377 const unsigned int blockYEnd = std::min(blockYStart + blockHeight, outputRowEnd);
1379 for (
unsigned int blockXStart = 0u; blockXStart < outputWidth; blockXStart += blockWidth)
1381 const unsigned int blockXEnd = std::min(blockXStart + blockWidth, outputWidth);
1383 for (
unsigned int y = blockYStart; y < blockYEnd; ++y)
1385 outputPixelData = (PixelType*)(output + y * (outputWidth * tChannels + outputPaddingElements) + blockXStart * tChannels);
1389 const int32x4_t m128_s_q_C0 = vdupq_n_s32(
Numeric::round32(fixedPointScale * ((*affineTransform)(0, 1) *
Scalar(y) + (*affineTransform)(0, 2))));
1390 const int32x4_t m128_s_q_C1 = vdupq_n_s32(
Numeric::round32(fixedPointScale * ((*affineTransform)(1, 1) *
Scalar(y) + (*affineTransform)(1, 2))));
1397 const int32x4_t m128_s_x_0123 = vaddq_s32(vdupq_n_s32(
int(blockXStart)), m128_s_offsets_0123);
1400 const float32x4_t m128_f_x_0123 = vcvtq_f32_s32(m128_s_x_0123);
1403 int32x4_t m128_s_q_X0x = vcvtq_s32_f32(vmulq_f32(m128_f_X0, m128_f_x_0123));
1404 int32x4_t m128_s_q_X1x = vcvtq_s32_f32(vmulq_f32(m128_f_X1, m128_f_x_0123));
1406 for (
unsigned int x = blockXStart; x < blockXEnd; x += pixelsPerIteration)
1408 if (x + pixelsPerIteration > outputWidth)
1410 ocean_assert(x + pixelsPerIteration > outputWidth);
1411 ocean_assert(x >= pixelsPerIteration && outputWidth > pixelsPerIteration);
1412 ocean_assert(lastMultipleNeonPixelBlockStart == (outputWidth - pixelsPerIteration));
1414 outputPixelData -= (x - lastMultipleNeonPixelBlockStart);
1416 x = lastMultipleNeonPixelBlockStart;
1418 m128_s_q_X0x = m128_s_q_X0x_lastMultipleNeonPixelBlockStart;
1419 m128_s_q_X1x = m128_s_q_X1x_lastMultipleNeonPixelBlockStart;
1422 ocean_assert(!(x + pixelsPerIteration < outputWidth));
1428 const int32x4_t m128_s_q_inputX = vaddq_s32(m128_s_q_C0, m128_s_q_X0x);
1429 const int32x4_t m128_s_q_inputY = vaddq_s32(m128_s_q_C1, m128_s_q_X1x);
1436 const uint32x4_t m128_u_inputX = vreinterpretq_u32_s32(vrshrq_n_s32(m128_s_q_inputX, fractionalBits));
1437 const uint32x4_t m128_u_inputY = vreinterpretq_u32_s32(vrshrq_n_s32(m128_s_q_inputY, fractionalBits));
1456 const uint32x4_t m128_u_isOutsideImage = vorrq_u32(vcgeq_u32(m128_u_inputX, m128_u_inputWidth), vcgeq_u32(m128_u_inputY, m128_u_inputHeight));
1463 const uint32x4_t m_128_u_nearestNeighborsElements = vorrq_u32(m128_u_isOutsideImage, vaddq_u32(vmulq_u32(m128_u_inputY, m128_u_inputStrideElements), vmulq_u32(m128_u_inputX, m128_u_channels)));
1464 vst1q_u32(nearestNeighboursElements, m_128_u_nearestNeighborsElements);
1466 outputPixelData[0] = nearestNeighboursElements[0] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighboursElements[0]) : *bColor;
1467 outputPixelData[1] = nearestNeighboursElements[1] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighboursElements[1]) : *bColor;
1468 outputPixelData[2] = nearestNeighboursElements[2] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighboursElements[2]) : *bColor;
1469 outputPixelData[3] = nearestNeighboursElements[3] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighboursElements[3]) : *bColor;
1471 outputPixelData += pixelsPerIteration;
1474 m128_s_q_X0x = vaddq_s32(m128_s_q_X0x, m128_s_q_X0x_increment);
1475 m128_s_q_X1x = vaddq_s32(m128_s_q_X1x, m128_s_q_X1x_increment);
1480 outputPixelData = (PixelType*)((uint8_t*)outputPixelData + outputPaddingElements);
1484template <
typename T,
unsigned int tChannels>
1485void FrameInterpolatorNearestPixel::homographyNEONSubset(
const T* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const SquareMatrix3* input_H_output,
const T* borderColor, T* output,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int inputPaddingElements,
const unsigned int outputPaddingElements,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows)
1487 static_assert(tChannels >= 1u,
"Invalid channel number!");
1489 ocean_assert(input !=
nullptr && output !=
nullptr);
1490 ocean_assert(inputWidth > 0u && inputHeight > 0u);
1491 ocean_assert(outputWidth >= 4u && outputHeight > 0u);
1492 ocean_assert(input_H_output !=
nullptr && !input_H_output->
isSingular());
1494 ocean_assert(firstOutputRow + numberOutputRows <= outputHeight);
1496 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1497 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1501 const T zeroColor[tChannels] = {T(0)};
1502 const PixelType bColor = borderColor ? *(
const PixelType*)(borderColor) : *(
const PixelType*)(zeroColor);
1504 unsigned int validPixels[4];
1505 unsigned int nearestNeighbourElementOffsets[4];
1533 const float32x4_t m128_f_X0 = vdupq_n_f32(
float((*input_H_output)(0, 0)));
1534 const float32x4_t m128_f_X1 = vdupq_n_f32(
float((*input_H_output)(1, 0)));
1535 const float32x4_t m128_f_X2 = vdupq_n_f32(
float((*input_H_output)(2, 0)));
1538 const float32x4_t m128_f_pointFive = vdupq_n_f32(0.5f);
1539 const float32x4_t m128_f_negPointFive = vdupq_n_f32(-0.5f);
1542 const uint32x4_t m128_u_inputStrideElements = vdupq_n_u32(inputStrideElements);
1544 const uint32x4_t m128_u_channels = vdupq_n_u32(tChannels);
1547 const float32x4_t m128_f_inputWidth_pointFive = vdupq_n_f32(
float(inputWidth) - 0.5f);
1548 const float32x4_t m128_f_inputHeight_pointFive = vdupq_n_f32(
float(inputHeight) - 0.5f);
1550 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
1552 PixelType* outputPixelData = (PixelType*)(output + y * outputStrideElements);
1555 const float32x4_t m128_f_C0 = vdupq_n_f32(
float((*input_H_output)(0, 1) *
Scalar(y) + (*input_H_output)(0, 2)));
1556 const float32x4_t m128_f_C1 = vdupq_n_f32(
float((*input_H_output)(1, 1) *
Scalar(y) + (*input_H_output)(1, 2)));
1557 const float32x4_t m128_f_C2 = vdupq_n_f32(
float((*input_H_output)(2, 1) *
Scalar(y) + (*input_H_output)(2, 2)));
1559 for (
unsigned int x = 0u; x < outputWidth; x += 4u)
1561 if (x + 4u > outputWidth)
1565 ocean_assert(x >= 4u && outputWidth > 4u);
1566 const unsigned int newX = outputWidth - 4u;
1568 ocean_assert(x > newX);
1569 outputPixelData -= x - newX;
1574 ocean_assert(!(x + 4u < outputWidth));
1579 float x_0123[4] = { float(x + 0u), float(x + 1u), float(x + 2u), float(x + 3u) };
1580 const float32x4_t m128_f_x_0123 = vld1q_f32(x_0123);
1583 const float32x4_t m128_f_xx = vmlaq_f32(m128_f_C0, m128_f_X0, m128_f_x_0123);
1584 const float32x4_t m128_f_yy = vmlaq_f32(m128_f_C1, m128_f_X1, m128_f_x_0123);
1585 const float32x4_t m128_f_zz = vmlaq_f32(m128_f_C2, m128_f_X2, m128_f_x_0123);
1587#ifdef USE_DIVISION_ARM64_ARCHITECTURE
1590 const float32x4_t m128_f_inputX = vdivq_f32(m128_f_xx, m128_f_zz);
1591 const float32x4_t m128_f_inputY = vdivq_f32(m128_f_yy, m128_f_zz);
1597 float32x4_t inv_zz_128 = vrecpeq_f32(m128_f_zz);
1598 inv_zz_128 = vmulq_f32(vrecpsq_f32(m128_f_zz, inv_zz_128), inv_zz_128);
1601 const float32x4_t m128_f_inputX = vmulq_f32(m128_f_xx, inv_zz_128);
1602 const float32x4_t m128_f_inputY = vmulq_f32(m128_f_yy, inv_zz_128);
1607 const uint32x4_t m128_u_validPixelX = vandq_u32(vcltq_f32(m128_f_inputX, m128_f_inputWidth_pointFive), vcgtq_f32(m128_f_inputX, m128_f_negPointFive));
1608 const uint32x4_t m128_u_validPixelY = vandq_u32(vcltq_f32(m128_f_inputY, m128_f_inputHeight_pointFive), vcgtq_f32(m128_f_inputY, m128_f_negPointFive));
1610 const uint32x4_t m128_u_validPixel = vandq_u32(m128_u_validPixelX, m128_u_validPixelY);
1613 const uint32x2_t m64_u_validPixel = vorr_u32(vget_low_u32(m128_u_validPixel), vget_high_u32(m128_u_validPixel));
1614 if ((vget_lane_u32(m64_u_validPixel, 0) | vget_lane_u32(m64_u_validPixel, 1)) == 0x00000000u)
1618 OCEAN_ALIGN_DATA(16)
unsigned int debugValidPixels[4];
1620 vst1q_u32(debugValidPixels, m128_u_validPixel);
1621 ocean_assert(!(debugValidPixels[0] || debugValidPixels[1] || debugValidPixels[2] || debugValidPixels[3]));
1624 outputPixelData[0] = bColor;
1625 outputPixelData[1] = bColor;
1626 outputPixelData[2] = bColor;
1627 outputPixelData[3] = bColor;
1629 outputPixelData += 4;
1635 vst1q_u32(validPixels, m128_u_validPixel);
1636 ocean_assert(validPixels[0] || validPixels[1] || validPixels[2] || validPixels[3]);
1638 const uint32x4_t m128_u_inputX = vcvtq_u32_f32(vaddq_f32(m128_f_inputX, m128_f_pointFive));
1639 const uint32x4_t m128_u_inputY = vcvtq_u32_f32(vaddq_f32(m128_f_inputY, m128_f_pointFive));
1640 const uint32x4_t m_128_u_nearestNeighbourElementOffsets = vmlaq_u32(vmulq_u32(m128_u_inputY, m128_u_inputStrideElements), m128_u_inputX, m128_u_channels);
1641 vst1q_u32(nearestNeighbourElementOffsets, m_128_u_nearestNeighbourElementOffsets);
1644 unsigned int debugInputX[4];
1645 unsigned int debugInputY[4];
1646 vst1q_u32(debugInputX, m128_u_inputX);
1647 vst1q_u32(debugInputY, m128_u_inputY);
1648 ocean_assert(!validPixels[0] || (debugInputX[0] < inputWidth && debugInputY[0] < inputHeight));
1649 ocean_assert(!validPixels[1] || (debugInputX[1] < inputWidth && debugInputY[1] < inputHeight));
1650 ocean_assert(!validPixels[2] || (debugInputX[2] < inputWidth && debugInputY[2] < inputHeight));
1651 ocean_assert(!validPixels[3] || (debugInputX[3] < inputWidth && debugInputY[3] < inputHeight));
1654 outputPixelData[0] = validPixels[0] ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[0]) : bColor;
1655 outputPixelData[1] = validPixels[1] ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[1]) : bColor;
1656 outputPixelData[2] = validPixels[2] ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[2]) : bColor;
1657 outputPixelData[3] = validPixels[3] ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[3]) : bColor;
1659 outputPixelData += 4;
1666template <
unsigned int tChannels>
1667void FrameInterpolatorNearestPixel::homographyMask8BitPerChannelSubset(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const SquareMatrix3* input_H_output, uint8_t* output,
const unsigned int outputPaddingElements, uint8_t* outputMask,
const unsigned int outputMaskPaddingElements,
const uint8_t maskValue,
const int outputOriginX,
const int outputOriginY,
const unsigned int outputWidth,
const unsigned int outputHeight,
const unsigned int firstOutputRow,
const unsigned int numberOutputRows)
1669 static_assert(tChannels > 0u,
"Invalid channel number!");
1671 ocean_assert(input !=
nullptr && output !=
nullptr && outputMask !=
nullptr);
1672 ocean_assert(inputWidth > 0u && inputHeight > 0u);
1673 ocean_assert(outputWidth > 0u && outputHeight > 0u);
1674 ocean_assert(input_H_output !=
nullptr && !input_H_output->
isSingular());
1676 ocean_assert_and_suppress_unused(firstOutputRow + numberOutputRows <= outputHeight, outputHeight);
1678 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1679 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1680 const unsigned int outputMaskStrideElements = outputWidth + outputMaskPaddingElements;
1684 output += firstOutputRow * outputStrideElements;
1685 outputMask += firstOutputRow * outputMaskStrideElements;
1687 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
1689 PixelType* outputPixel = (PixelType*)(output);
1691 for (
unsigned int x = 0; x < outputWidth; ++x)
1694 const Vector2 inputPosition(*input_H_output * outputPosition);
1699 if (inputX < inputWidth && inputY < inputHeight)
1701 *outputPixel = *((PixelType*)(input + inputY * inputStrideElements + inputX * tChannels));
1702 *outputMask = maskValue;
1706 *outputMask = 0xFFu - maskValue;
1713 output += outputStrideElements;
1714 outputMask += outputMaskPaddingElements;
1718template <
unsigned int tChannels>
1719void FrameInterpolatorNearestPixel::transform8BitPerChannelSubset(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const LookupTable* lookupTable,
const bool offset,
const uint8_t* borderColor, uint8_t* output,
const unsigned int inputPaddingElements,
const unsigned int outputPaddingElements,
const unsigned int firstRow,
const unsigned int numberRows)
1721 static_assert(tChannels > 0u,
"Invalid channel number!");
1723 ocean_assert(lookupTable !=
nullptr);
1724 ocean_assert(input !=
nullptr && output !=
nullptr);
1726 ocean_assert(inputWidth != 0u && inputHeight != 0u);
1727 ocean_assert(firstRow + numberRows <= lookupTable->sizeY());
1729 const unsigned int outputWidth = (
unsigned int)(lookupTable->
sizeX());
1731 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1732 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1736 const uint8_t zeroColor[tChannels] = {uint8_t(0)};
1737 const PixelType*
const bColor = borderColor ? (PixelType*)(borderColor) : (PixelType*)(zeroColor);
1741 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1743 PixelType* outputData = (PixelType*)(output + y * outputStrideElements);
1745 for (
unsigned int x = 0u; x < outputWidth; ++x)
1753 if (inputX < inputWidth && inputY < inputHeight)
1755 *outputData = *((
const PixelType*)(input + inputY * inputStrideElements) + inputX);
1759 *outputData = *bColor;
1768 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1770 PixelType* outputData = (PixelType*)(output + y * outputStrideElements);
1772 for (
unsigned int x = 0u; x < outputWidth; ++x)
1779 if (inputX < inputWidth && inputY < inputHeight)
1781 *outputData = *((
const PixelType*)(input + inputY * inputStrideElements) + inputX);
1785 *outputData = *bColor;
1794template <
unsigned int tChannels>
1795void FrameInterpolatorNearestPixel::transformMask8BitPerChannelSubset(
const uint8_t* input,
const unsigned int inputWidth,
const unsigned int inputHeight,
const unsigned int inputPaddingElements,
const LookupTable* lookupTable,
const bool offset, uint8_t* output,
const unsigned int outputPaddingElements, uint8_t* outputMask,
const unsigned int outputMaskPaddingElements,
const uint8_t maskValue,
const unsigned int firstRow,
const unsigned int numberRows)
1797 static_assert(tChannels > 0u,
"Invalid channel number!");
1799 ocean_assert(lookupTable !=
nullptr);
1800 ocean_assert(input !=
nullptr && output !=
nullptr);
1802 ocean_assert(inputWidth != 0u && inputHeight != 0u);
1803 ocean_assert(firstRow + numberRows <= lookupTable->sizeY());
1806 const unsigned int outputWidth = (
unsigned int)(lookupTable->
sizeX());
1808 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1809 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1810 const unsigned int outputMaskStrideElements = outputWidth + outputMaskPaddingElements;
1814 output += firstRow * outputStrideElements;
1815 outputMask += firstRow * outputMaskStrideElements;
1819 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1821 PixelType* outputPixel = (PixelType*)(output);
1823 for (
unsigned int x = 0u; x < lookupTable->
sizeX(); ++x)
1831 if (inputX < inputWidth && inputY < inputHeight)
1833 *outputPixel = *((PixelType*)(input + inputY * inputStrideElements + inputX * tChannels));
1834 *outputMask = maskValue;
1838 *outputMask = 0xFF - maskValue;
1845 output += outputStrideElements;
1846 outputMask += outputMaskPaddingElements;
1851 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1853 PixelType* outputPixel = (PixelType*)(output);
1855 for (
unsigned int x = 0u; x < lookupTable->
sizeX(); ++x)
1862 if (inputX < inputWidth && inputY < inputHeight)
1864 *outputPixel = *((PixelType*)(input + inputY * inputStrideElements + inputX * tChannels));
1865 *outputMask = maskValue;
1869 *outputMask = 0xFF - maskValue;
1876 output += outputStrideElements;
1877 outputMask += outputMaskPaddingElements;
The following comfort class provides comfortable functions simplifying prototyping applications but a...
Definition FrameInterpolatorNearestPixel.h:49
static bool rotate90(const Frame &input, Frame &output, const bool clockwise, Worker *worker=nullptr)
Rotates a given frame either clockwise or counter-clockwise by 90 degrees.
Definition FrameInterpolatorNearestPixel.h:589
static bool affine(const Frame &input, Frame &output, const SquareMatrix3 &input_A_output, const uint8_t *borderColor=nullptr, Worker *worker=nullptr, const PixelPositionI &outputOrigin=PixelPositionI(0, 0))
Applies an affine image transformation to a frame (with zipped pixel format) and renders using neares...
static bool resize(const Frame &source, Frame &target, Worker *worker=nullptr)
Resizes a given frame by a nearest pixel search.
static bool transform(const Frame &input, Frame &output, const LookupTable &lookupTable, const bool offset, const uint8_t *borderColor, Worker *worker=nullptr)
Transforms a given input frame (with 1 plane) into an output frame by application of an interpolation...
static bool transformMask(const Frame &input, Frame &output, Frame &outputMask, const LookupTable &lookupTable, const bool offset, Worker *worker=nullptr, const uint8_t maskValue=0xFFu)
Transforms a given input frame (with zipped pixel format) into an output frame by application of an i...
static bool homographyMask(const Frame &input, Frame &output, Frame &outputMask, const SquareMatrix3 &input_H_output, Worker *worker=nullptr, const uint8_t maskValue=0xFFu, const PixelPositionI &outputOrigin=PixelPositionI(0, 0))
Transforms a given input frame (with zipped pixel format) into an output frame (with arbitrary frame ...
static bool rotate180(const Frame &input, Frame &output, Worker *worker=nullptr)
Rotates a given frame by 180 degrees.
Definition FrameInterpolatorNearestPixel.h:594
static bool rotate(const Frame &input, Frame &output, const int angle, Worker *worker=nullptr)
Rotates a given frame with 90 degree steps.
Definition FrameInterpolatorNearestPixel.h:599
static bool homography(const Frame &input, Frame &output, const SquareMatrix3 &input_H_output, const void *borderColor=nullptr, Worker *worker=nullptr, const PixelPositionI &outputOrigin=PixelPositionI(0, 0))
Transforms a given input frame (with zipped pixel format) into an output frame by application of a ho...
This class implements highly optimized interpolation functions with fixed properties.
Definition FrameInterpolatorNearestPixel.h:189
static void resize400x400To224x224_8BitPerChannel(const uint8_t *const source, uint8_t *const target, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements)
Resizes a given FORMAT_Y8 frame with resolution 400x400 to a FORMAT_Y8 frame with resolution 224x224 ...
This class implements a nearest pixel frame interpolator.
Definition FrameInterpolatorNearestPixel.h:35
static void resize(const T *source, T *target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Resizes a given frame by a nearest pixel search and uses several CPU cores to speed update the proces...
Definition FrameInterpolatorNearestPixel.h:605
static void homography(const T *input, const unsigned int inputWidth, const unsigned int inputHeight, const SquareMatrix3 &input_H_output, const T *borderColor, T *output, const PixelPositionI &outputOrigin, const unsigned int outputWidth, const unsigned int outputHeight, const unsigned int inputPaddingElements, const unsigned int outputPaddingElements, Worker *worker=nullptr)
Transforms a given input frame into an output frame by application of a homography.
Definition FrameInterpolatorNearestPixel.h:664
static void affine8BitPerChannel(const uint8_t *input, const unsigned int inputWidth, const unsigned int inputHeight, const SquareMatrix3 &input_A_output, const uint8_t *borderColor, uint8_t *output, const PixelPositionI &outputOrigin, const unsigned int outputWidth, const unsigned int outputHeight, const unsigned int inputPaddingElements, const unsigned int outputPaddingElements, Worker *worker=nullptr)
Applies an affine image transformation to an 8 bit per channel input frame and renders the output.
Definition FrameInterpolatorNearestPixel.h:620
static void transform8BitPerChannel(const uint8_t *input, const unsigned int inputWidth, const unsigned int inputHeight, const LookupTable &lookupTable, const bool offset, const uint8_t *borderColor, uint8_t *output, const unsigned int inputPaddingElements, const unsigned int outputPaddingElements, Worker *worker=nullptr)
Transforms a given input frame (with zipped pixel format) into an output frame by application of an i...
Definition FrameInterpolatorNearestPixel.h:719
static void homographySubset(const T *input, const unsigned int inputWidth, const unsigned int inputHeight, const SquareMatrix3 *input_H_output, const T *borderColor, T *output, const unsigned int outputWidth, const unsigned int outputHeight, const unsigned int inputPaddingElements, const unsigned int outputPaddingElements, const unsigned int firstOutputRow, const unsigned int numberOutputRows)
Copies the image content of an input image to a subset of an output image by application of a given h...
Definition FrameInterpolatorNearestPixel.h:881
static void resizeSubset(const T *source, T *target, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int targetWidth, const unsigned int targetHeight, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
Resizes a given frame by a nearest pixel search.
Definition FrameInterpolatorNearestPixel.h:757
static void rotate90(const TElementType *source, TElementType *target, const unsigned int sourceWidth, const unsigned int sourceHeight, const bool clockwise, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Rotates a given frame either clockwise or counter-clockwise by 90 degree.
Definition FrameInterpolatorNearestPixel.h:745
static void affine8BitPerChannelSSESubset(const uint8_t *input, const unsigned int inputWidth, const unsigned int inputHeight, const unsigned int inputPaddingElements, const SquareMatrix3 *affineTransform, const uint8_t *borderColor, uint8_t *output, const unsigned int outputWidth, const unsigned int outputHeight, const unsigned int outputPaddingElements, const unsigned int firstOutputRow, const unsigned int numberOutputRows)
Apply an affine image transformation to an 8 bit per channel frame using nearest neighbor interpolati...
Definition FrameInterpolatorNearestPixel.h:929
static void transformMask8BitPerChannelSubset(const uint8_t *input, const unsigned int inputWidth, const unsigned int inputHeight, const unsigned int inputPaddingElements, const LookupTable *lookupTable, const bool offset, uint8_t *output, const unsigned int outputPaddingElements, uint8_t *outputMask, const unsigned int outputMaskPaddingElements, const uint8_t maskValue, const unsigned int firstRow, const unsigned int numberRows)
Transforms a given input frame (with zipped pixel format) into an output frame by application of an i...
Definition FrameInterpolatorNearestPixel.h:1795
static void homographyMask8BitPerChannelSubset(const uint8_t *input, const unsigned int inputWidth, const unsigned int inputHeight, const unsigned int inputPaddingElements, const SquareMatrix3 *input_H_output, uint8_t *output, const unsigned int outputPaddingElements, uint8_t *outputMask, const unsigned int outputMaskPaddingElements, const uint8_t maskValue, const int outputOriginX, const int outputOriginY, const unsigned int outputWidth, const unsigned int outputHeight, const unsigned int firstOutputRow, const unsigned int numberOutputRows)
Transforms an 8 bit per channel frame using the given homography.
Definition FrameInterpolatorNearestPixel.h:1667
static void affine8BitPerChannelSubset(const uint8_t *input, const unsigned int inputWidth, const unsigned int inputHeight, const unsigned int inputPaddingElements, const SquareMatrix3 *affineTransform, const uint8_t *borderColor, uint8_t *output, const unsigned int outputWidth, const unsigned int outputHeight, const unsigned int outputPaddingElements, const unsigned int firstOutputRow, const unsigned int numberOutputRows)
Apply an affine image transformation to an 8 bit per channel frame using nearest neighbor interpolati...
Definition FrameInterpolatorNearestPixel.h:806
static void homographySSESubset(const T *input, const unsigned int inputWidth, const unsigned int inputHeight, const SquareMatrix3 *input_H_output, const T *borderColor, T *output, const unsigned int outputWidth, const unsigned int outputHeight, const unsigned int inputPaddingElements, const unsigned int outputPaddingElements, const unsigned int firstOutputRow, const unsigned int numberOutputRows)
Copies the image content of an input image to a subset of an output image by application of a given h...
Definition FrameInterpolatorNearestPixel.h:1067
static void homographyMask8BitPerChannel(const uint8_t *input, const unsigned int inputWidth, const unsigned int inputHeight, const unsigned int inputPaddingElements, const SquareMatrix3 &input_H_output, uint8_t *output, const unsigned int outputPaddingElements, uint8_t *outputMask, const unsigned int outputMaskPaddingElements, const PixelPositionI &outputOrigin, const unsigned int outputWidth, const unsigned int outputHeight, Worker *worker=nullptr, const uint8_t maskValue=0xFF)
Transforms a given 8 bit per channel input frame into an output frame by application of a homography.
Definition FrameInterpolatorNearestPixel.h:706
static void affine8BitPerChannelIntegerNEONSubset(const uint8_t *input, const unsigned int inputWidth, const unsigned int inputHeight, const unsigned int inputPaddingElements, const SquareMatrix3 *affineTransform, const uint8_t *borderColor, uint8_t *output, const unsigned int outputWidth, const unsigned int outputHeight, const unsigned int outputPaddingElements, const unsigned int firstOutputRow, const unsigned int numberOutputRows)
Affine image transformation for 8-bit per channel frames using nearest neighbor interpolation (using ...
Definition FrameInterpolatorNearestPixel.h:1235
static void transform8BitPerChannelSubset(const uint8_t *input, const unsigned int inputWidth, const unsigned int inputHeight, const LookupTable *lookupTable, const bool offset, const uint8_t *borderColor, uint8_t *output, const unsigned int inputPaddingElements, const unsigned int outputPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
Transforms a subset of a given input frame (with zipped pixel format) into an output frame by applica...
Definition FrameInterpolatorNearestPixel.h:1719
static void transformMask8BitPerChannel(const uint8_t *input, const unsigned int inputWidth, const unsigned int inputHeight, const unsigned int inputPaddingElements, const LookupTable &lookupTable, const bool offset, uint8_t *output, const unsigned int outputPaddingElements, uint8_t *outputMask, const unsigned int outputMaskPaddingElements, Worker *worker=nullptr, const uint8_t maskValue=0xFF)
Transforms a given input frame (with zipped pixel format) into an output frame by application of an i...
Definition FrameInterpolatorNearestPixel.h:732
static void homographyNEONSubset(const T *input, const unsigned int inputWidth, const unsigned int inputHeight, const SquareMatrix3 *input_H_output, const T *borderColor, T *output, const unsigned int outputWidth, const unsigned int outputHeight, const unsigned int inputPaddingElements, const unsigned int outputPaddingElements, const unsigned int firstOutputRow, const unsigned int numberOutputRows)
Copies the image content of an input image to a subset of an output image by application of a given h...
Definition FrameInterpolatorNearestPixel.h:1485
static bool coversHomographyInputFrame(const unsigned int inputWidth, const unsigned int inputHeight, const unsigned int outputWidth, const unsigned int outputHeight, const SquareMatrix3 &input_H_output, const int outputOriginX=0, const int outputOriginY=0)
Checks whether the application of a given homography for a specified input frame and output frame cov...
static bool rotate(const Frame &input, Frame &output, const int angle, Worker *worker=nullptr)
Rotates a given frame with 90 degree steps.
static bool rotate180(const Frame &input, Frame &output, Worker *worker=nullptr)
Rotates a given frame by 180 degrees.
static bool rotate90(const Frame &input, Frame &output, const bool clockwise, Worker *worker=nullptr)
Rotates a given frame either clockwise or counter-clockwise by 90 degrees.
This class implements a 2D pixel position with pixel precision.
Definition PixelPosition.h:63
T y() const
Returns the vertical coordinate position of this object.
Definition PixelPosition.h:468
T x() const
Returns the horizontal coordinate position of this object.
Definition PixelPosition.h:456
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:2877
This class implements Ocean's image class.
Definition Frame.h:1879
void setRelativeTimestamp(const Timestamp &relative)
Sets the relative timestamp of this frame.
Definition Frame.h:4317
void setTimestamp(const Timestamp ×tamp)
Sets the timestamp of this frame.
Definition Frame.h:4312
const Timestamp & timestamp() const
Returns the timestamp of this frame.
Definition Frame.h:4302
const Timestamp & relativeTimestamp() const
Returns the relative timestamp of this frame.
Definition Frame.h:4307
Definition of a frame type composed by the frame dimension, pixel format and pixel origin.
Definition Frame.h:30
size_t sizeY() const
Returns the vertical dimension of this lookup object.
Definition Lookup2.h:947
size_t sizeX() const
Returns the horizontal dimension of this lookup object.
Definition Lookup2.h:941
This class implements a 2D lookup object with values at the bins' corners defining the individual loo...
Definition Lookup2.h:636
T bilinearValue(const TScalar x, const TScalar y) const
Applies a lookup for a specific position in this lookup object.
Definition Lookup2.h:1815
This class implements an object able to allocate memory.
Definition base/Memory.h:22
void * data()
Returns the pointer to the writable memory which is allocated by this object.
Definition base/Memory.h:303
This class provides basic numeric functionalities.
Definition Numeric.h:57
static constexpr int32_t round32(const T value)
Returns the rounded 32 bit integer value of a given value.
Definition Numeric.h:2073
static constexpr bool isEqualEps(const T value)
Returns whether a value is smaller than or equal to a small epsilon.
Definition Numeric.h:2096
bool isNull() const
Returns whether this matrix is a zero matrix.
Definition SquareMatrix3.h:1334
const T * data() const
Returns a pointer to the internal values.
Definition SquareMatrix3.h:1047
bool isSingular() const
Returns whether this matrix is singular (and thus cannot be inverted).
Definition SquareMatrix3.h:1342
typename TypeMapperBySize< sizeof(T)>::Type Type
Definition of an invalid mapped data type.
Definition DataType.h:508
const T & x() const noexcept
Returns the x value.
Definition Vector2.h:710
const T & y() const noexcept
Returns the y value.
Definition Vector2.h:722
bool isEqual(const VectorT2< T > &vector, const T eps) const
Returns whether two vectors are equal up to a specified epsilon.
Definition Vector2.h:758
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.
float Scalar
Definition of a scalar type.
Definition Math.h:129
SquareMatrixT3< Scalar > SquareMatrix3
Definition of the SquareMatrix3 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with ...
Definition SquareMatrix3.h:43
VectorT3< Scalar > Vector3
Definition of a 3D vector.
Definition Vector3.h:29
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition Vector2.h:28
The namespace covering the entire Ocean framework.
Definition Accessor.h:15
Default definition of a type with tBytes bytes.
Definition DataType.h:32