mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
Moved IPP remap to HAL
This commit is contained in:
@@ -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
|
#define cv_hal_warpPerspective ipp_hal_warpPerspective
|
||||||
#endif
|
#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__
|
#endif //__IPP_HAL_IMGPROC_HPP__
|
||||||
|
|||||||
@@ -11,6 +11,18 @@
|
|||||||
#include "iw++/iw.hpp"
|
#include "iw++/iw.hpp"
|
||||||
#endif
|
#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)
|
static inline IppDataType ippiGetDataType(int depth)
|
||||||
{
|
{
|
||||||
depth = CV_MAT_DEPTH(depth);
|
depth = CV_MAT_DEPTH(depth);
|
||||||
|
|||||||
+122
-5
@@ -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;
|
return CV_HAL_ERROR_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef IppStatus (CV_STDCALL* ippiSetFunc)(const void*, void *, int, IppiSize);
|
typedef IppStatus (CV_STDCALL* ippiSetFunc)(const void*, void *, int, IppiSize);
|
||||||
|
|
||||||
template <int channels, typename Type>
|
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();
|
//CV_INSTRUMENT_REGION_IPP();
|
||||||
|
|
||||||
Type values[channels];
|
Type values[channels];
|
||||||
for( int i = 0; i < channels; i++ )
|
for( int i = 0; i < channels; i++ )
|
||||||
values[i] = cv::saturate_cast<Type>(value[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();
|
//CV_INSTRUMENT_REGION_IPP();
|
||||||
|
|
||||||
@@ -248,7 +249,7 @@ public:
|
|||||||
{
|
{
|
||||||
IppiSize setSize = {dst.cols, range.end - range.start};
|
IppiSize setSize = {dst.cols, range.end - range.start};
|
||||||
void *dataPointer = dst.ptr(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;
|
*ok = false;
|
||||||
return;
|
return;
|
||||||
@@ -364,4 +365,120 @@ int ipp_hal_warpPerspective(int src_type, const uchar *src_data, size_t src_step
|
|||||||
return CV_HAL_ERROR_OK;
|
return CV_HAL_ERROR_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -60,66 +60,6 @@ using namespace cv;
|
|||||||
namespace cv
|
namespace cv
|
||||||
{
|
{
|
||||||
|
|
||||||
#if defined (HAVE_IPP) && (!IPP_DISABLE_REMAP)
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
CV_INSTRUMENT_REGION_IPP();
|
|
||||||
|
|
||||||
Type values[channels];
|
|
||||||
for( int i = 0; i < channels; i++ )
|
|
||||||
values[i] = saturate_cast<Type>(value[i]);
|
|
||||||
return func(values, dataPointer, step, size) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool IPPSet(const cv::Scalar &value, void *dataPointer, int step, IppiSize &size, int channels, int depth)
|
|
||||||
{
|
|
||||||
CV_INSTRUMENT_REGION_IPP();
|
|
||||||
|
|
||||||
if( channels == 1 )
|
|
||||||
{
|
|
||||||
switch( depth )
|
|
||||||
{
|
|
||||||
case CV_8U:
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiSet_8u_C1R, saturate_cast<Ipp8u>(value[0]), (Ipp8u *)dataPointer, step, size) >= 0;
|
|
||||||
case CV_16U:
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiSet_16u_C1R, saturate_cast<Ipp16u>(value[0]), (Ipp16u *)dataPointer, step, size) >= 0;
|
|
||||||
case CV_32F:
|
|
||||||
return CV_INSTRUMENT_FUN_IPP(ippiSet_32f_C1R, saturate_cast<Ipp32f>(value[0]), (Ipp32f *)dataPointer, step, size) >= 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( channels == 3 )
|
|
||||||
{
|
|
||||||
switch( depth )
|
|
||||||
{
|
|
||||||
case CV_8U:
|
|
||||||
return IPPSetSimple<3, Ipp8u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_8u_C3R);
|
|
||||||
case CV_16U:
|
|
||||||
return IPPSetSimple<3, Ipp16u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_16u_C3R);
|
|
||||||
case CV_32F:
|
|
||||||
return IPPSetSimple<3, Ipp32f>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_32f_C3R);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( channels == 4 )
|
|
||||||
{
|
|
||||||
switch( depth )
|
|
||||||
{
|
|
||||||
case CV_8U:
|
|
||||||
return IPPSetSimple<4, Ipp8u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_8u_C4R);
|
|
||||||
case CV_16U:
|
|
||||||
return IPPSetSimple<4, Ipp16u>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_16u_C4R);
|
|
||||||
case CV_32F:
|
|
||||||
return IPPSetSimple<4, Ipp32f>(value, dataPointer, step, size, (ippiSetFunc)ippiSet_32f_C4R);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/************** interpolation formulas and tables ***************/
|
/************** interpolation formulas and tables ***************/
|
||||||
|
|
||||||
@@ -1572,57 +1512,7 @@ static bool ocl_logPolar(InputArray _src, OutputArray _dst,
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined HAVE_IPP && !IPP_DISABLE_REMAP
|
|
||||||
|
|
||||||
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 ParallelLoopBody
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IPPRemapInvoker(Mat & _src, Mat & _dst, Mat & _xmap, Mat & _ymap, ippiRemap _ippFunc,
|
|
||||||
int _ippInterpolation, int _borderType, const Scalar & _borderValue, bool * _ok) :
|
|
||||||
ParallelLoopBody(), src(_src), dst(_dst), map1(_xmap), map2(_ymap), ippFunc(_ippFunc),
|
|
||||||
ippInterpolation(_ippInterpolation), borderType(_borderType), borderValue(_borderValue), ok(_ok)
|
|
||||||
{
|
|
||||||
*ok = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void operator() (const Range & range) const
|
|
||||||
{
|
|
||||||
IppiRect srcRoiRect = { 0, 0, src.cols, src.rows };
|
|
||||||
Mat dstRoi = dst.rowRange(range);
|
|
||||||
IppiSize dstRoiSize = ippiSize(dstRoi.size());
|
|
||||||
int type = dst.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
|
|
||||||
|
|
||||||
if (borderType == BORDER_CONSTANT &&
|
|
||||||
!IPPSet(borderValue, dstRoi.ptr(), (int)dstRoi.step, dstRoiSize, cn, depth))
|
|
||||||
{
|
|
||||||
*ok = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CV_INSTRUMENT_FUN_IPP(ippFunc, src.ptr(), ippiSize(src.size()), (int)src.step, srcRoiRect,
|
|
||||||
map1.ptr<Ipp32f>(), (int)map1.step, map2.ptr<Ipp32f>(), (int)map2.step,
|
|
||||||
dstRoi.ptr(), (int)dstRoi.step, dstRoiSize, ippInterpolation) < 0)
|
|
||||||
*ok = false;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Mat & src, & dst, & map1, & map2;
|
|
||||||
ippiRemap ippFunc;
|
|
||||||
int ippInterpolation, borderType;
|
|
||||||
Scalar borderValue;
|
|
||||||
bool * ok;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1737,47 +1627,6 @@ void cv::remap( InputArray _src, OutputArray _dst,
|
|||||||
|
|
||||||
int type = src.type(), depth = CV_MAT_DEPTH(type);
|
int type = src.type(), depth = CV_MAT_DEPTH(type);
|
||||||
|
|
||||||
#if defined HAVE_IPP && !IPP_DISABLE_REMAP
|
|
||||||
CV_IPP_CHECK()
|
|
||||||
{
|
|
||||||
if ((interpolation == INTER_LINEAR || interpolation == INTER_CUBIC || interpolation == INTER_NEAREST) &&
|
|
||||||
map1.type() == CV_32FC1 && map2.type() == CV_32FC1 &&
|
|
||||||
(borderType == BORDER_CONSTANT || borderType == BORDER_TRANSPARENT))
|
|
||||||
{
|
|
||||||
int ippInterpolation =
|
|
||||||
interpolation == INTER_NEAREST ? IPPI_INTER_NN :
|
|
||||||
interpolation == INTER_LINEAR ? IPPI_INTER_LINEAR : IPPI_INTER_CUBIC;
|
|
||||||
|
|
||||||
ippiRemap ippFunc =
|
|
||||||
type == CV_8UC1 ? (ippiRemap)ippiRemap_8u_C1R :
|
|
||||||
type == CV_8UC3 ? (ippiRemap)ippiRemap_8u_C3R :
|
|
||||||
type == CV_8UC4 ? (ippiRemap)ippiRemap_8u_C4R :
|
|
||||||
type == CV_16UC1 ? (ippiRemap)ippiRemap_16u_C1R :
|
|
||||||
type == CV_16UC3 ? (ippiRemap)ippiRemap_16u_C3R :
|
|
||||||
type == CV_16UC4 ? (ippiRemap)ippiRemap_16u_C4R :
|
|
||||||
type == CV_32FC1 ? (ippiRemap)ippiRemap_32f_C1R :
|
|
||||||
type == CV_32FC3 ? (ippiRemap)ippiRemap_32f_C3R :
|
|
||||||
type == CV_32FC4 ? (ippiRemap)ippiRemap_32f_C4R : 0;
|
|
||||||
|
|
||||||
if (ippFunc)
|
|
||||||
{
|
|
||||||
bool ok;
|
|
||||||
IPPRemapInvoker invoker(src, dst, map1, map2, ippFunc, ippInterpolation,
|
|
||||||
borderType, borderValue, &ok);
|
|
||||||
Range range(0, dst.rows);
|
|
||||||
parallel_for_(range, invoker, dst.total() / (double)(1 << 16));
|
|
||||||
|
|
||||||
if (ok)
|
|
||||||
{
|
|
||||||
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setIppErrorStatus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RemapNNFunc nnfunc = 0;
|
RemapNNFunc nnfunc = 0;
|
||||||
RemapFunc ifunc = 0;
|
RemapFunc ifunc = 0;
|
||||||
const void* ctab = 0;
|
const void* ctab = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user