1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

Merge pull request #27519 from ekharkov:dev/reamp

Move IPP Remap to HAL
This commit is contained in:
Alexander Smorkalov
2025-07-14 09:20:16 +03:00
committed by GitHub
4 changed files with 143 additions and 156 deletions
+9
View File
@@ -24,4 +24,13 @@ int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step
#define cv_hal_warpPerspective ipp_hal_warpPerspective
#endif
int ipp_hal_remap32f(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height,
uchar *dst_data, size_t dst_step, int dst_width, int dst_height,
float* mapx, size_t mapx_step, float* mapy, size_t mapy_step,
int interpolation, int border_type, const double border_value[4]);
#undef cv_hal_remap32f
#define cv_hal_remap32f ipp_hal_remap32f
#endif //__IPP_HAL_IMGPROC_HPP__
+12
View File
@@ -11,6 +11,18 @@
#include "iw++/iw.hpp"
#endif
static inline IppiSize ippiSize(size_t width, size_t height)
{
IppiSize size = { (int)width, (int)height };
return size;
}
static inline IppiSize ippiSize(const cv::Size & _size)
{
IppiSize size = { _size.width, _size.height };
return size;
}
static inline IppDataType ippiGetDataType(int depth)
{
depth = CV_MAT_DEPTH(depth);
+122 -5
View File
@@ -133,21 +133,22 @@ int ipp_hal_warpAffine(int src_type, const uchar *src_data, size_t src_step, int
return CV_HAL_ERROR_OK;
}
#endif
#endif
typedef IppStatus (CV_STDCALL* ippiSetFunc)(const void*, void *, int, IppiSize);
template <int channels, typename Type>
bool IPPSetSimple(cv::Scalar value, void *dataPointer, int step, IppiSize &size, ippiSetFunc func)
bool IPPSetSimple(const double value[4], void *dataPointer, int step, IppiSize &size, ippiSetFunc func)
{
//CV_INSTRUMENT_REGION_IPP();
Type values[channels];
for( int i = 0; i < channels; i++ )
values[i] = cv::saturate_cast<Type>(value[i]);
return func(values, dataPointer, step, size) >= 0;
return CV_INSTRUMENT_FUN_IPP(func, values, dataPointer, step, size) >= 0;
}
static bool IPPSet(const cv::Scalar &value, void *dataPointer, int step, IppiSize &size, int channels, int depth)
static bool IPPSet(const double value[4], void *dataPointer, int step, IppiSize &size, int channels, int depth)
{
//CV_INSTRUMENT_REGION_IPP();
@@ -248,7 +249,7 @@ public:
{
IppiSize setSize = {dst.cols, range.end - range.start};
void *dataPointer = dst.ptr(range.start);
if( !IPPSet( cv::Scalar(borderValue[0], borderValue[1], borderValue[2], borderValue[3]), dataPointer, (int)dst.step[0], setSize, cnn, src.depth() ) )
if( !IPPSet( borderValue, dataPointer, (int)dst.step[0], setSize, cnn, src.depth() ) )
{
*ok = false;
ippsFree(pBuffer);
@@ -368,4 +369,120 @@ int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step
return CV_HAL_ERROR_OK;
}
#endif
#endif
typedef IppStatus(CV_STDCALL *ippiRemap)(const void *pSrc, IppiSize srcSize, int srcStep, IppiRect srcRoi,
const Ipp32f *pxMap, int xMapStep, const Ipp32f *pyMap, int yMapStep,
void *pDst, int dstStep, IppiSize dstRoiSize, int interpolation);
class IPPRemapInvoker : public cv::ParallelLoopBody
{
public:
IPPRemapInvoker(int _src_type, const uchar *_src_data, size_t _src_step, int _src_width, int _src_height,
uchar *_dst_data, size_t _dst_step, int _dst_width, float *_mapx, size_t _mapx_step, float *_mapy,
size_t _mapy_step, ippiRemap _ippFunc, int _ippInterpolation, int _borderType, const double _borderValue[4], bool *_ok) :
ParallelLoopBody(),
src_type(_src_type), src(_src_data), src_step(_src_step), src_width(_src_width), src_height(_src_height),
dst(_dst_data), dst_step(_dst_step), dst_width(_dst_width), mapx(_mapx), mapx_step(_mapx_step), mapy(_mapy),
mapy_step(_mapy_step), ippFunc(_ippFunc), ippInterpolation(_ippInterpolation), borderType(_borderType), ok(_ok)
{
memcpy(this->borderValue, _borderValue, sizeof(this->borderValue));
*ok = true;
}
virtual void operator()(const cv::Range &range) const
{
IppiRect srcRoiRect = {0, 0, src_width, src_height};
uchar *dst_roi_data = dst + range.start * dst_step;
IppiSize dstRoiSize = ippiSize(dst_width, range.size());
int depth = CV_MAT_DEPTH(src_type), cn = CV_MAT_CN(src_type);
if (borderType == cv::BORDER_CONSTANT &&
!IPPSet(borderValue, dst_roi_data, (int)dst_step, dstRoiSize, cn, depth))
{
*ok = false;
return;
}
if (CV_INSTRUMENT_FUN_IPP(ippFunc, src, {src_width, src_height}, (int)src_step, srcRoiRect,
mapx, (int)mapx_step, mapy, (int)mapy_step,
dst_roi_data, (int)dst_step, dstRoiSize, ippInterpolation) < 0)
*ok = false;
else
{
CV_IMPL_ADD(CV_IMPL_IPP | CV_IMPL_MT);
}
}
private:
int src_type;
const uchar *src;
size_t src_step;
int src_width, src_height;
uchar *dst;
size_t dst_step;
int dst_width;
float *mapx;
size_t mapx_step;
float *mapy;
size_t mapy_step;
ippiRemap ippFunc;
int ippInterpolation, borderType;
double borderValue[4];
bool *ok;
};
int ipp_hal_remap32f(int src_type, const uchar *src_data, size_t src_step, int src_width, int src_height,
uchar *dst_data, size_t dst_step, int dst_width, int dst_height,
float *mapx, size_t mapx_step, float *mapy, size_t mapy_step,
int interpolation, int border_type, const double border_value[4])
{
if ((interpolation == cv::INTER_LINEAR || interpolation == cv::INTER_CUBIC || interpolation == cv::INTER_NEAREST) &&
(border_type == cv::BORDER_CONSTANT || border_type == cv::BORDER_TRANSPARENT))
{
int ippInterpolation =
interpolation == cv::INTER_NEAREST ? IPPI_INTER_NN : interpolation == cv::INTER_LINEAR ? IPPI_INTER_LINEAR
: IPPI_INTER_CUBIC;
/* C1 C2 C3 C4 */
char impl[CV_DEPTH_MAX][4][3]={{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8U
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //8S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //16U
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //16S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32S
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, //32F
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}; //64F
if (impl[CV_TYPE(src_type)][CV_MAT_CN(src_type) - 1][interpolation] == 0)
{
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
ippiRemap ippFunc =
src_type == CV_8UC1 ? (ippiRemap)ippiRemap_8u_C1R : src_type == CV_8UC3 ? (ippiRemap)ippiRemap_8u_C3R
: src_type == CV_8UC4 ? (ippiRemap)ippiRemap_8u_C4R
: src_type == CV_16UC1 ? (ippiRemap)ippiRemap_16u_C1R
: src_type == CV_16UC3 ? (ippiRemap)ippiRemap_16u_C3R
: src_type == CV_16UC4 ? (ippiRemap)ippiRemap_16u_C4R
: src_type == CV_32FC1 ? (ippiRemap)ippiRemap_32f_C1R
: src_type == CV_32FC3 ? (ippiRemap)ippiRemap_32f_C3R
: src_type == CV_32FC4 ? (ippiRemap)ippiRemap_32f_C4R
: 0;
if (ippFunc)
{
bool ok;
IPPRemapInvoker invoker(src_type, src_data, src_step, src_width, src_height, dst_data, dst_step, dst_width,
mapx, mapx_step, mapy, mapy_step, ippFunc, ippInterpolation, border_type, border_value, &ok);
cv::Range range(0, dst_height);
cv::parallel_for_(range, invoker, dst_width * dst_height / (double)(1 << 16));
if (ok)
{
CV_IMPL_ADD(CV_IMPL_IPP | CV_IMPL_MT);
return CV_HAL_ERROR_OK;
}
}
}
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}