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);
604 template <
typename T,
unsigned int tChannels>
605 inline 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);
619 template <
unsigned int tChannels>
620 inline 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);
663 template <
typename T,
unsigned int tChannels>
664 inline 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);
705 template <
unsigned int tChannels>
706 inline 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);
718 template <
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()));
731 template <
unsigned int tChannels>
732 inline 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());
744 template <
typename TElementType,
unsigned int tChannels>
745 inline 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);
756 template <
typename T,
unsigned int tChannels>
757 void 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;
805 template <
unsigned int tChannels>
806 void 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)
865 *outputData = *(PixelType*)(input + inputY * (inputWidth * tChannels + inputPaddingElements) + inputX * tChannels);
867 *outputData = *bColor;
872 outputData = (PixelType*)((uint8_t*)outputData + outputPaddingElements);
876 template <
typename T,
unsigned int tChannels>
877 void 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)
879 static_assert(tChannels > 0u,
"Invalid channel number!");
881 ocean_assert(input !=
nullptr && output !=
nullptr);
882 ocean_assert(inputWidth > 0u && inputHeight > 0u);
883 ocean_assert(outputWidth > 0u && outputHeight > 0u);
884 ocean_assert(input_H_output !=
nullptr && !input_H_output->
isSingular());
886 ocean_assert_and_suppress_unused(firstOutputRow + numberOutputRows <= outputHeight, outputHeight);
888 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
889 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
893 const T zeroColor[tChannels] = {T(0)};
894 const PixelType bColor = borderColor ? *(
const PixelType*)(borderColor) : *(
const PixelType*)(zeroColor);
896 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
898 PixelType* outputData = (PixelType*)(output + y * outputStrideElements);
900 for (
unsigned int x = 0u; x < outputWidth; ++x)
903 const Vector2 inputPosition(*input_H_output * outputPosition);
908 if (inputX < inputWidth && inputY < inputHeight)
910 *outputData = *((
const PixelType*)(input + inputY * inputStrideElements) + inputX);
914 *outputData = bColor;
922 #if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
924 template <
unsigned int tChannels>
925 inline 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)
927 static_assert(tChannels >= 1u,
"Invalid channel number!");
929 ocean_assert(input && output);
930 ocean_assert(inputWidth > 0u && inputHeight > 0u);
931 ocean_assert(outputWidth >= 4u && outputHeight > 0u);
932 ocean_assert(affineTransform);
935 ocean_assert_and_suppress_unused(firstOutputRow + numberOutputRows <= outputHeight, outputHeight);
939 const uint8_t zeroColor[tChannels] = {uint8_t(0)};
940 const PixelType*
const bColor = borderColor ? (PixelType*)borderColor : (PixelType*)zeroColor;
942 PixelType* outputPixelData = (PixelType*)(output + firstOutputRow * (outputWidth * tChannels + outputPaddingElements));
945 unsigned int nearestNeighbours[4];
948 const __m128 m128_f_X0 = _mm_set_ps1(
float((*affineTransform)(0, 0)));
949 const __m128 m128_f_X1 = _mm_set_ps1(
float((*affineTransform)(1, 0)));
952 const __m128i m128_i_inputStrideElements = _mm_set1_epi32(inputWidth * tChannels + inputPaddingElements);
955 const __m128i m128_i_channels = _mm_set1_epi32(tChannels);
958 const __m128i m128_i_inputWidth_1 = _mm_set1_epi32(inputWidth - 1u);
961 const __m128i m128_i_inputHeight_1 = _mm_set1_epi32(inputHeight - 1u);
964 const __m128i m128_i_zero = _mm_setzero_si128();
967 const unsigned int inputElementsEnd = inputHeight * inputWidth * tChannels + (inputHeight - 1u) * inputPaddingElements;
969 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
991 const __m128 m128_f_C0 = _mm_set_ps1(
float((*affineTransform)(0, 1) *
Scalar(y) + (*affineTransform)(0, 2)));
992 const __m128 m128_f_C1 = _mm_set_ps1(
float((*affineTransform)(1, 1) *
Scalar(y) + (*affineTransform)(1, 2)));
994 for (
unsigned int x = 0u; x < outputWidth; x += 4u)
996 if (x + 4u > outputWidth)
1001 ocean_assert(x >= 4u && outputWidth > 4u);
1002 const unsigned int newX = outputWidth - 4u;
1004 ocean_assert(x > newX);
1005 outputPixelData -= x - newX;
1010 ocean_assert(!(x + 4u < outputWidth));
1015 const __m128 m128_f_x_0123 = _mm_set_ps(
float(x + 3u),
float(x + 2u),
float(x + 1u),
float(x + 0u));
1018 const __m128 m128_f_inputX = _mm_add_ps(_mm_mul_ps(m128_f_X0, m128_f_x_0123), m128_f_C0);
1019 const __m128 m128_f_inputY = _mm_add_ps(_mm_mul_ps(m128_f_X1, m128_f_x_0123), m128_f_C1);
1022 const __m128i m128_i_inputX = _mm_cvtps_epi32(_mm_round_ps(m128_f_inputX, _MM_FROUND_TO_NEAREST_INT));
1023 const __m128i m128_i_inputY = _mm_cvtps_epi32(_mm_round_ps(m128_f_inputY, _MM_FROUND_TO_NEAREST_INT));
1040 const __m128i m128_i_isOutsideImage = _mm_or_si128(
1041 _mm_or_si128(_mm_cmplt_epi32(m128_i_inputX, m128_i_zero), _mm_cmplt_epi32(m128_i_inputY, m128_i_zero)),
1042 _mm_or_si128(_mm_cmpgt_epi32(m128_i_inputX, m128_i_inputWidth_1), _mm_cmpgt_epi32(m128_i_inputY, m128_i_inputHeight_1)));
1046 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)));
1047 _mm_store_si128((__m128i*)nearestNeighbours, m_128_i_nearestNeighborElements);
1050 outputPixelData[0] = nearestNeighbours[0] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighbours[0]) : *bColor;
1051 outputPixelData[1] = nearestNeighbours[1] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighbours[1]) : *bColor;
1052 outputPixelData[2] = nearestNeighbours[2] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighbours[2]) : *bColor;
1053 outputPixelData[3] = nearestNeighbours[3] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighbours[3]) : *bColor;
1055 outputPixelData += 4u;
1058 outputPixelData = (PixelType*)((uint8_t*)outputPixelData + outputPaddingElements);
1062 template <
typename T,
unsigned int tChannels>
1063 void 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)
1065 static_assert(tChannels > 0u,
"Invalid channel number!");
1067 ocean_assert(input !=
nullptr && output !=
nullptr);
1068 ocean_assert(inputWidth > 0u && inputHeight > 0u);
1069 ocean_assert(outputWidth >= 4u && outputHeight > 0u);
1070 ocean_assert(input_H_output !=
nullptr && !input_H_output->
isSingular());
1072 ocean_assert_and_suppress_unused(firstOutputRow + numberOutputRows <= outputHeight, outputHeight);
1074 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1075 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1079 const T zeroColor[tChannels] = {T(0)};
1080 const PixelType bColor = borderColor ? *(
const PixelType*)(borderColor) : *(
const PixelType*)(zeroColor);
1082 OCEAN_ALIGN_DATA(16)
unsigned int nearestNeighbourElementOffsets[4];
1110 const __m128 m128_f_X0 = _mm_set_ps1((
float)(*input_H_output)(0, 0));
1111 const __m128 m128_f_X1 = _mm_set_ps1((
float)(*input_H_output)(1, 0));
1112 const __m128 m128_f_X2 = _mm_set_ps1((
float)(*input_H_output)(2, 0));
1115 const __m128i m128_i_inputStrideElements = _mm_set1_epi32(inputStrideElements);
1117 const unsigned int inputPixelElementIndexEnd = inputHeight * inputStrideElements;
1120 const __m128i m128_i_inputWidth_1 = _mm_set1_epi32(inputWidth - 1u);
1123 const __m128i m128_i_inputHeight_1 = _mm_set1_epi32(inputHeight - 1u);
1126 const __m128i m128_i_channels = _mm_set1_epi32(tChannels);
1129 const __m128i m128_i_zero = _mm_setzero_si128();
1131 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
1133 PixelType* outputPixelData = (PixelType*)(output + y * outputStrideElements);
1136 const __m128 m128_f_C0 = _mm_set_ps1((
float)((*input_H_output)(0, 1) *
Scalar(y) + ((*input_H_output)(0, 2))));
1137 const __m128 m128_f_C1 = _mm_set_ps1((
float)((*input_H_output)(1, 1) *
Scalar(y) + ((*input_H_output)(1, 2))));
1138 const __m128 m128_f_C2 = _mm_set_ps1((
float)((*input_H_output)(2, 1) *
Scalar(y) + ((*input_H_output)(2, 2))));
1140 for (
unsigned int x = 0u; x < outputWidth; x += 4u)
1142 if (x + 4u > outputWidth)
1147 ocean_assert(x >= 4u && outputWidth > 4u);
1148 const unsigned int newX = outputWidth - 4u;
1150 ocean_assert(x > newX);
1151 outputPixelData -= x - newX;
1156 ocean_assert(!(x + 4u < outputWidth));
1161 const __m128 m128_f_x_0123 = _mm_set_ps(
float(x + 3u),
float(x + 2u),
float(x + 1u),
float(x + 0u));
1164 const __m128 m128_f_xx = _mm_add_ps(_mm_mul_ps(m128_f_X0, m128_f_x_0123), m128_f_C0);
1165 const __m128 m128_f_yy = _mm_add_ps(_mm_mul_ps(m128_f_X1, m128_f_x_0123), m128_f_C1);
1166 const __m128 m128_f_zz = _mm_add_ps(_mm_mul_ps(m128_f_X2, m128_f_x_0123), m128_f_C2);
1168 #ifdef USE_APPROXIMATED_INVERSE_OF_ZZ
1173 const __m128 inv_zz_128 = _mm_rcp_ps(m128_f_zz);
1176 const __m128 m128_f_inputX = _mm_mul_ps(m128_f_xx, inv_zz_128);
1177 const __m128 m128_f_inputY = _mm_mul_ps(m128_f_yy, inv_zz_128);
1182 const __m128 m128_f_inputX = _mm_div_ps(m128_f_xx, m128_f_zz);
1183 const __m128 m128_f_inputY = _mm_div_ps(m128_f_yy, m128_f_zz);
1188 const __m128i m128_i_inputX = _mm_cvtps_epi32(_mm_round_ps(m128_f_inputX, _MM_FROUND_TO_NEAREST_INT));
1189 const __m128i m128_i_inputY = _mm_cvtps_epi32(_mm_round_ps(m128_f_inputY, _MM_FROUND_TO_NEAREST_INT));
1206 const __m128i m128_i_isOutsideImage = _mm_or_si128(
1207 _mm_or_si128(_mm_cmplt_epi32(m128_i_inputX, m128_i_zero), _mm_cmplt_epi32(m128_i_inputY, m128_i_zero)),
1208 _mm_or_si128(_mm_cmpgt_epi32(m128_i_inputX, m128_i_inputWidth_1), _mm_cmpgt_epi32(m128_i_inputY, m128_i_inputHeight_1)));
1212 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)));
1213 _mm_store_si128((__m128i*)nearestNeighbourElementOffsets, m_128_i_nearestNeighbors);
1216 outputPixelData[0] = nearestNeighbourElementOffsets[0] < inputPixelElementIndexEnd ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[0]) : bColor;
1217 outputPixelData[1] = nearestNeighbourElementOffsets[1] < inputPixelElementIndexEnd ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[1]) : bColor;
1218 outputPixelData[2] = nearestNeighbourElementOffsets[2] < inputPixelElementIndexEnd ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[2]) : bColor;
1219 outputPixelData[3] = nearestNeighbourElementOffsets[3] < inputPixelElementIndexEnd ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[3]) : bColor;
1221 outputPixelData += 4u;
1228 #if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
1230 template <
unsigned int tChannels>
1231 void 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)
1283 static_assert(tChannels >= 1u,
"Invalid channel number!");
1285 constexpr
unsigned int fractionalBits = 15u;
1286 constexpr
unsigned int totalBits = (
unsigned int)(CHAR_BIT *
sizeof(
int));
1288 static_assert((fractionalBits + 1u ) < totalBits,
"Number of fractional bits exceeds number of total bits");
1290 constexpr
unsigned int maxImageEdgeLength = 1u << (totalBits - fractionalBits - 1u );
1293 constexpr
Scalar fixedPointScale =
Scalar(1u << fractionalBits);
1296 constexpr
unsigned int pixelsPerIteration = 4u;
1298 ocean_assert(input && output);
1299 ocean_assert_and_suppress_unused(inputWidth > 0u && inputHeight > 0u && inputWidth <= maxImageEdgeLength && inputHeight <= maxImageEdgeLength, maxImageEdgeLength);
1300 ocean_assert_and_suppress_unused(outputWidth >= pixelsPerIteration && outputHeight > 0u && outputWidth <= maxImageEdgeLength && outputHeight <= maxImageEdgeLength, maxImageEdgeLength);
1301 ocean_assert(affineTransform);
1304 ocean_assert(firstOutputRow + numberOutputRows <= outputHeight);
1308 const uint8_t zeroColor[tChannels] = {uint8_t(0)};
1309 const PixelType*
const bColor = borderColor ? (PixelType*)borderColor : (PixelType*)zeroColor;
1311 PixelType* outputPixelData = (PixelType*)(output + firstOutputRow * (outputWidth * tChannels + outputPaddingElements));
1313 const unsigned int outputRowEnd = firstOutputRow + numberOutputRows;
1316 unsigned int nearestNeighboursElements[4];
1319 const unsigned int inputElementsEnd = inputHeight * inputWidth * tChannels + (inputHeight - 1u) * inputPaddingElements;
1322 const uint32x4_t m128_u_inputWidth = vdupq_n_u32(inputWidth);
1323 const uint32x4_t m128_u_inputHeight = vdupq_n_u32(inputHeight);
1326 const uint32x4_t m128_u_inputStrideElements = vdupq_n_u32(inputWidth * tChannels + inputPaddingElements);
1329 const uint32x4_t m128_u_channels = vdupq_n_u32(tChannels);
1332 const int offsets_0123[4] = { 0, 1, 2, 3 };
1333 const int32x4_t m128_s_offsets_0123 = vld1q_s32(offsets_0123);
1336 const float32x4_t m128_f_pixelsPerIteration = vdupq_n_f32((
float)pixelsPerIteration);
1342 const float32x4_t m128_f_X0 = vdupq_n_f32(
float(fixedPointScale * (*affineTransform)(0, 0)));
1343 const float32x4_t m128_f_X1 = vdupq_n_f32(
float(fixedPointScale * (*affineTransform)(1, 0)));
1347 const int32x4_t m128_s_q_X0x_increment = vcvtq_s32_f32(vmulq_f32(m128_f_X0, m128_f_pixelsPerIteration));
1348 const int32x4_t m128_s_q_X1x_increment = vcvtq_s32_f32(vmulq_f32(m128_f_X1, m128_f_pixelsPerIteration));
1351 constexpr
unsigned int blockSize = 64u;
1352 constexpr
unsigned int blockElements = blockSize * blockSize;
1353 const unsigned int blockWidth = std::min(blockElements / std::min(numberOutputRows, blockSize), outputWidth);
1354 const unsigned int blockHeight = std::min(blockElements / blockWidth, numberOutputRows);
1355 ocean_assert(blockWidth > 0u && blockWidth <= outputWidth);
1356 ocean_assert(blockHeight > 0u && blockHeight <= numberOutputRows);
1362 const unsigned int lastMultipleNeonPixelBlockStart = outputWidth - pixelsPerIteration;
1365 const float32x4_t m128_f_lastMultipleNeonPixelBlockStart = vcvtq_f32_s32(vaddq_s32(vdupq_n_s32((
int)lastMultipleNeonPixelBlockStart), m128_s_offsets_0123));
1368 const int32x4_t m128_s_q_X0x_lastMultipleNeonPixelBlockStart = vcvtq_s32_f32(vmulq_f32(m128_f_X0, m128_f_lastMultipleNeonPixelBlockStart));
1369 const int32x4_t m128_s_q_X1x_lastMultipleNeonPixelBlockStart = vcvtq_s32_f32(vmulq_f32(m128_f_X1, m128_f_lastMultipleNeonPixelBlockStart));
1371 for (
unsigned int blockYStart = firstOutputRow; blockYStart < outputRowEnd; blockYStart += blockHeight)
1373 const unsigned int blockYEnd = std::min(blockYStart + blockHeight, outputRowEnd);
1375 for (
unsigned int blockXStart = 0u; blockXStart < outputWidth; blockXStart += blockWidth)
1377 const unsigned int blockXEnd = std::min(blockXStart + blockWidth, outputWidth);
1379 for (
unsigned int y = blockYStart; y < blockYEnd; ++y)
1381 outputPixelData = (PixelType*)(output + y * (outputWidth * tChannels + outputPaddingElements) + blockXStart * tChannels);
1385 const int32x4_t m128_s_q_C0 = vdupq_n_s32(
Numeric::round32(fixedPointScale * ((*affineTransform)(0, 1) *
Scalar(y) + (*affineTransform)(0, 2))));
1386 const int32x4_t m128_s_q_C1 = vdupq_n_s32(
Numeric::round32(fixedPointScale * ((*affineTransform)(1, 1) *
Scalar(y) + (*affineTransform)(1, 2))));
1393 const int32x4_t m128_s_x_0123 = vaddq_s32(vdupq_n_s32(
int(blockXStart)), m128_s_offsets_0123);
1396 const float32x4_t m128_f_x_0123 = vcvtq_f32_s32(m128_s_x_0123);
1399 int32x4_t m128_s_q_X0x = vcvtq_s32_f32(vmulq_f32(m128_f_X0, m128_f_x_0123));
1400 int32x4_t m128_s_q_X1x = vcvtq_s32_f32(vmulq_f32(m128_f_X1, m128_f_x_0123));
1402 for (
unsigned int x = blockXStart; x < blockXEnd; x += pixelsPerIteration)
1404 if (x + pixelsPerIteration > outputWidth)
1406 ocean_assert(x + pixelsPerIteration > outputWidth);
1407 ocean_assert(x >= pixelsPerIteration && outputWidth > pixelsPerIteration);
1408 ocean_assert(lastMultipleNeonPixelBlockStart == (outputWidth - pixelsPerIteration));
1410 outputPixelData -= (x - lastMultipleNeonPixelBlockStart);
1412 x = lastMultipleNeonPixelBlockStart;
1414 m128_s_q_X0x = m128_s_q_X0x_lastMultipleNeonPixelBlockStart;
1415 m128_s_q_X1x = m128_s_q_X1x_lastMultipleNeonPixelBlockStart;
1418 ocean_assert(!(x + pixelsPerIteration < outputWidth));
1424 const int32x4_t m128_s_q_inputX = vaddq_s32(m128_s_q_C0, m128_s_q_X0x);
1425 const int32x4_t m128_s_q_inputY = vaddq_s32(m128_s_q_C1, m128_s_q_X1x);
1432 const uint32x4_t m128_u_inputX = vreinterpretq_u32_s32(vrshrq_n_s32(m128_s_q_inputX, fractionalBits));
1433 const uint32x4_t m128_u_inputY = vreinterpretq_u32_s32(vrshrq_n_s32(m128_s_q_inputY, fractionalBits));
1452 const uint32x4_t m128_u_isOutsideImage = vorrq_u32(vcgeq_u32(m128_u_inputX, m128_u_inputWidth), vcgeq_u32(m128_u_inputY, m128_u_inputHeight));
1459 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)));
1460 vst1q_u32(nearestNeighboursElements, m_128_u_nearestNeighborsElements);
1462 outputPixelData[0] = nearestNeighboursElements[0] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighboursElements[0]) : *bColor;
1463 outputPixelData[1] = nearestNeighboursElements[1] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighboursElements[1]) : *bColor;
1464 outputPixelData[2] = nearestNeighboursElements[2] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighboursElements[2]) : *bColor;
1465 outputPixelData[3] = nearestNeighboursElements[3] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighboursElements[3]) : *bColor;
1467 outputPixelData += pixelsPerIteration;
1470 m128_s_q_X0x = vaddq_s32(m128_s_q_X0x, m128_s_q_X0x_increment);
1471 m128_s_q_X1x = vaddq_s32(m128_s_q_X1x, m128_s_q_X1x_increment);
1476 outputPixelData = (PixelType*)((uint8_t*)outputPixelData + outputPaddingElements);
1480 template <
typename T,
unsigned int tChannels>
1481 void 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)
1483 static_assert(tChannels >= 1u,
"Invalid channel number!");
1485 ocean_assert(input !=
nullptr && output !=
nullptr);
1486 ocean_assert(inputWidth > 0u && inputHeight > 0u);
1487 ocean_assert(outputWidth >= 4u && outputHeight > 0u);
1488 ocean_assert(input_H_output !=
nullptr && !input_H_output->
isSingular());
1490 ocean_assert(firstOutputRow + numberOutputRows <= outputHeight);
1492 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1493 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1497 const T zeroColor[tChannels] = {T(0)};
1498 const PixelType bColor = borderColor ? *(
const PixelType*)(borderColor) : *(
const PixelType*)(zeroColor);
1500 unsigned int validPixels[4];
1501 unsigned int nearestNeighbourElementOffsets[4];
1529 const float32x4_t m128_f_X0 = vdupq_n_f32(
float((*input_H_output)(0, 0)));
1530 const float32x4_t m128_f_X1 = vdupq_n_f32(
float((*input_H_output)(1, 0)));
1531 const float32x4_t m128_f_X2 = vdupq_n_f32(
float((*input_H_output)(2, 0)));
1534 const float32x4_t m128_f_pointFive = vdupq_n_f32(0.5f);
1535 const float32x4_t m128_f_negPointFive = vdupq_n_f32(-0.5f);
1538 const uint32x4_t m128_u_inputStrideElements = vdupq_n_u32(inputStrideElements);
1540 const uint32x4_t m128_u_channels = vdupq_n_u32(tChannels);
1543 const float32x4_t m128_f_inputWidth_pointFive = vdupq_n_f32(
float(inputWidth) - 0.5f);
1544 const float32x4_t m128_f_inputHeight_pointFive = vdupq_n_f32(
float(inputHeight) - 0.5f);
1546 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
1548 PixelType* outputPixelData = (PixelType*)(output + y * outputStrideElements);
1551 const float32x4_t m128_f_C0 = vdupq_n_f32(
float((*input_H_output)(0, 1) *
Scalar(y) + (*input_H_output)(0, 2)));
1552 const float32x4_t m128_f_C1 = vdupq_n_f32(
float((*input_H_output)(1, 1) *
Scalar(y) + (*input_H_output)(1, 2)));
1553 const float32x4_t m128_f_C2 = vdupq_n_f32(
float((*input_H_output)(2, 1) *
Scalar(y) + (*input_H_output)(2, 2)));
1555 for (
unsigned int x = 0u; x < outputWidth; x += 4u)
1557 if (x + 4u > outputWidth)
1561 ocean_assert(x >= 4u && outputWidth > 4u);
1562 const unsigned int newX = outputWidth - 4u;
1564 ocean_assert(x > newX);
1565 outputPixelData -= x - newX;
1570 ocean_assert(!(x + 4u < outputWidth));
1575 float x_0123[4] = { float(x + 0u), float(x + 1u), float(x + 2u), float(x + 3u) };
1576 const float32x4_t m128_f_x_0123 = vld1q_f32(x_0123);
1579 const float32x4_t m128_f_xx = vmlaq_f32(m128_f_C0, m128_f_X0, m128_f_x_0123);
1580 const float32x4_t m128_f_yy = vmlaq_f32(m128_f_C1, m128_f_X1, m128_f_x_0123);
1581 const float32x4_t m128_f_zz = vmlaq_f32(m128_f_C2, m128_f_X2, m128_f_x_0123);
1583 #ifdef USE_DIVISION_ARM64_ARCHITECTURE
1586 const float32x4_t m128_f_inputX = vdivq_f32(m128_f_xx, m128_f_zz);
1587 const float32x4_t m128_f_inputY = vdivq_f32(m128_f_yy, m128_f_zz);
1593 float32x4_t inv_zz_128 = vrecpeq_f32(m128_f_zz);
1594 inv_zz_128 = vmulq_f32(vrecpsq_f32(m128_f_zz, inv_zz_128), inv_zz_128);
1597 const float32x4_t m128_f_inputX = vmulq_f32(m128_f_xx, inv_zz_128);
1598 const float32x4_t m128_f_inputY = vmulq_f32(m128_f_yy, inv_zz_128);
1603 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));
1604 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));
1606 const uint32x4_t m128_u_validPixel = vandq_u32(m128_u_validPixelX, m128_u_validPixelY);
1609 const uint32x2_t m64_u_validPixel = vorr_u32(vget_low_u32(m128_u_validPixel), vget_high_u32(m128_u_validPixel));
1610 if ((vget_lane_u32(m64_u_validPixel, 0) | vget_lane_u32(m64_u_validPixel, 1)) == 0x00000000u)
1614 OCEAN_ALIGN_DATA(16)
unsigned int debugValidPixels[4];
1616 vst1q_u32(debugValidPixels, m128_u_validPixel);
1617 ocean_assert(!(debugValidPixels[0] || debugValidPixels[1] || debugValidPixels[2] || debugValidPixels[3]));
1620 outputPixelData[0] = bColor;
1621 outputPixelData[1] = bColor;
1622 outputPixelData[2] = bColor;
1623 outputPixelData[3] = bColor;
1625 outputPixelData += 4;
1631 vst1q_u32(validPixels, m128_u_validPixel);
1632 ocean_assert(validPixels[0] || validPixels[1] || validPixels[2] || validPixels[3]);
1634 const uint32x4_t m128_u_inputX = vcvtq_u32_f32(vaddq_f32(m128_f_inputX, m128_f_pointFive));
1635 const uint32x4_t m128_u_inputY = vcvtq_u32_f32(vaddq_f32(m128_f_inputY, m128_f_pointFive));
1636 const uint32x4_t m_128_u_nearestNeighbourElementOffsets = vmlaq_u32(vmulq_u32(m128_u_inputY, m128_u_inputStrideElements), m128_u_inputX, m128_u_channels);
1637 vst1q_u32(nearestNeighbourElementOffsets, m_128_u_nearestNeighbourElementOffsets);
1640 unsigned int debugInputX[4];
1641 unsigned int debugInputY[4];
1642 vst1q_u32(debugInputX, m128_u_inputX);
1643 vst1q_u32(debugInputY, m128_u_inputY);
1644 ocean_assert(!validPixels[0] || (debugInputX[0] < inputWidth && debugInputY[0] < inputHeight));
1645 ocean_assert(!validPixels[1] || (debugInputX[1] < inputWidth && debugInputY[1] < inputHeight));
1646 ocean_assert(!validPixels[2] || (debugInputX[2] < inputWidth && debugInputY[2] < inputHeight));
1647 ocean_assert(!validPixels[3] || (debugInputX[3] < inputWidth && debugInputY[3] < inputHeight));
1650 outputPixelData[0] = validPixels[0] ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[0]) : bColor;
1651 outputPixelData[1] = validPixels[1] ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[1]) : bColor;
1652 outputPixelData[2] = validPixels[2] ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[2]) : bColor;
1653 outputPixelData[3] = validPixels[3] ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[3]) : bColor;
1655 outputPixelData += 4;
1662 template <
unsigned int tChannels>
1663 void 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)
1665 static_assert(tChannels > 0u,
"Invalid channel number!");
1667 ocean_assert(input !=
nullptr && output !=
nullptr && outputMask !=
nullptr);
1668 ocean_assert(inputWidth > 0u && inputHeight > 0u);
1669 ocean_assert(outputWidth > 0u && outputHeight > 0u);
1670 ocean_assert(input_H_output !=
nullptr && !input_H_output->
isSingular());
1672 ocean_assert_and_suppress_unused(firstOutputRow + numberOutputRows <= outputHeight, outputHeight);
1674 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1675 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1676 const unsigned int outputMaskStrideElements = outputWidth + outputMaskPaddingElements;
1680 output += firstOutputRow * outputStrideElements;
1681 outputMask += firstOutputRow * outputMaskStrideElements;
1683 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
1685 PixelType* outputPixel = (PixelType*)(output);
1687 for (
unsigned int x = 0; x < outputWidth; ++x)
1690 const Vector2 inputPosition(*input_H_output * outputPosition);
1695 if (inputX < inputWidth && inputY < inputHeight)
1697 *outputPixel = *((PixelType*)(input + inputY * inputStrideElements + inputX * tChannels));
1698 *outputMask = maskValue;
1702 *outputMask = 0xFFu - maskValue;
1709 output += outputStrideElements;
1710 outputMask += outputMaskPaddingElements;
1714 template <
unsigned int tChannels>
1715 void 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)
1717 static_assert(tChannels > 0u,
"Invalid channel number!");
1719 ocean_assert(lookupTable !=
nullptr);
1720 ocean_assert(input !=
nullptr && output !=
nullptr);
1722 ocean_assert(inputWidth != 0u && inputHeight != 0u);
1723 ocean_assert(firstRow + numberRows <= lookupTable->sizeY());
1725 const unsigned int outputWidth = (
unsigned int)(lookupTable->
sizeX());
1727 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1728 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1732 const uint8_t zeroColor[tChannels] = {uint8_t(0)};
1733 const PixelType*
const bColor = borderColor ? (PixelType*)(borderColor) : (PixelType*)(zeroColor);
1737 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1739 PixelType* outputData = (PixelType*)(output + y * outputStrideElements);
1741 for (
unsigned int x = 0u; x < outputWidth; ++x)
1749 if (inputX < inputWidth && inputY < inputHeight)
1751 *outputData = *((
const PixelType*)(input + inputY * inputStrideElements) + inputX);
1755 *outputData = *bColor;
1764 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1766 PixelType* outputData = (PixelType*)(output + y * outputStrideElements);
1768 for (
unsigned int x = 0u; x < outputWidth; ++x)
1775 if (inputX < inputWidth && inputY < inputHeight)
1777 *outputData = *((
const PixelType*)(input + inputY * inputStrideElements) + inputX);
1781 *outputData = *bColor;
1790 template <
unsigned int tChannels>
1791 void 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)
1793 static_assert(tChannels > 0u,
"Invalid channel number!");
1795 ocean_assert(lookupTable !=
nullptr);
1796 ocean_assert(input !=
nullptr && output !=
nullptr);
1798 ocean_assert(inputWidth != 0u && inputHeight != 0u);
1799 ocean_assert(firstRow + numberRows <= lookupTable->sizeY());
1802 const unsigned int outputWidth = (
unsigned int)(lookupTable->
sizeX());
1804 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1805 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1806 const unsigned int outputMaskStrideElements = outputWidth + outputMaskPaddingElements;
1810 output += firstRow * outputStrideElements;
1811 outputMask += firstRow * outputMaskStrideElements;
1815 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1817 PixelType* outputPixel = (PixelType*)(output);
1819 for (
unsigned int x = 0u; x < lookupTable->
sizeX(); ++x)
1827 if (inputX < inputWidth && inputY < inputHeight)
1829 *outputPixel = *((PixelType*)(input + inputY * inputStrideElements + inputX * tChannels));
1830 *outputMask = maskValue;
1834 *outputMask = 0xFF - maskValue;
1841 output += outputStrideElements;
1842 outputMask += outputMaskPaddingElements;
1847 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1849 PixelType* outputPixel = (PixelType*)(output);
1851 for (
unsigned int x = 0u; x < lookupTable->
sizeX(); ++x)
1858 if (inputX < inputWidth && inputY < inputHeight)
1860 *outputPixel = *((PixelType*)(input + inputY * inputStrideElements + inputX * tChannels));
1861 *outputMask = maskValue;
1865 *outputMask = 0xFF - maskValue;
1872 output += outputStrideElements;
1873 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
LookupCorner2< Vector2 > LookupTable
Definition of a lookup table for 2D vectors.
Definition: FrameInterpolatorNearestPixel.h:39
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:877
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:925
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:1791
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:1663
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:1063
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:1231
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:1715
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:1481
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:65
T y() const
Returns the vertical coordinate position of this object.
Definition: PixelPosition.h:470
T x() const
Returns the horizontal coordinate position of this object.
Definition: PixelPosition.h:458
static Caller< void > createStatic(typename StaticFunctionPointerMaker< void, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass >::Type function)
Creates a new caller container for a static function with no function parameter.
Definition: Caller.h:2876
Template class allowing to define an array of data types.
Definition: DataType.h:27
This class implements Ocean's image class.
Definition: Frame.h:1792
void setRelativeTimestamp(const Timestamp &relative)
Sets the relative timestamp of this frame.
Definition: Frame.h:4153
void setTimestamp(const Timestamp ×tamp)
Sets the timestamp of this frame.
Definition: Frame.h:4148
const Timestamp & timestamp() const
Returns the timestamp of this frame.
Definition: Frame.h:4138
const Timestamp & relativeTimestamp() const
Returns the relative timestamp of this frame.
Definition: Frame.h:4143
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:2064
static constexpr bool isEqualEps(const T value)
Returns whether a value is smaller than or equal to a small epsilon.
Definition: Numeric.h:2087
bool isNull() const
Returns whether this matrix is a zero matrix.
Definition: SquareMatrix3.h:1333
const T * data() const
Returns a pointer to the internal values.
Definition: SquareMatrix3.h:1046
bool isSingular() const
Returns whether this matrix is singular (and thus cannot be inverted).
Definition: SquareMatrix3.h:1341
TypeMapperBySize< sizeof(T)>::Type Type
Definition of an invalid mapped data type.
Definition: DataType.h:501
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
bool isEqual(const VectorT2< T > &vector, const T eps) const
Returns whether two vectors are equal up to a specified epsilon.
Definition: Vector2.h:746
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.
PixelPositionT< int > PixelPositionI
Definition of a PixelPosition object with a data type allowing positive and negative coordinate value...
Definition: PixelPosition.h:41
SquareMatrixT3< Scalar > SquareMatrix3
Definition of the SquareMatrix3 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with ...
Definition: SquareMatrix3.h:35
float Scalar
Definition of a scalar type.
Definition: Math.h:128
VectorT3< Scalar > Vector3
Definition of a 3D vector.
Definition: Vector3.h:22
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition: Vector2.h:21
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15
Default definition of a type with tBytes bytes.
Definition: DataType.h:32