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) {
865 *outputData = *(PixelType*)(input + inputY * (inputWidth * tChannels + inputPaddingElements) + inputX * tChannels);
867 *outputData = *bColor;
873 outputData = (PixelType*)((uint8_t*)outputData + outputPaddingElements);
877template <
typename T,
unsigned int tChannels>
878void 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)
880 static_assert(tChannels > 0u,
"Invalid channel number!");
882 ocean_assert(input !=
nullptr && output !=
nullptr);
883 ocean_assert(inputWidth > 0u && inputHeight > 0u);
884 ocean_assert(outputWidth > 0u && outputHeight > 0u);
885 ocean_assert(input_H_output !=
nullptr && !input_H_output->
isSingular());
887 ocean_assert_and_suppress_unused(firstOutputRow + numberOutputRows <= outputHeight, outputHeight);
889 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
890 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
894 const T zeroColor[tChannels] = {T(0)};
895 const PixelType bColor = borderColor ? *(
const PixelType*)(borderColor) : *(
const PixelType*)(zeroColor);
897 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
899 PixelType* outputData = (PixelType*)(output + y * outputStrideElements);
901 for (
unsigned int x = 0u; x < outputWidth; ++x)
904 const Vector2 inputPosition(*input_H_output * outputPosition);
909 if (inputX < inputWidth && inputY < inputHeight)
911 *outputData = *((
const PixelType*)(input + inputY * inputStrideElements) + inputX);
915 *outputData = bColor;
923#if defined(OCEAN_HARDWARE_SSE_VERSION) && OCEAN_HARDWARE_SSE_VERSION >= 41
925template <
unsigned int tChannels>
926inline 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)
928 static_assert(tChannels >= 1u,
"Invalid channel number!");
930 ocean_assert(input && output);
931 ocean_assert(inputWidth > 0u && inputHeight > 0u);
932 ocean_assert(outputWidth >= 4u && outputHeight > 0u);
933 ocean_assert(affineTransform);
936 ocean_assert_and_suppress_unused(firstOutputRow + numberOutputRows <= outputHeight, outputHeight);
940 const uint8_t zeroColor[tChannels] = {uint8_t(0)};
941 const PixelType*
const bColor = borderColor ? (PixelType*)borderColor : (PixelType*)zeroColor;
943 PixelType* outputPixelData = (PixelType*)(output + firstOutputRow * (outputWidth * tChannels + outputPaddingElements));
946 unsigned int nearestNeighbours[4];
949 const __m128 m128_f_X0 = _mm_set_ps1(
float((*affineTransform)(0, 0)));
950 const __m128 m128_f_X1 = _mm_set_ps1(
float((*affineTransform)(1, 0)));
953 const __m128i m128_i_inputStrideElements = _mm_set1_epi32(inputWidth * tChannels + inputPaddingElements);
956 const __m128i m128_i_channels = _mm_set1_epi32(tChannels);
959 const __m128i m128_i_inputWidth_1 = _mm_set1_epi32(inputWidth - 1u);
962 const __m128i m128_i_inputHeight_1 = _mm_set1_epi32(inputHeight - 1u);
965 const __m128i m128_i_zero = _mm_setzero_si128();
968 const unsigned int inputElementsEnd = inputHeight * inputWidth * tChannels + (inputHeight - 1u) * inputPaddingElements;
970 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
992 const __m128 m128_f_C0 = _mm_set_ps1(
float((*affineTransform)(0, 1) *
Scalar(y) + (*affineTransform)(0, 2)));
993 const __m128 m128_f_C1 = _mm_set_ps1(
float((*affineTransform)(1, 1) *
Scalar(y) + (*affineTransform)(1, 2)));
995 for (
unsigned int x = 0u; x < outputWidth; x += 4u)
997 if (x + 4u > outputWidth)
1002 ocean_assert(x >= 4u && outputWidth > 4u);
1003 const unsigned int newX = outputWidth - 4u;
1005 ocean_assert(x > newX);
1006 outputPixelData -= x - newX;
1011 ocean_assert(!(x + 4u < outputWidth));
1016 const __m128 m128_f_x_0123 = _mm_set_ps(
float(x + 3u),
float(x + 2u),
float(x + 1u),
float(x + 0u));
1019 const __m128 m128_f_inputX = _mm_add_ps(_mm_mul_ps(m128_f_X0, m128_f_x_0123), m128_f_C0);
1020 const __m128 m128_f_inputY = _mm_add_ps(_mm_mul_ps(m128_f_X1, m128_f_x_0123), m128_f_C1);
1023 const __m128i m128_i_inputX = _mm_cvtps_epi32(_mm_round_ps(m128_f_inputX, _MM_FROUND_TO_NEAREST_INT));
1024 const __m128i m128_i_inputY = _mm_cvtps_epi32(_mm_round_ps(m128_f_inputY, _MM_FROUND_TO_NEAREST_INT));
1041 const __m128i m128_i_isOutsideImage = _mm_or_si128(
1042 _mm_or_si128(_mm_cmplt_epi32(m128_i_inputX, m128_i_zero), _mm_cmplt_epi32(m128_i_inputY, m128_i_zero)),
1043 _mm_or_si128(_mm_cmpgt_epi32(m128_i_inputX, m128_i_inputWidth_1), _mm_cmpgt_epi32(m128_i_inputY, m128_i_inputHeight_1)));
1047 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)));
1048 _mm_store_si128((__m128i*)nearestNeighbours, m_128_i_nearestNeighborElements);
1051 outputPixelData[0] = nearestNeighbours[0] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighbours[0]) : *bColor;
1052 outputPixelData[1] = nearestNeighbours[1] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighbours[1]) : *bColor;
1053 outputPixelData[2] = nearestNeighbours[2] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighbours[2]) : *bColor;
1054 outputPixelData[3] = nearestNeighbours[3] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighbours[3]) : *bColor;
1056 outputPixelData += 4u;
1059 outputPixelData = (PixelType*)((uint8_t*)outputPixelData + outputPaddingElements);
1063template <
typename T,
unsigned int tChannels>
1064void 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)
1066 static_assert(tChannels > 0u,
"Invalid channel number!");
1068 ocean_assert(input !=
nullptr && output !=
nullptr);
1069 ocean_assert(inputWidth > 0u && inputHeight > 0u);
1070 ocean_assert(outputWidth >= 4u && outputHeight > 0u);
1071 ocean_assert(input_H_output !=
nullptr && !input_H_output->
isSingular());
1073 ocean_assert_and_suppress_unused(firstOutputRow + numberOutputRows <= outputHeight, outputHeight);
1075 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1076 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1080 const T zeroColor[tChannels] = {T(0)};
1081 const PixelType bColor = borderColor ? *(
const PixelType*)(borderColor) : *(
const PixelType*)(zeroColor);
1083 OCEAN_ALIGN_DATA(16)
unsigned int nearestNeighbourElementOffsets[4];
1111 const __m128 m128_f_X0 = _mm_set_ps1((
float)(*input_H_output)(0, 0));
1112 const __m128 m128_f_X1 = _mm_set_ps1((
float)(*input_H_output)(1, 0));
1113 const __m128 m128_f_X2 = _mm_set_ps1((
float)(*input_H_output)(2, 0));
1116 const __m128i m128_i_inputStrideElements = _mm_set1_epi32(inputStrideElements);
1118 const unsigned int inputPixelElementIndexEnd = inputHeight * inputStrideElements;
1121 const __m128i m128_i_inputWidth_1 = _mm_set1_epi32(inputWidth - 1u);
1124 const __m128i m128_i_inputHeight_1 = _mm_set1_epi32(inputHeight - 1u);
1127 const __m128i m128_i_channels = _mm_set1_epi32(tChannels);
1130 const __m128i m128_i_zero = _mm_setzero_si128();
1132 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
1134 PixelType* outputPixelData = (PixelType*)(output + y * outputStrideElements);
1137 const __m128 m128_f_C0 = _mm_set_ps1((
float)((*input_H_output)(0, 1) *
Scalar(y) + ((*input_H_output)(0, 2))));
1138 const __m128 m128_f_C1 = _mm_set_ps1((
float)((*input_H_output)(1, 1) *
Scalar(y) + ((*input_H_output)(1, 2))));
1139 const __m128 m128_f_C2 = _mm_set_ps1((
float)((*input_H_output)(2, 1) *
Scalar(y) + ((*input_H_output)(2, 2))));
1141 for (
unsigned int x = 0u; x < outputWidth; x += 4u)
1143 if (x + 4u > outputWidth)
1148 ocean_assert(x >= 4u && outputWidth > 4u);
1149 const unsigned int newX = outputWidth - 4u;
1151 ocean_assert(x > newX);
1152 outputPixelData -= x - newX;
1157 ocean_assert(!(x + 4u < outputWidth));
1162 const __m128 m128_f_x_0123 = _mm_set_ps(
float(x + 3u),
float(x + 2u),
float(x + 1u),
float(x + 0u));
1165 const __m128 m128_f_xx = _mm_add_ps(_mm_mul_ps(m128_f_X0, m128_f_x_0123), m128_f_C0);
1166 const __m128 m128_f_yy = _mm_add_ps(_mm_mul_ps(m128_f_X1, m128_f_x_0123), m128_f_C1);
1167 const __m128 m128_f_zz = _mm_add_ps(_mm_mul_ps(m128_f_X2, m128_f_x_0123), m128_f_C2);
1169#ifdef USE_APPROXIMATED_INVERSE_OF_ZZ
1174 const __m128 inv_zz_128 = _mm_rcp_ps(m128_f_zz);
1177 const __m128 m128_f_inputX = _mm_mul_ps(m128_f_xx, inv_zz_128);
1178 const __m128 m128_f_inputY = _mm_mul_ps(m128_f_yy, inv_zz_128);
1183 const __m128 m128_f_inputX = _mm_div_ps(m128_f_xx, m128_f_zz);
1184 const __m128 m128_f_inputY = _mm_div_ps(m128_f_yy, m128_f_zz);
1189 const __m128i m128_i_inputX = _mm_cvtps_epi32(_mm_round_ps(m128_f_inputX, _MM_FROUND_TO_NEAREST_INT));
1190 const __m128i m128_i_inputY = _mm_cvtps_epi32(_mm_round_ps(m128_f_inputY, _MM_FROUND_TO_NEAREST_INT));
1207 const __m128i m128_i_isOutsideImage = _mm_or_si128(
1208 _mm_or_si128(_mm_cmplt_epi32(m128_i_inputX, m128_i_zero), _mm_cmplt_epi32(m128_i_inputY, m128_i_zero)),
1209 _mm_or_si128(_mm_cmpgt_epi32(m128_i_inputX, m128_i_inputWidth_1), _mm_cmpgt_epi32(m128_i_inputY, m128_i_inputHeight_1)));
1213 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)));
1214 _mm_store_si128((__m128i*)nearestNeighbourElementOffsets, m_128_i_nearestNeighbors);
1217 outputPixelData[0] = nearestNeighbourElementOffsets[0] < inputPixelElementIndexEnd ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[0]) : bColor;
1218 outputPixelData[1] = nearestNeighbourElementOffsets[1] < inputPixelElementIndexEnd ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[1]) : bColor;
1219 outputPixelData[2] = nearestNeighbourElementOffsets[2] < inputPixelElementIndexEnd ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[2]) : bColor;
1220 outputPixelData[3] = nearestNeighbourElementOffsets[3] < inputPixelElementIndexEnd ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[3]) : bColor;
1222 outputPixelData += 4u;
1229#if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
1231template <
unsigned int tChannels>
1232void 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)
1284 static_assert(tChannels >= 1u,
"Invalid channel number!");
1286 constexpr unsigned int fractionalBits = 15u;
1287 constexpr unsigned int totalBits = (
unsigned int)(CHAR_BIT *
sizeof(
int));
1289 static_assert((fractionalBits + 1u ) < totalBits,
"Number of fractional bits exceeds number of total bits");
1291 constexpr unsigned int maxImageEdgeLength = 1u << (totalBits - fractionalBits - 1u );
1294 constexpr Scalar fixedPointScale =
Scalar(1u << fractionalBits);
1297 constexpr unsigned int pixelsPerIteration = 4u;
1299 ocean_assert(input && output);
1300 ocean_assert_and_suppress_unused(inputWidth > 0u && inputHeight > 0u && inputWidth <= maxImageEdgeLength && inputHeight <= maxImageEdgeLength, maxImageEdgeLength);
1301 ocean_assert_and_suppress_unused(outputWidth >= pixelsPerIteration && outputHeight > 0u && outputWidth <= maxImageEdgeLength && outputHeight <= maxImageEdgeLength, maxImageEdgeLength);
1302 ocean_assert(affineTransform);
1305 ocean_assert(firstOutputRow + numberOutputRows <= outputHeight);
1309 const uint8_t zeroColor[tChannels] = {uint8_t(0)};
1310 const PixelType*
const bColor = borderColor ? (PixelType*)borderColor : (PixelType*)zeroColor;
1312 PixelType* outputPixelData = (PixelType*)(output + firstOutputRow * (outputWidth * tChannels + outputPaddingElements));
1314 const unsigned int outputRowEnd = firstOutputRow + numberOutputRows;
1317 unsigned int nearestNeighboursElements[4];
1320 const unsigned int inputElementsEnd = inputHeight * inputWidth * tChannels + (inputHeight - 1u) * inputPaddingElements;
1323 const uint32x4_t m128_u_inputWidth = vdupq_n_u32(inputWidth);
1324 const uint32x4_t m128_u_inputHeight = vdupq_n_u32(inputHeight);
1327 const uint32x4_t m128_u_inputStrideElements = vdupq_n_u32(inputWidth * tChannels + inputPaddingElements);
1330 const uint32x4_t m128_u_channels = vdupq_n_u32(tChannels);
1333 const int offsets_0123[4] = { 0, 1, 2, 3 };
1334 const int32x4_t m128_s_offsets_0123 = vld1q_s32(offsets_0123);
1337 const float32x4_t m128_f_pixelsPerIteration = vdupq_n_f32((
float)pixelsPerIteration);
1343 const float32x4_t m128_f_X0 = vdupq_n_f32(
float(fixedPointScale * (*affineTransform)(0, 0)));
1344 const float32x4_t m128_f_X1 = vdupq_n_f32(
float(fixedPointScale * (*affineTransform)(1, 0)));
1348 const int32x4_t m128_s_q_X0x_increment = vcvtq_s32_f32(vmulq_f32(m128_f_X0, m128_f_pixelsPerIteration));
1349 const int32x4_t m128_s_q_X1x_increment = vcvtq_s32_f32(vmulq_f32(m128_f_X1, m128_f_pixelsPerIteration));
1352 constexpr unsigned int blockSize = 64u;
1353 constexpr unsigned int blockElements = blockSize * blockSize;
1354 const unsigned int blockWidth = std::min(blockElements / std::min(numberOutputRows, blockSize), outputWidth);
1355 const unsigned int blockHeight = std::min(blockElements / blockWidth, numberOutputRows);
1356 ocean_assert(blockWidth > 0u && blockWidth <= outputWidth);
1357 ocean_assert(blockHeight > 0u && blockHeight <= numberOutputRows);
1363 const unsigned int lastMultipleNeonPixelBlockStart = outputWidth - pixelsPerIteration;
1366 const float32x4_t m128_f_lastMultipleNeonPixelBlockStart = vcvtq_f32_s32(vaddq_s32(vdupq_n_s32((
int)lastMultipleNeonPixelBlockStart), m128_s_offsets_0123));
1369 const int32x4_t m128_s_q_X0x_lastMultipleNeonPixelBlockStart = vcvtq_s32_f32(vmulq_f32(m128_f_X0, m128_f_lastMultipleNeonPixelBlockStart));
1370 const int32x4_t m128_s_q_X1x_lastMultipleNeonPixelBlockStart = vcvtq_s32_f32(vmulq_f32(m128_f_X1, m128_f_lastMultipleNeonPixelBlockStart));
1372 for (
unsigned int blockYStart = firstOutputRow; blockYStart < outputRowEnd; blockYStart += blockHeight)
1374 const unsigned int blockYEnd = std::min(blockYStart + blockHeight, outputRowEnd);
1376 for (
unsigned int blockXStart = 0u; blockXStart < outputWidth; blockXStart += blockWidth)
1378 const unsigned int blockXEnd = std::min(blockXStart + blockWidth, outputWidth);
1380 for (
unsigned int y = blockYStart; y < blockYEnd; ++y)
1382 outputPixelData = (PixelType*)(output + y * (outputWidth * tChannels + outputPaddingElements) + blockXStart * tChannels);
1386 const int32x4_t m128_s_q_C0 = vdupq_n_s32(
Numeric::round32(fixedPointScale * ((*affineTransform)(0, 1) *
Scalar(y) + (*affineTransform)(0, 2))));
1387 const int32x4_t m128_s_q_C1 = vdupq_n_s32(
Numeric::round32(fixedPointScale * ((*affineTransform)(1, 1) *
Scalar(y) + (*affineTransform)(1, 2))));
1394 const int32x4_t m128_s_x_0123 = vaddq_s32(vdupq_n_s32(
int(blockXStart)), m128_s_offsets_0123);
1397 const float32x4_t m128_f_x_0123 = vcvtq_f32_s32(m128_s_x_0123);
1400 int32x4_t m128_s_q_X0x = vcvtq_s32_f32(vmulq_f32(m128_f_X0, m128_f_x_0123));
1401 int32x4_t m128_s_q_X1x = vcvtq_s32_f32(vmulq_f32(m128_f_X1, m128_f_x_0123));
1403 for (
unsigned int x = blockXStart; x < blockXEnd; x += pixelsPerIteration)
1405 if (x + pixelsPerIteration > outputWidth)
1407 ocean_assert(x + pixelsPerIteration > outputWidth);
1408 ocean_assert(x >= pixelsPerIteration && outputWidth > pixelsPerIteration);
1409 ocean_assert(lastMultipleNeonPixelBlockStart == (outputWidth - pixelsPerIteration));
1411 outputPixelData -= (x - lastMultipleNeonPixelBlockStart);
1413 x = lastMultipleNeonPixelBlockStart;
1415 m128_s_q_X0x = m128_s_q_X0x_lastMultipleNeonPixelBlockStart;
1416 m128_s_q_X1x = m128_s_q_X1x_lastMultipleNeonPixelBlockStart;
1419 ocean_assert(!(x + pixelsPerIteration < outputWidth));
1425 const int32x4_t m128_s_q_inputX = vaddq_s32(m128_s_q_C0, m128_s_q_X0x);
1426 const int32x4_t m128_s_q_inputY = vaddq_s32(m128_s_q_C1, m128_s_q_X1x);
1433 const uint32x4_t m128_u_inputX = vreinterpretq_u32_s32(vrshrq_n_s32(m128_s_q_inputX, fractionalBits));
1434 const uint32x4_t m128_u_inputY = vreinterpretq_u32_s32(vrshrq_n_s32(m128_s_q_inputY, fractionalBits));
1453 const uint32x4_t m128_u_isOutsideImage = vorrq_u32(vcgeq_u32(m128_u_inputX, m128_u_inputWidth), vcgeq_u32(m128_u_inputY, m128_u_inputHeight));
1460 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)));
1461 vst1q_u32(nearestNeighboursElements, m_128_u_nearestNeighborsElements);
1463 outputPixelData[0] = nearestNeighboursElements[0] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighboursElements[0]) : *bColor;
1464 outputPixelData[1] = nearestNeighboursElements[1] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighboursElements[1]) : *bColor;
1465 outputPixelData[2] = nearestNeighboursElements[2] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighboursElements[2]) : *bColor;
1466 outputPixelData[3] = nearestNeighboursElements[3] < inputElementsEnd ? *(
const PixelType*)(input + nearestNeighboursElements[3]) : *bColor;
1468 outputPixelData += pixelsPerIteration;
1471 m128_s_q_X0x = vaddq_s32(m128_s_q_X0x, m128_s_q_X0x_increment);
1472 m128_s_q_X1x = vaddq_s32(m128_s_q_X1x, m128_s_q_X1x_increment);
1477 outputPixelData = (PixelType*)((uint8_t*)outputPixelData + outputPaddingElements);
1481template <
typename T,
unsigned int tChannels>
1482void 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)
1484 static_assert(tChannels >= 1u,
"Invalid channel number!");
1486 ocean_assert(input !=
nullptr && output !=
nullptr);
1487 ocean_assert(inputWidth > 0u && inputHeight > 0u);
1488 ocean_assert(outputWidth >= 4u && outputHeight > 0u);
1489 ocean_assert(input_H_output !=
nullptr && !input_H_output->
isSingular());
1491 ocean_assert(firstOutputRow + numberOutputRows <= outputHeight);
1493 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1494 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1498 const T zeroColor[tChannels] = {T(0)};
1499 const PixelType bColor = borderColor ? *(
const PixelType*)(borderColor) : *(
const PixelType*)(zeroColor);
1501 unsigned int validPixels[4];
1502 unsigned int nearestNeighbourElementOffsets[4];
1530 const float32x4_t m128_f_X0 = vdupq_n_f32(
float((*input_H_output)(0, 0)));
1531 const float32x4_t m128_f_X1 = vdupq_n_f32(
float((*input_H_output)(1, 0)));
1532 const float32x4_t m128_f_X2 = vdupq_n_f32(
float((*input_H_output)(2, 0)));
1535 const float32x4_t m128_f_pointFive = vdupq_n_f32(0.5f);
1536 const float32x4_t m128_f_negPointFive = vdupq_n_f32(-0.5f);
1539 const uint32x4_t m128_u_inputStrideElements = vdupq_n_u32(inputStrideElements);
1541 const uint32x4_t m128_u_channels = vdupq_n_u32(tChannels);
1544 const float32x4_t m128_f_inputWidth_pointFive = vdupq_n_f32(
float(inputWidth) - 0.5f);
1545 const float32x4_t m128_f_inputHeight_pointFive = vdupq_n_f32(
float(inputHeight) - 0.5f);
1547 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
1549 PixelType* outputPixelData = (PixelType*)(output + y * outputStrideElements);
1552 const float32x4_t m128_f_C0 = vdupq_n_f32(
float((*input_H_output)(0, 1) *
Scalar(y) + (*input_H_output)(0, 2)));
1553 const float32x4_t m128_f_C1 = vdupq_n_f32(
float((*input_H_output)(1, 1) *
Scalar(y) + (*input_H_output)(1, 2)));
1554 const float32x4_t m128_f_C2 = vdupq_n_f32(
float((*input_H_output)(2, 1) *
Scalar(y) + (*input_H_output)(2, 2)));
1556 for (
unsigned int x = 0u; x < outputWidth; x += 4u)
1558 if (x + 4u > outputWidth)
1562 ocean_assert(x >= 4u && outputWidth > 4u);
1563 const unsigned int newX = outputWidth - 4u;
1565 ocean_assert(x > newX);
1566 outputPixelData -= x - newX;
1571 ocean_assert(!(x + 4u < outputWidth));
1576 float x_0123[4] = { float(x + 0u), float(x + 1u), float(x + 2u), float(x + 3u) };
1577 const float32x4_t m128_f_x_0123 = vld1q_f32(x_0123);
1580 const float32x4_t m128_f_xx = vmlaq_f32(m128_f_C0, m128_f_X0, m128_f_x_0123);
1581 const float32x4_t m128_f_yy = vmlaq_f32(m128_f_C1, m128_f_X1, m128_f_x_0123);
1582 const float32x4_t m128_f_zz = vmlaq_f32(m128_f_C2, m128_f_X2, m128_f_x_0123);
1584#ifdef USE_DIVISION_ARM64_ARCHITECTURE
1587 const float32x4_t m128_f_inputX = vdivq_f32(m128_f_xx, m128_f_zz);
1588 const float32x4_t m128_f_inputY = vdivq_f32(m128_f_yy, m128_f_zz);
1594 float32x4_t inv_zz_128 = vrecpeq_f32(m128_f_zz);
1595 inv_zz_128 = vmulq_f32(vrecpsq_f32(m128_f_zz, inv_zz_128), inv_zz_128);
1598 const float32x4_t m128_f_inputX = vmulq_f32(m128_f_xx, inv_zz_128);
1599 const float32x4_t m128_f_inputY = vmulq_f32(m128_f_yy, inv_zz_128);
1604 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));
1605 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));
1607 const uint32x4_t m128_u_validPixel = vandq_u32(m128_u_validPixelX, m128_u_validPixelY);
1610 const uint32x2_t m64_u_validPixel = vorr_u32(vget_low_u32(m128_u_validPixel), vget_high_u32(m128_u_validPixel));
1611 if ((vget_lane_u32(m64_u_validPixel, 0) | vget_lane_u32(m64_u_validPixel, 1)) == 0x00000000u)
1615 OCEAN_ALIGN_DATA(16)
unsigned int debugValidPixels[4];
1617 vst1q_u32(debugValidPixels, m128_u_validPixel);
1618 ocean_assert(!(debugValidPixels[0] || debugValidPixels[1] || debugValidPixels[2] || debugValidPixels[3]));
1621 outputPixelData[0] = bColor;
1622 outputPixelData[1] = bColor;
1623 outputPixelData[2] = bColor;
1624 outputPixelData[3] = bColor;
1626 outputPixelData += 4;
1632 vst1q_u32(validPixels, m128_u_validPixel);
1633 ocean_assert(validPixels[0] || validPixels[1] || validPixels[2] || validPixels[3]);
1635 const uint32x4_t m128_u_inputX = vcvtq_u32_f32(vaddq_f32(m128_f_inputX, m128_f_pointFive));
1636 const uint32x4_t m128_u_inputY = vcvtq_u32_f32(vaddq_f32(m128_f_inputY, m128_f_pointFive));
1637 const uint32x4_t m_128_u_nearestNeighbourElementOffsets = vmlaq_u32(vmulq_u32(m128_u_inputY, m128_u_inputStrideElements), m128_u_inputX, m128_u_channels);
1638 vst1q_u32(nearestNeighbourElementOffsets, m_128_u_nearestNeighbourElementOffsets);
1641 unsigned int debugInputX[4];
1642 unsigned int debugInputY[4];
1643 vst1q_u32(debugInputX, m128_u_inputX);
1644 vst1q_u32(debugInputY, m128_u_inputY);
1645 ocean_assert(!validPixels[0] || (debugInputX[0] < inputWidth && debugInputY[0] < inputHeight));
1646 ocean_assert(!validPixels[1] || (debugInputX[1] < inputWidth && debugInputY[1] < inputHeight));
1647 ocean_assert(!validPixels[2] || (debugInputX[2] < inputWidth && debugInputY[2] < inputHeight));
1648 ocean_assert(!validPixels[3] || (debugInputX[3] < inputWidth && debugInputY[3] < inputHeight));
1651 outputPixelData[0] = validPixels[0] ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[0]) : bColor;
1652 outputPixelData[1] = validPixels[1] ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[1]) : bColor;
1653 outputPixelData[2] = validPixels[2] ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[2]) : bColor;
1654 outputPixelData[3] = validPixels[3] ? *(
const PixelType*)(input + nearestNeighbourElementOffsets[3]) : bColor;
1656 outputPixelData += 4;
1663template <
unsigned int tChannels>
1664void 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)
1666 static_assert(tChannels > 0u,
"Invalid channel number!");
1668 ocean_assert(input !=
nullptr && output !=
nullptr && outputMask !=
nullptr);
1669 ocean_assert(inputWidth > 0u && inputHeight > 0u);
1670 ocean_assert(outputWidth > 0u && outputHeight > 0u);
1671 ocean_assert(input_H_output !=
nullptr && !input_H_output->
isSingular());
1673 ocean_assert_and_suppress_unused(firstOutputRow + numberOutputRows <= outputHeight, outputHeight);
1675 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1676 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1677 const unsigned int outputMaskStrideElements = outputWidth + outputMaskPaddingElements;
1681 output += firstOutputRow * outputStrideElements;
1682 outputMask += firstOutputRow * outputMaskStrideElements;
1684 for (
unsigned int y = firstOutputRow; y < firstOutputRow + numberOutputRows; ++y)
1686 PixelType* outputPixel = (PixelType*)(output);
1688 for (
unsigned int x = 0; x < outputWidth; ++x)
1691 const Vector2 inputPosition(*input_H_output * outputPosition);
1696 if (inputX < inputWidth && inputY < inputHeight)
1698 *outputPixel = *((PixelType*)(input + inputY * inputStrideElements + inputX * tChannels));
1699 *outputMask = maskValue;
1703 *outputMask = 0xFFu - maskValue;
1710 output += outputStrideElements;
1711 outputMask += outputMaskPaddingElements;
1715template <
unsigned int tChannels>
1716void 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)
1718 static_assert(tChannels > 0u,
"Invalid channel number!");
1720 ocean_assert(lookupTable !=
nullptr);
1721 ocean_assert(input !=
nullptr && output !=
nullptr);
1723 ocean_assert(inputWidth != 0u && inputHeight != 0u);
1724 ocean_assert(firstRow + numberRows <= lookupTable->sizeY());
1726 const unsigned int outputWidth = (
unsigned int)(lookupTable->
sizeX());
1728 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1729 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1733 const uint8_t zeroColor[tChannels] = {uint8_t(0)};
1734 const PixelType*
const bColor = borderColor ? (PixelType*)(borderColor) : (PixelType*)(zeroColor);
1738 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1740 PixelType* outputData = (PixelType*)(output + y * outputStrideElements);
1742 for (
unsigned int x = 0u; x < outputWidth; ++x)
1750 if (inputX < inputWidth && inputY < inputHeight)
1752 *outputData = *((
const PixelType*)(input + inputY * inputStrideElements) + inputX);
1756 *outputData = *bColor;
1765 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1767 PixelType* outputData = (PixelType*)(output + y * outputStrideElements);
1769 for (
unsigned int x = 0u; x < outputWidth; ++x)
1776 if (inputX < inputWidth && inputY < inputHeight)
1778 *outputData = *((
const PixelType*)(input + inputY * inputStrideElements) + inputX);
1782 *outputData = *bColor;
1791template <
unsigned int tChannels>
1792void 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)
1794 static_assert(tChannels > 0u,
"Invalid channel number!");
1796 ocean_assert(lookupTable !=
nullptr);
1797 ocean_assert(input !=
nullptr && output !=
nullptr);
1799 ocean_assert(inputWidth != 0u && inputHeight != 0u);
1800 ocean_assert(firstRow + numberRows <= lookupTable->sizeY());
1803 const unsigned int outputWidth = (
unsigned int)(lookupTable->
sizeX());
1805 const unsigned int inputStrideElements = inputWidth * tChannels + inputPaddingElements;
1806 const unsigned int outputStrideElements = outputWidth * tChannels + outputPaddingElements;
1807 const unsigned int outputMaskStrideElements = outputWidth + outputMaskPaddingElements;
1811 output += firstRow * outputStrideElements;
1812 outputMask += firstRow * outputMaskStrideElements;
1816 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1818 PixelType* outputPixel = (PixelType*)(output);
1820 for (
unsigned int x = 0u; x < lookupTable->
sizeX(); ++x)
1828 if (inputX < inputWidth && inputY < inputHeight)
1830 *outputPixel = *((PixelType*)(input + inputY * inputStrideElements + inputX * tChannels));
1831 *outputMask = maskValue;
1835 *outputMask = 0xFF - maskValue;
1842 output += outputStrideElements;
1843 outputMask += outputMaskPaddingElements;
1848 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1850 PixelType* outputPixel = (PixelType*)(output);
1852 for (
unsigned int x = 0u; x < lookupTable->
sizeX(); ++x)
1859 if (inputX < inputWidth && inputY < inputHeight)
1861 *outputPixel = *((PixelType*)(input + inputY * inputStrideElements + inputX * tChannels));
1862 *outputMask = maskValue;
1866 *outputMask = 0xFF - maskValue;
1873 output += outputStrideElements;
1874 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:878
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:926
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:1792
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:1664
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:1064
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:1232
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:1716
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:1482
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:1808
void setRelativeTimestamp(const Timestamp &relative)
Sets the relative timestamp of this frame.
Definition Frame.h:4236
void setTimestamp(const Timestamp ×tamp)
Sets the timestamp of this frame.
Definition Frame.h:4231
const Timestamp & timestamp() const
Returns the timestamp of this frame.
Definition Frame.h:4221
const Timestamp & relativeTimestamp() const
Returns the relative timestamp of this frame.
Definition Frame.h:4226
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:2067
static constexpr bool isEqualEps(const T value)
Returns whether a value is smaller than or equal to a small epsilon.
Definition Numeric.h:2090
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: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.
SquareMatrixT3< Scalar > SquareMatrix3
Definition of the SquareMatrix3 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with ...
Definition SquareMatrix3.h:42
float Scalar
Definition of a scalar type.
Definition Math.h:129
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