1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 15:53:03 +04:00

Update for IPP for OpenCV 2017u2 integration;

Updated integrations for:
cv::split
cv::merge
cv::insertChannel
cv::extractChannel
cv::Mat::convertTo - now with scaled conversions support
cv::LUT - disabled due to performance issues
Mat::copyTo
Mat::setTo
cv::flip
cv::copyMakeBorder - currently disabled
cv::polarToCart
cv::pow - ipp pow function was removed due to performance issues
cv::hal::magnitude32f/64f - disabled for <= SSE42, poor performance
cv::countNonZero
cv::minMaxIdx
cv::norm
cv::canny - new integration. Disabled for threaded;
cv::cornerHarris
cv::boxFilter
cv::bilateralFilter
cv::integral
This commit is contained in:
Pavel Vlasov
2017-04-21 14:52:45 +03:00
parent f1c8094f5f
commit 11c2ffaf1c
21 changed files with 1392 additions and 1245 deletions
@@ -217,8 +217,6 @@ CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int un
#define IPP_DISABLE_PERF_MAG_SSE42 1 // cv::magnitude optimizations problem
#define IPP_DISABLE_PERF_BOX16S_SSE42 1 // cv::boxFilter optimizations problem
#define IPP_DISABLE_BLOCK 0 // legacy switch
#ifdef HAVE_IPP
#include "ippversion.h"
#ifndef IPP_VERSION_UPDATE // prior to 7.1
+284 -49
View File
@@ -85,6 +85,66 @@ static MergeFunc getMergeFunc(int depth)
return mergeTab[depth];
}
#ifdef HAVE_IPP
#ifdef HAVE_IPP_IW
extern "C" {
IW_DECL(IppStatus) llwiCopySplit(const void *pSrc, int srcStep, void* const pDstOrig[], int dstStep,
IppiSize size, int typeSize, int channels);
}
#endif
namespace cv {
static bool ipp_split(const Mat& src, Mat* mv, int channels)
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
if(channels != 3 && channels != 4)
return false;
if(src.dims <= 2)
{
IppiSize size = ippiSize(src.size());
void *dstPtrs[4] = {NULL};
size_t dstStep = mv[0].step;
for(int i = 0; i < channels; i++)
{
dstPtrs[i] = mv[i].ptr();
if(dstStep != mv[i].step)
return false;
}
return CV_INSTRUMENT_FUN_IPP(llwiCopySplit, src.ptr(), (int)src.step, dstPtrs, (int)dstStep, size, (int)src.elemSize1(), channels) >= 0;
}
else
{
const Mat *arrays[5] = {NULL};
uchar *ptrs[5] = {NULL};
arrays[0] = &src;
for(int i = 1; i < channels; i++)
{
arrays[i] = &mv[i-1];
}
NAryMatIterator it(arrays, ptrs);
IppiSize size = { (int)it.size, 1 };
for( size_t i = 0; i < it.nplanes; i++, ++it )
{
if(CV_INSTRUMENT_FUN_IPP(llwiCopySplit, ptrs[0], 0, (void**)&ptrs[1], 0, size, (int)src.elemSize1(), channels) < 0)
return false;
}
return true;
}
#else
CV_UNUSED(src); CV_UNUSED(mv); CV_UNUSED(channels);
return false;
#endif
}
}
#endif
void cv::split(const Mat& src, Mat* mv)
{
CV_INSTRUMENT_REGION()
@@ -96,6 +156,13 @@ void cv::split(const Mat& src, Mat* mv)
return;
}
for( k = 0; k < cn; k++ )
{
mv[k].create(src.dims, src.size, depth);
}
CV_IPP_RUN_FAST(ipp_split(src, mv, cn));
SplitFunc func = getSplitFunc(depth);
CV_Assert( func != 0 );
@@ -108,7 +175,6 @@ void cv::split(const Mat& src, Mat* mv)
arrays[0] = &src;
for( k = 0; k < cn; k++ )
{
mv[k].create(src.dims, src.size, depth);
arrays[k+1] = &mv[k];
}
@@ -206,6 +272,66 @@ void cv::split(InputArray _m, OutputArrayOfArrays _mv)
split(m, &dst[0]);
}
#ifdef HAVE_IPP
#ifdef HAVE_IPP_IW
extern "C" {
IW_DECL(IppStatus) llwiCopyMerge(const void* const pSrc[], int srcStep, void *pDst, int dstStep,
IppiSize size, int typeSize, int channels);
}
#endif
namespace cv {
static bool ipp_merge(const Mat* mv, Mat& dst, int channels)
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
if(channels != 3 && channels != 4)
return false;
if(mv[0].dims <= 2)
{
IppiSize size = ippiSize(mv[0].size());
const void *srcPtrs[4] = {NULL};
size_t srcStep = mv[0].step;
for(int i = 0; i < channels; i++)
{
srcPtrs[i] = mv[i].ptr();
if(srcStep != mv[i].step)
return false;
}
return CV_INSTRUMENT_FUN_IPP(llwiCopyMerge, srcPtrs, (int)srcStep, dst.ptr(), (int)dst.step, size, (int)mv[0].elemSize1(), channels) >= 0;
}
else
{
const Mat *arrays[5] = {NULL};
uchar *ptrs[5] = {NULL};
arrays[0] = &dst;
for(int i = 1; i < channels; i++)
{
arrays[i] = &mv[i-1];
}
NAryMatIterator it(arrays, ptrs);
IppiSize size = { (int)it.size, 1 };
for( size_t i = 0; i < it.nplanes; i++, ++it )
{
if(CV_INSTRUMENT_FUN_IPP(llwiCopyMerge, (const void**)&ptrs[1], 0, ptrs[0], 0, size, (int)mv[0].elemSize1(), channels) < 0)
return false;
}
return true;
}
#else
CV_UNUSED(dst); CV_UNUSED(mv); CV_UNUSED(channels);
return false;
#endif
}
}
#endif
void cv::merge(const Mat* mv, size_t n, OutputArray _dst)
{
CV_INSTRUMENT_REGION()
@@ -234,6 +360,8 @@ void cv::merge(const Mat* mv, size_t n, OutputArray _dst)
return;
}
CV_IPP_RUN_FAST(ipp_merge(mv, dst, (int)n));
if( !allch1 )
{
AutoBuffer<int> pairs(cn*2);
@@ -691,6 +819,59 @@ void cv::mixChannels(InputArrayOfArrays src, InputOutputArrayOfArrays dst,
mixChannels(&buf[0], nsrc, &buf[nsrc], ndst, &fromTo[0], fromTo.size()/2);
}
#ifdef HAVE_IPP
#ifdef HAVE_IPP_IW
extern "C" {
IW_DECL(IppStatus) llwiCopyMixed(const void *pSrc, int srcStep, int srcChannels, void *pDst, int dstStep, int dstChannels,
IppiSize size, int typeSize, int channelsShift);
}
#endif
namespace cv
{
static bool ipp_extractInsertChannel(const Mat &src, Mat &dst, int channel)
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
int srcChannels = src.channels();
int dstChannels = dst.channels();
if(src.dims != dst.dims)
return false;
if(srcChannels == dstChannels || (srcChannels != 1 && dstChannels != 1))
return false;
if(src.dims <= 2)
{
IppiSize size = ippiSize(src.size());
return CV_INSTRUMENT_FUN_IPP(llwiCopyMixed, src.ptr(), (int)src.step, srcChannels, dst.ptr(), (int)dst.step, dstChannels, size, (int)src.elemSize1(), channel) >= 0;
}
else
{
const Mat *arrays[] = {&dst, NULL};
uchar *ptrs[2] = {NULL};
NAryMatIterator it(arrays, ptrs);
IppiSize size = {(int)it.size, 1};
for( size_t i = 0; i < it.nplanes; i++, ++it )
{
if(CV_INSTRUMENT_FUN_IPP(llwiCopyMixed, ptrs[0], 0, srcChannels, ptrs[1], 0, dstChannels, size, (int)src.elemSize1(), channel) < 0)
return false;
}
return true;
}
#else
CV_UNUSED(src); CV_UNUSED(dst); CV_UNUSED(channel);
return false;
#endif
}
}
#endif
void cv::extractChannel(InputArray _src, OutputArray _dst, int coi)
{
CV_INSTRUMENT_REGION()
@@ -711,6 +892,9 @@ void cv::extractChannel(InputArray _src, OutputArray _dst, int coi)
Mat src = _src.getMat();
_dst.create(src.dims, &src.size[0], depth);
Mat dst = _dst.getMat();
CV_IPP_RUN_FAST(ipp_extractInsertChannel(src, dst, coi))
mixChannels(&src, 1, &dst, 1, ch, 1);
}
@@ -732,6 +916,9 @@ void cv::insertChannel(InputArray _src, InputOutputArray _dst, int coi)
}
Mat src = _src.getMat(), dst = _dst.getMat();
CV_IPP_RUN_FAST(ipp_extractInsertChannel(src, dst, coi))
mixChannels(&src, 1, &dst, 1, ch, 1);
}
@@ -5264,6 +5451,72 @@ void cv::convertFp16( InputArray _src, OutputArray _dst)
}
}
#ifdef HAVE_IPP
namespace cv
{
static bool ipp_convertTo(Mat &src, Mat &dst, double alpha, double beta)
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
IppDataType srcDepth = ippiGetDataType(src.depth());
IppDataType dstDepth = ippiGetDataType(dst.depth());
int channels = src.channels();
if(src.dims == 0)
return false;
::ipp::IwiImage iwSrc;
::ipp::IwiImage iwDst;
try
{
IppHintAlgorithm mode = ippAlgHintFast;
if(dstDepth == ipp64f ||
(dstDepth == ipp32f && (srcDepth == ipp32s || srcDepth == ipp64f)) ||
(dstDepth == ipp32s && (srcDepth == ipp32s || srcDepth == ipp64f)))
mode = ippAlgHintAccurate;
if(src.dims <= 2)
{
Size sz = getContinuousSize(src, dst, channels);
iwSrc.Init(ippiSize(sz), srcDepth, 1, NULL, (void*)src.ptr(), src.step);
iwDst.Init(ippiSize(sz), dstDepth, 1, NULL, (void*)dst.ptr(), dst.step);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, &iwSrc, &iwDst, alpha, beta, mode);
}
else
{
const Mat *arrays[] = {&src, &dst, NULL};
uchar *ptrs[2] = {NULL};
NAryMatIterator it(arrays, ptrs);
iwSrc.Init(ippiSize(it.size, 1), srcDepth, channels);
iwDst.Init(ippiSize(it.size, 1), dstDepth, channels);
for(size_t i = 0; i < it.nplanes; i++, ++it)
{
iwSrc.m_ptr = ptrs[0];
iwDst.m_ptr = ptrs[1];
CV_INSTRUMENT_FUN_IPP(::ipp::iwiScale, &iwSrc, &iwDst, alpha, beta, mode);
}
}
}
catch (::ipp::IwException)
{
return false;
}
return true;
#else
CV_UNUSED(src); CV_UNUSED(dst); CV_UNUSED(alpha); CV_UNUSED(beta);
return false;
#endif
}
}
#endif
void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta) const
{
CV_INSTRUMENT_REGION()
@@ -5283,6 +5536,13 @@ void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta)
}
Mat src = *this;
if( dims <= 2 )
_dst.create( size(), _type );
else
_dst.create( dims, size, _type );
Mat dst = _dst.getMat();
CV_IPP_RUN_FAST(ipp_convertTo(src, dst, alpha, beta ));
BinaryFunc func = noScale ? getConvertFunc(sdepth, ddepth) : getConvertScaleFunc(sdepth, ddepth);
double scale[] = {alpha, beta};
@@ -5291,15 +5551,12 @@ void cv::Mat::convertTo(OutputArray _dst, int _type, double alpha, double beta)
if( dims <= 2 )
{
_dst.create( size(), _type );
Mat dst = _dst.getMat();
Size sz = getContinuousSize(src, dst, cn);
func( src.data, src.step, 0, 0, dst.data, dst.step, sz, scale );
}
else
{
_dst.create( dims, size, _type );
Mat dst = _dst.getMat();
const Mat* arrays[] = {&src, &dst, 0};
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs);
@@ -5436,9 +5693,9 @@ static bool openvx_LUT(Mat src, Mat dst, Mat _lut)
#endif
#if defined(HAVE_IPP)
#if !IPP_DISABLE_PERF_LUT // there are no performance benefits (PR #2653)
namespace ipp {
#if IPP_DISABLE_BLOCK // there are no performance benefits (PR #2653)
class IppLUTParallelBody_LUTC1 : public ParallelLoopBody
{
public:
@@ -5447,25 +5704,17 @@ public:
const Mat& lut_;
Mat& dst_;
typedef IppStatus (*IppFn)(const Ipp8u* pSrc, int srcStep, void* pDst, int dstStep,
IppiSize roiSize, const void* pTable, int nBitSize);
IppFn fn;
int width;
size_t elemSize1;
IppLUTParallelBody_LUTC1(const Mat& src, const Mat& lut, Mat& dst, bool* _ok)
: ok(_ok), src_(src), lut_(lut), dst_(dst)
{
width = dst.cols * dst.channels();
elemSize1 = CV_ELEM_SIZE1(dst.depth());
size_t elemSize1 = CV_ELEM_SIZE1(dst.depth());
fn =
elemSize1 == 1 ? (IppFn)ippiLUTPalette_8u_C1R :
elemSize1 == 4 ? (IppFn)ippiLUTPalette_8u32u_C1R :
NULL;
*ok = (fn != NULL);
CV_DbgAssert(elemSize1 == 1 || elemSize1 == 4);
*ok = true;
}
void operator()( const cv::Range& range ) const
@@ -5481,19 +5730,22 @@ public:
IppiSize sz = { width, dst.rows };
CV_DbgAssert(fn != NULL);
if (fn(src.data, (int)src.step[0], dst.data, (int)dst.step[0], sz, lut_.data, 8) < 0)
if (elemSize1 == 1)
{
setIppErrorStatus();
*ok = false;
if (CV_INSTRUMENT_FUN_IPP(ippiLUTPalette_8u_C1R, (const Ipp8u*)src.data, (int)src.step[0], dst.data, (int)dst.step[0], sz, lut_.data, 8) >= 0)
return;
}
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
else if (elemSize1 == 4)
{
if (CV_INSTRUMENT_FUN_IPP(ippiLUTPalette_8u32u_C1R, (const Ipp8u*)src.data, (int)src.step[0], (Ipp32u*)dst.data, (int)dst.step[0], sz, (Ipp32u*)lut_.data, 8) >= 0)
return;
}
*ok = false;
}
private:
IppLUTParallelBody_LUTC1(const IppLUTParallelBody_LUTC1&);
IppLUTParallelBody_LUTC1& operator=(const IppLUTParallelBody_LUTC1&);
};
#endif
class IppLUTParallelBody_LUTCN : public ParallelLoopBody
{
@@ -5527,21 +5779,13 @@ public:
{
IppStatus status = CV_INSTRUMENT_FUN_IPP(ippiCopy_8u_C3P3R, lut.ptr(), (int)lut.step[0], lutTable, (int)lut.step[0], sz256);
if (status < 0)
{
setIppErrorStatus();
return;
}
CV_IMPL_ADD(CV_IMPL_IPP);
}
else if (lutcn == 4)
{
IppStatus status = CV_INSTRUMENT_FUN_IPP(ippiCopy_8u_C4P4R, lut.ptr(), (int)lut.step[0], lutTable, (int)lut.step[0], sz256);
if (status < 0)
{
setIppErrorStatus();
return;
}
CV_IMPL_ADD(CV_IMPL_IPP);
}
*ok = true;
@@ -5568,25 +5812,14 @@ public:
if (lutcn == 3)
{
if (CV_INSTRUMENT_FUN_IPP(ippiLUTPalette_8u_C3R,
src.ptr(), (int)src.step[0], dst.ptr(), (int)dst.step[0],
ippiSize(dst.size()), lutTable, 8) >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
if (CV_INSTRUMENT_FUN_IPP(ippiLUTPalette_8u_C3R, src.ptr(), (int)src.step[0], dst.ptr(), (int)dst.step[0], ippiSize(dst.size()), lutTable, 8) >= 0)
return;
}
}
else if (lutcn == 4)
{
if (CV_INSTRUMENT_FUN_IPP(ippiLUTPalette_8u_C4R,
src.ptr(), (int)src.step[0], dst.ptr(), (int)dst.step[0],
ippiSize(dst.size()), lutTable, 8) >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
if (CV_INSTRUMENT_FUN_IPP(ippiLUTPalette_8u_C4R, src.ptr(), (int)src.step[0], dst.ptr(), (int)dst.step[0], ippiSize(dst.size()), lutTable, 8) >= 0)
return;
}
}
setIppErrorStatus();
*ok = false;
}
private:
@@ -5608,15 +5841,13 @@ static bool ipp_lut(Mat &src, Mat &lut, Mat &dst)
Ptr<ParallelLoopBody> body;
size_t elemSize1 = CV_ELEM_SIZE1(dst.depth());
#if IPP_DISABLE_BLOCK // there are no performance benefits (PR #2653)
if (lutcn == 1)
{
ParallelLoopBody* p = new ipp::IppLUTParallelBody_LUTC1(src, lut, dst, &ok);
body.reset(p);
}
else
#endif
if ((lutcn == 3 || lutcn == 4) && elemSize1 == 1)
else if ((lutcn == 3 || lutcn == 4) && elemSize1 == 1)
{
ParallelLoopBody* p = new ipp::IppLUTParallelBody_LUTCN(src, lut, dst, &ok);
body.reset(p);
@@ -5635,6 +5866,8 @@ static bool ipp_lut(Mat &src, Mat &lut, Mat &dst)
return false;
}
#endif
#endif // IPP
class LUTParallelBody : public ParallelLoopBody
@@ -5703,7 +5936,9 @@ void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst )
CV_OVX_RUN(true,
openvx_LUT(src, dst, lut))
#if !IPP_DISABLE_PERF_LUT
CV_IPP_RUN(_src.dims() <= 2, ipp_lut(src, lut, dst));
#endif
if (_src.dims() <= 2)
{
+150 -276
View File
@@ -49,6 +49,19 @@
#include "precomp.hpp"
#include "opencl_kernels_core.hpp"
#ifdef HAVE_IPP_IW
extern "C" {
IW_DECL(IppStatus) llwiCopyMask(const void *pSrc, int srcStep, void *pDst, int dstStep,
IppiSize size, int typeSize, int channels, const Ipp8u *pMask, int maskStep);
IW_DECL(IppStatus) llwiSet(const double *pValue, void *pDst, int dstStep,
IppiSize size, IppDataType dataType, int channels);
IW_DECL(IppStatus) llwiSetMask(const double *pValue, void *pDst, int dstStep,
IppiSize size, IppDataType dataType, int channels, const Ipp8u *pMask, int maskStep);
IW_DECL(IppStatus) llwiCopyMakeBorder(const void *pSrc, IppSizeL srcStep, void *pDst, IppSizeL dstStep,
IppiSizeL size, IppDataType dataType, int channels, IppiBorderSize *pBorderSize, IppiBorderType border, const Ipp64f *pBorderVal);
}
#endif
namespace cv
{
@@ -326,6 +339,42 @@ void Mat::copyTo( OutputArray _dst ) const
}
}
#ifdef HAVE_IPP
static bool ipp_copyTo(const Mat &src, Mat &dst, const Mat &mask)
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
if(mask.channels() > 1 && mask.depth() != CV_8U)
return false;
if (src.dims <= 2)
{
IppiSize size = ippiSize(src.size());
return CV_INSTRUMENT_FUN_IPP(llwiCopyMask, src.ptr(), (int)src.step, dst.ptr(), (int)dst.step, size, (int)src.elemSize1(), src.channels(), mask.ptr(), (int)mask.step) >= 0;
}
else
{
const Mat *arrays[] = {&src, &dst, &mask, NULL};
uchar *ptrs[3] = {NULL};
NAryMatIterator it(arrays, ptrs);
IppiSize size = ippiSize(it.size, 1);
for (size_t i = 0; i < it.nplanes; i++, ++it)
{
if(CV_INSTRUMENT_FUN_IPP(llwiCopyMask, ptrs[0], 0, ptrs[1], 0, size, (int)src.elemSize1(), src.channels(), ptrs[2], 0) < 0)
return false;
}
return true;
}
#else
CV_UNUSED(src); CV_UNUSED(dst); CV_UNUSED(mask);
return false;
#endif
}
#endif
void Mat::copyTo( OutputArray _dst, InputArray _mask ) const
{
CV_INSTRUMENT_REGION()
@@ -340,9 +389,10 @@ void Mat::copyTo( OutputArray _dst, InputArray _mask ) const
int cn = channels(), mcn = mask.channels();
CV_Assert( mask.depth() == CV_8U && (mcn == 1 || mcn == cn) );
bool colorMask = mcn > 1;
size_t esz = colorMask ? elemSize1() : elemSize();
BinaryFunc copymask = getCopyMaskFunc(esz);
if( dims <= 2 )
{
CV_Assert( size() == mask.size() );
}
uchar* data0 = _dst.getMat().data;
_dst.create( dims, size, type() );
@@ -351,9 +401,13 @@ void Mat::copyTo( OutputArray _dst, InputArray _mask ) const
if( dst.data != data0 ) // do not leave dst uninitialized
dst = Scalar(0);
CV_IPP_RUN_FAST(ipp_copyTo(*this, dst, mask))
size_t esz = colorMask ? elemSize1() : elemSize();
BinaryFunc copymask = getCopyMaskFunc(esz);
if( dims <= 2 )
{
CV_Assert( size() == mask.size() );
Size sz = getContinuousSize(*this, dst, mask, mcn);
copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz);
return;
@@ -380,36 +434,6 @@ Mat& Mat::operator = (const Scalar& s)
if( is[0] == 0 && is[1] == 0 && is[2] == 0 && is[3] == 0 )
{
#if defined HAVE_IPP && IPP_DISABLE_BLOCK
CV_IPP_CHECK()
{
if (dims <= 2 || isContinuous())
{
IppiSize roisize = { cols, rows };
if (isContinuous())
{
roisize.width = (int)total();
roisize.height = 1;
if (ippsZero_8u(data, static_cast<int>(roisize.width * elemSize())) >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP)
return *this;
}
setIppErrorStatus();
}
roisize.width *= (int)elemSize();
if (ippiSet_8u_C1R(0, data, (int)step, roisize) >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP)
return *this;
}
setIppErrorStatus();
}
}
#endif
for( size_t i = 0; i < it.nplanes; i++, ++it )
memset( dptr, 0, elsize );
}
@@ -437,89 +461,55 @@ Mat& Mat::operator = (const Scalar& s)
return *this;
}
#if defined HAVE_IPP
static bool ipp_Mat_setTo(Mat *src, Mat &value, Mat &mask)
#ifdef HAVE_IPP
static bool ipp_Mat_setTo_Mat(Mat &dst, Mat &_val, Mat &mask)
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
int cn = src->channels(), depth0 = src->depth();
if(mask.empty())
return false;
if (!mask.empty() && (src->dims <= 2 || (src->isContinuous() && mask.isContinuous())) &&
(/*depth0 == CV_8U ||*/ depth0 == CV_16U || depth0 == CV_16S || depth0 == CV_32S || depth0 == CV_32F) &&
(cn == 1 || cn == 3 || cn == 4))
if(mask.depth() != CV_8U || mask.channels() > 1)
return false;
if(dst.channels() > 4)
return false;
if(dst.dims <= 2)
{
uchar _buf[32];
void * buf = _buf;
convertAndUnrollScalar( value, src->type(), _buf, 1 );
IppiSize size = ippiSize(dst.size());
IppDataType dataType = ippiGetDataType(dst.depth());
::ipp::IwValue s;
convertAndUnrollScalar(_val, CV_MAKETYPE(CV_64F, dst.channels()), (uchar*)((Ipp64f*)s), 1);
IppStatus status = (IppStatus)-1;
IppiSize roisize = { src->cols, src->rows };
int mstep = (int)mask.step[0], dstep = (int)src->step[0];
if (src->isContinuous() && mask.isContinuous())
{
roisize.width = (int)src->total();
roisize.height = 1;
}
if (cn == 1)
{
/*if (depth0 == CV_8U)
status = ippiSet_8u_C1MR(*(Ipp8u *)buf, (Ipp8u *)data, dstep, roisize, mask.data, mstep);
else*/ if (depth0 == CV_16U)
status = CV_INSTRUMENT_FUN_IPP(ippiSet_16u_C1MR, *(Ipp16u *)buf, (Ipp16u *)src->data, dstep, roisize, mask.data, mstep);
else if (depth0 == CV_16S)
status = CV_INSTRUMENT_FUN_IPP(ippiSet_16s_C1MR, *(Ipp16s *)buf, (Ipp16s *)src->data, dstep, roisize, mask.data, mstep);
else if (depth0 == CV_32S)
status = CV_INSTRUMENT_FUN_IPP(ippiSet_32s_C1MR, *(Ipp32s *)buf, (Ipp32s *)src->data, dstep, roisize, mask.data, mstep);
else if (depth0 == CV_32F)
status = CV_INSTRUMENT_FUN_IPP(ippiSet_32f_C1MR, *(Ipp32f *)buf, (Ipp32f *)src->data, dstep, roisize, mask.data, mstep);
}
else if (cn == 3 || cn == 4)
{
#define IPP_SET(ippfavor, ippcn) \
do \
{ \
typedef Ipp##ippfavor ipptype; \
ipptype ippvalue[4] = { ((ipptype *)buf)[0], ((ipptype *)buf)[1], ((ipptype *)buf)[2], ((ipptype *)buf)[3] }; \
status = CV_INSTRUMENT_FUN_IPP(ippiSet_##ippfavor##_C##ippcn##MR, ippvalue, (ipptype *)src->data, dstep, roisize, mask.data, mstep); \
} while ((void)0, 0)
#define IPP_SET_CN(ippcn) \
do \
{ \
if (cn == ippcn) \
{ \
/*if (depth0 == CV_8U) \
IPP_SET(8u, ippcn); \
else*/ if (depth0 == CV_16U) \
IPP_SET(16u, ippcn); \
else if (depth0 == CV_16S) \
IPP_SET(16s, ippcn); \
else if (depth0 == CV_32S) \
IPP_SET(32s, ippcn); \
else if (depth0 == CV_32F) \
IPP_SET(32f, ippcn); \
} \
} while ((void)0, 0)
IPP_SET_CN(3);
IPP_SET_CN(4);
#undef IPP_SET_CN
#undef IPP_SET
}
if (status >= 0)
return true;
return CV_INSTRUMENT_FUN_IPP(llwiSetMask, s, dst.ptr(), (int)dst.step, size, dataType, dst.channels(), mask.ptr(), (int)mask.step) >= 0;
}
else
{
const Mat *arrays[] = {&dst, mask.empty()?NULL:&mask, NULL};
uchar *ptrs[2] = {NULL};
NAryMatIterator it(arrays, ptrs);
IppiSize size = {(int)it.size, 1};
IppDataType dataType = ippiGetDataType(dst.depth());
::ipp::IwValue s;
convertAndUnrollScalar(_val, CV_MAKETYPE(CV_64F, dst.channels()), (uchar*)((Ipp64f*)s), 1);
for( size_t i = 0; i < it.nplanes; i++, ++it)
{
if(CV_INSTRUMENT_FUN_IPP(llwiSetMask, s, ptrs[0], 0, size, dataType, dst.channels(), ptrs[1], 0) < 0)
return false;
}
return true;
}
#else
CV_UNUSED(dst); CV_UNUSED(_val); CV_UNUSED(mask);
return false;
#endif
}
#endif
Mat& Mat::setTo(InputArray _value, InputArray _mask)
{
CV_INSTRUMENT_REGION()
@@ -532,7 +522,7 @@ Mat& Mat::setTo(InputArray _value, InputArray _mask)
CV_Assert( checkScalar(value, type(), _value.kind(), _InputArray::MAT ));
CV_Assert( mask.empty() || (mask.type() == CV_8U && size == mask.size) );
CV_IPP_RUN_FAST(ipp_Mat_setTo((cv::Mat*)this, value, mask), *this)
CV_IPP_RUN_FAST(ipp_Mat_setTo_Mat(*this, value, mask), *this)
size_t esz = elemSize();
BinaryFunc copymask = getCopyMaskFunc(esz);
@@ -707,73 +697,36 @@ static bool ocl_flip(InputArray _src, OutputArray _dst, int flipCode )
#endif
#if defined HAVE_IPP
static bool ipp_flip( Mat &src, Mat &dst, int flip_mode )
static bool ipp_flip(Mat &src, Mat &dst, int flip_mode)
{
#ifdef HAVE_IPP_IW
CV_INSTRUMENT_REGION_IPP()
int type = src.type();
typedef IppStatus (CV_STDCALL * IppiMirror)(const void * pSrc, int srcStep, void * pDst, int dstStep, IppiSize roiSize, IppiAxis flip);
typedef IppStatus (CV_STDCALL * IppiMirrorI)(const void * pSrcDst, int srcDstStep, IppiSize roiSize, IppiAxis flip);
IppiMirror ippiMirror = 0;
IppiMirrorI ippiMirror_I = 0;
if (src.data == dst.data)
{
CV_SUPPRESS_DEPRECATED_START
ippiMirror_I =
type == CV_8UC1 ? (IppiMirrorI)ippiMirror_8u_C1IR :
type == CV_8UC3 ? (IppiMirrorI)ippiMirror_8u_C3IR :
type == CV_8UC4 ? (IppiMirrorI)ippiMirror_8u_C4IR :
type == CV_16UC1 ? (IppiMirrorI)ippiMirror_16u_C1IR :
type == CV_16UC3 ? (IppiMirrorI)ippiMirror_16u_C3IR :
type == CV_16UC4 ? (IppiMirrorI)ippiMirror_16u_C4IR :
type == CV_16SC1 ? (IppiMirrorI)ippiMirror_16s_C1IR :
type == CV_16SC3 ? (IppiMirrorI)ippiMirror_16s_C3IR :
type == CV_16SC4 ? (IppiMirrorI)ippiMirror_16s_C4IR :
type == CV_32SC1 ? (IppiMirrorI)ippiMirror_32s_C1IR :
type == CV_32SC3 ? (IppiMirrorI)ippiMirror_32s_C3IR :
type == CV_32SC4 ? (IppiMirrorI)ippiMirror_32s_C4IR :
type == CV_32FC1 ? (IppiMirrorI)ippiMirror_32f_C1IR :
type == CV_32FC3 ? (IppiMirrorI)ippiMirror_32f_C3IR :
type == CV_32FC4 ? (IppiMirrorI)ippiMirror_32f_C4IR : 0;
CV_SUPPRESS_DEPRECATED_END
}
IppiAxis ippMode;
if(flip_mode < 0)
ippMode = ippAxsBoth;
else if(flip_mode == 0)
ippMode = ippAxsHorizontal;
else
{
ippiMirror =
type == CV_8UC1 ? (IppiMirror)ippiMirror_8u_C1R :
type == CV_8UC3 ? (IppiMirror)ippiMirror_8u_C3R :
type == CV_8UC4 ? (IppiMirror)ippiMirror_8u_C4R :
type == CV_16UC1 ? (IppiMirror)ippiMirror_16u_C1R :
type == CV_16UC3 ? (IppiMirror)ippiMirror_16u_C3R :
type == CV_16UC4 ? (IppiMirror)ippiMirror_16u_C4R :
type == CV_16SC1 ? (IppiMirror)ippiMirror_16s_C1R :
type == CV_16SC3 ? (IppiMirror)ippiMirror_16s_C3R :
type == CV_16SC4 ? (IppiMirror)ippiMirror_16s_C4R :
type == CV_32SC1 ? (IppiMirror)ippiMirror_32s_C1R :
type == CV_32SC3 ? (IppiMirror)ippiMirror_32s_C3R :
type == CV_32SC4 ? (IppiMirror)ippiMirror_32s_C4R :
type == CV_32FC1 ? (IppiMirror)ippiMirror_32f_C1R :
type == CV_32FC3 ? (IppiMirror)ippiMirror_32f_C3R :
type == CV_32FC4 ? (IppiMirror)ippiMirror_32f_C4R : 0;
}
IppiAxis axis = flip_mode == 0 ? ippAxsHorizontal :
flip_mode > 0 ? ippAxsVertical : ippAxsBoth;
IppiSize roisize = { dst.cols, dst.rows };
ippMode = ippAxsVertical;
if (ippiMirror != 0)
try
{
if (CV_INSTRUMENT_FUN_IPP(ippiMirror, src.ptr(), (int)src.step, dst.ptr(), (int)dst.step, ippiSize(src.cols, src.rows), axis) >= 0)
return true;
::ipp::IwiImage iwSrc = ippiGetImage(src);
::ipp::IwiImage iwDst = ippiGetImage(dst);
CV_INSTRUMENT_FUN_IPP(::ipp::iwiMirror, &iwSrc, &iwDst, ippMode);
}
else if (ippiMirror_I != 0)
catch(::ipp::IwException)
{
if (CV_INSTRUMENT_FUN_IPP(ippiMirror_I, dst.ptr(), (int)dst.step, roisize, axis) >= 0)
return true;
return false;
}
return true;
#else
CV_UNUSED(src); CV_UNUSED(dst); CV_UNUSED(flip_mode);
return false;
#endif
}
#endif
@@ -1178,7 +1131,41 @@ static bool ocl_copyMakeBorder( InputArray _src, OutputArray _dst, int top, int
}
}
#endif
#ifdef HAVE_IPP
namespace cv {
static bool ipp_copyMakeBorder( Mat &_src, Mat &_dst, int top, int bottom,
int left, int right, int _borderType, const Scalar& value )
{
#if defined HAVE_IPP_IW && !IPP_DISABLE_PERF_COPYMAKE
CV_INSTRUMENT_REGION_IPP()
::ipp::IwiBorderSize borderSize(left, top, right, bottom);
::ipp::IwiSize size(_src.cols, _src.rows);
IppDataType dataType = ippiGetDataType(_src.depth());
IppiBorderType borderType = ippiGetBorderType(_borderType);
if((int)borderType == -1)
return false;
if(_src.dims > 2)
return false;
Rect dstRect(borderSize.borderLeft, borderSize.borderTop,
_dst.cols - borderSize.borderRight - borderSize.borderLeft,
_dst.rows - borderSize.borderBottom - borderSize.borderTop);
Mat subDst = Mat(_dst, dstRect);
Mat *pSrc = &_src;
return CV_INSTRUMENT_FUN_IPP(llwiCopyMakeBorder, pSrc->ptr(), pSrc->step, subDst.ptr(), subDst.step, size, dataType, _src.channels(), &borderSize, borderType, &value[0]) >= 0;
#else
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(top); CV_UNUSED(bottom); CV_UNUSED(left); CV_UNUSED(right);
CV_UNUSED(_borderType); CV_UNUSED(value);
return false;
#endif
}
}
#endif
void cv::copyMakeBorder( InputArray _src, OutputArray _dst, int top, int bottom,
@@ -1222,120 +1209,7 @@ void cv::copyMakeBorder( InputArray _src, OutputArray _dst, int top, int bottom,
borderType &= ~BORDER_ISOLATED;
#if defined HAVE_IPP && IPP_DISABLE_BLOCK
CV_IPP_CHECK()
{
typedef IppStatus (CV_STDCALL * ippiCopyMakeBorder)(const void * pSrc, int srcStep, IppiSize srcRoiSize, void * pDst,
int dstStep, IppiSize dstRoiSize, int topBorderHeight, int leftBorderWidth);
typedef IppStatus (CV_STDCALL * ippiCopyMakeBorderI)(const void * pSrc, int srcDstStep, IppiSize srcRoiSize, IppiSize dstRoiSize,
int topBorderHeight, int leftborderwidth);
typedef IppStatus (CV_STDCALL * ippiCopyConstBorder)(const void * pSrc, int srcStep, IppiSize srcRoiSize, void * pDst, int dstStep,
IppiSize dstRoiSize, int topBorderHeight, int leftBorderWidth, void * value);
IppiSize srcRoiSize = { src.cols, src.rows }, dstRoiSize = { dst.cols, dst.rows };
ippiCopyMakeBorder ippFunc = 0;
ippiCopyMakeBorderI ippFuncI = 0;
ippiCopyConstBorder ippFuncConst = 0;
bool inplace = dst.datastart == src.datastart;
if (borderType == BORDER_CONSTANT)
{
ippFuncConst =
// type == CV_8UC1 ? (ippiCopyConstBorder)ippiCopyConstBorder_8u_C1R : bug in IPP 8.1
type == CV_16UC1 ? (ippiCopyConstBorder)ippiCopyConstBorder_16u_C1R :
// type == CV_16SC1 ? (ippiCopyConstBorder)ippiCopyConstBorder_16s_C1R : bug in IPP 8.1
// type == CV_32SC1 ? (ippiCopyConstBorder)ippiCopyConstBorder_32s_C1R : bug in IPP 8.1
// type == CV_32FC1 ? (ippiCopyConstBorder)ippiCopyConstBorder_32f_C1R : bug in IPP 8.1
type == CV_8UC3 ? (ippiCopyConstBorder)ippiCopyConstBorder_8u_C3R :
type == CV_16UC3 ? (ippiCopyConstBorder)ippiCopyConstBorder_16u_C3R :
type == CV_16SC3 ? (ippiCopyConstBorder)ippiCopyConstBorder_16s_C3R :
type == CV_32SC3 ? (ippiCopyConstBorder)ippiCopyConstBorder_32s_C3R :
type == CV_32FC3 ? (ippiCopyConstBorder)ippiCopyConstBorder_32f_C3R :
type == CV_8UC4 ? (ippiCopyConstBorder)ippiCopyConstBorder_8u_C4R :
type == CV_16UC4 ? (ippiCopyConstBorder)ippiCopyConstBorder_16u_C4R :
type == CV_16SC4 ? (ippiCopyConstBorder)ippiCopyConstBorder_16s_C4R :
type == CV_32SC4 ? (ippiCopyConstBorder)ippiCopyConstBorder_32s_C4R :
type == CV_32FC4 ? (ippiCopyConstBorder)ippiCopyConstBorder_32f_C4R : 0;
}
else if (borderType == BORDER_WRAP)
{
if (inplace)
{
CV_SUPPRESS_DEPRECATED_START
ippFuncI =
type == CV_32SC1 ? (ippiCopyMakeBorderI)ippiCopyWrapBorder_32s_C1IR :
type == CV_32FC1 ? (ippiCopyMakeBorderI)ippiCopyWrapBorder_32s_C1IR : 0;
CV_SUPPRESS_DEPRECATED_END
}
else
{
ippFunc =
type == CV_32SC1 ? (ippiCopyMakeBorder)ippiCopyWrapBorder_32s_C1R :
type == CV_32FC1 ? (ippiCopyMakeBorder)ippiCopyWrapBorder_32s_C1R : 0;
}
}
else if (borderType == BORDER_REPLICATE)
{
if (inplace)
{
CV_SUPPRESS_DEPRECATED_START
ippFuncI =
type == CV_8UC1 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_8u_C1IR :
type == CV_16UC1 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_16u_C1IR :
type == CV_16SC1 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_16s_C1IR :
type == CV_32SC1 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_32s_C1IR :
type == CV_32FC1 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_32f_C1IR :
type == CV_8UC3 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_8u_C3IR :
type == CV_16UC3 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_16u_C3IR :
type == CV_16SC3 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_16s_C3IR :
type == CV_32SC3 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_32s_C3IR :
type == CV_32FC3 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_32f_C3IR :
type == CV_8UC4 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_8u_C4IR :
type == CV_16UC4 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_16u_C4IR :
type == CV_16SC4 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_16s_C4IR :
type == CV_32SC4 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_32s_C4IR :
type == CV_32FC4 ? (ippiCopyMakeBorderI)ippiCopyReplicateBorder_32f_C4IR : 0;
CV_SUPPRESS_DEPRECATED_END
}
else
{
ippFunc =
type == CV_8UC1 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_8u_C1R :
type == CV_16UC1 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_16u_C1R :
type == CV_16SC1 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_16s_C1R :
type == CV_32SC1 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_32s_C1R :
type == CV_32FC1 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_32f_C1R :
type == CV_8UC3 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_8u_C3R :
type == CV_16UC3 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_16u_C3R :
type == CV_16SC3 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_16s_C3R :
type == CV_32SC3 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_32s_C3R :
type == CV_32FC3 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_32f_C3R :
type == CV_8UC4 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_8u_C4R :
type == CV_16UC4 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_16u_C4R :
type == CV_16SC4 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_16s_C4R :
type == CV_32SC4 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_32s_C4R :
type == CV_32FC4 ? (ippiCopyMakeBorder)ippiCopyReplicateBorder_32f_C4R : 0;
}
}
if (ippFunc || ippFuncI || ippFuncConst)
{
uchar scbuf[32];
scalarToRawData(value, scbuf, type);
if ( (ippFunc && ippFunc(src.data, (int)src.step, srcRoiSize, dst.data, (int)dst.step, dstRoiSize, top, left) >= 0) ||
(ippFuncI && ippFuncI(src.data, (int)src.step, srcRoiSize, dstRoiSize, top, left) >= 0) ||
(ippFuncConst && ippFuncConst(src.data, (int)src.step, srcRoiSize, dst.data, (int)dst.step,
dstRoiSize, top, left, scbuf) >= 0))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
}
}
#endif
CV_IPP_RUN_FAST(ipp_copyMakeBorder(src, dst, top, bottom, left, right, borderType, value))
if( borderType != BORDER_CONSTANT )
copyMakeBorder_8u( src.ptr(), src.step, src.size(),
+62 -47
View File
@@ -497,6 +497,65 @@ static bool ocl_polarToCart( InputArray _mag, InputArray _angle,
#endif
#ifdef HAVE_IPP
static bool ipp_polarToCart(Mat &mag, Mat &angle, Mat &x, Mat &y)
{
CV_INSTRUMENT_REGION_IPP()
int depth = angle.depth();
if(depth != CV_32F && depth != CV_64F)
return false;
if(angle.dims <= 2)
{
int len = (int)(angle.cols*angle.channels());
if(depth == CV_32F)
{
for (int h = 0; h < angle.rows; h++)
{
if(CV_INSTRUMENT_FUN_IPP(ippsPolarToCart_32f, (const float*)mag.ptr(h), (const float*)angle.ptr(h), (float*)x.ptr(h), (float*)y.ptr(h), len) < 0)
return false;
}
}
else
{
for (int h = 0; h < angle.rows; h++)
{
if(CV_INSTRUMENT_FUN_IPP(ippsPolarToCart_64f, (const double*)mag.ptr(h), (const double*)angle.ptr(h), (double*)x.ptr(h), (double*)y.ptr(h), len) < 0)
return false;
}
}
return true;
}
else
{
const Mat *arrays[] = {&mag, &angle, &x, &y, NULL};
uchar *ptrs[4] = {NULL};
NAryMatIterator it(arrays, ptrs);
int len = (int)(it.size*angle.channels());
if(depth == CV_32F)
{
for (size_t i = 0; i < it.nplanes; i++, ++it)
{
if(CV_INSTRUMENT_FUN_IPP(ippsPolarToCart_32f, (const float*)ptrs[0], (const float*)ptrs[1], (float*)ptrs[2], (float*)ptrs[3], len) < 0)
return false;
}
}
else
{
for (size_t i = 0; i < it.nplanes; i++, ++it)
{
if(CV_INSTRUMENT_FUN_IPP(ippsPolarToCart_64f, (const double*)ptrs[0], (const double*)ptrs[1], (double*)ptrs[2], (double*)ptrs[3], len) < 0)
return false;
}
}
return true;
}
}
#endif
void polarToCart( InputArray src1, InputArray src2,
OutputArray dst1, OutputArray dst2, bool angleInDegrees )
{
@@ -514,28 +573,7 @@ void polarToCart( InputArray src1, InputArray src2,
dst2.create( Angle.dims, Angle.size, type );
Mat X = dst1.getMat(), Y = dst2.getMat();
#if defined(HAVE_IPP)
CV_IPP_CHECK()
{
if (Mag.isContinuous() && Angle.isContinuous() && X.isContinuous() && Y.isContinuous() && !angleInDegrees)
{
typedef IppStatus (CV_STDCALL * IppsPolarToCart)(const void * pSrcMagn, const void * pSrcPhase,
void * pDstRe, void * pDstIm, int len);
IppsPolarToCart ippsPolarToCart =
depth == CV_32F ? (IppsPolarToCart)ippsPolarToCart_32f :
depth == CV_64F ? (IppsPolarToCart)ippsPolarToCart_64f : 0;
CV_Assert(ippsPolarToCart != 0);
IppStatus status = CV_INSTRUMENT_FUN_IPP(ippsPolarToCart, Mag.ptr(), Angle.ptr(), X.ptr(), Y.ptr(), static_cast<int>(cn * X.total()));
if (status >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
}
}
#endif
CV_IPP_RUN(!angleInDegrees, ipp_polarToCart(Mag, Angle, X, Y));
const Mat* arrays[] = {&Mag, &Angle, &X, &Y, 0};
uchar* ptrs[4];
@@ -1167,11 +1205,6 @@ static bool ocl_pow(InputArray _src, double power, OutputArray _dst,
#endif
static void InvSqrt_32f(const float* src, float* dst, int n) { hal::invSqrt32f(src, dst, n); }
static void InvSqrt_64f(const double* src, double* dst, int n) { hal::invSqrt64f(src, dst, n); }
static void Sqrt_32f(const float* src, float* dst, int n) { hal::sqrt32f(src, dst, n); }
static void Sqrt_64f(const double* src, double* dst, int n) { hal::sqrt64f(src, dst, n); }
void pow( InputArray _src, double power, OutputArray _dst )
{
CV_INSTRUMENT_REGION()
@@ -1228,8 +1261,8 @@ void pow( InputArray _src, double power, OutputArray _dst )
else if( fabs(fabs(power) - 0.5) < DBL_EPSILON )
{
MathFunc func = power < 0 ?
(depth == CV_32F ? (MathFunc)InvSqrt_32f : (MathFunc)InvSqrt_64f) :
(depth == CV_32F ? (MathFunc)Sqrt_32f : (MathFunc)Sqrt_64f);
(depth == CV_32F ? (MathFunc)hal::invSqrt32f : (MathFunc)hal::invSqrt64f) :
(depth == CV_32F ? (MathFunc)hal::sqrt32f : (MathFunc)hal::sqrt64f);
for( size_t i = 0; i < it.nplanes; i++, ++it )
func( ptrs[0], ptrs[1], len );
@@ -1261,24 +1294,6 @@ void pow( InputArray _src, double power, OutputArray _dst )
{
int bsz = std::min(len - j, blockSize);
#if defined(HAVE_IPP)
CV_IPP_CHECK()
{
IppStatus status = depth == CV_32F ?
CV_INSTRUMENT_FUN_IPP(ippsPowx_32f_A21, (const float*)ptrs[0], (float)power, (float*)ptrs[1], bsz) :
CV_INSTRUMENT_FUN_IPP(ippsPowx_64f_A50, (const double*)ptrs[0], (double)power, (double*)ptrs[1], bsz);
if (status >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
ptrs[0] += bsz*esz1;
ptrs[1] += bsz*esz1;
continue;
}
setIppErrorStatus();
}
#endif
if( depth == CV_32F )
{
float* x0 = (float*)ptrs[0];
+2 -2
View File
@@ -44,7 +44,7 @@ void magnitude32f(const float* x, const float* y, float* mag, int len)
CV_INSTRUMENT_REGION()
CALL_HAL(magnitude32f, cv_hal_magnitude32f, x, y, mag, len);
CV_IPP_RUN_FAST(CV_INSTRUMENT_FUN_IPP(ippsMagnitude_32f, x, y, mag, len) >= 0);
CV_IPP_RUN(!IPP_DISABLE_PERF_MAG_SSE42 || (ipp::getIppFeatures()&ippCPUID_AVX), CV_INSTRUMENT_FUN_IPP(ippsMagnitude_32f, x, y, mag, len) >= 0);
CV_CPU_DISPATCH(magnitude32f, (x, y, mag, len),
CV_CPU_DISPATCH_MODES_ALL);
@@ -55,7 +55,7 @@ void magnitude64f(const double* x, const double* y, double* mag, int len)
CV_INSTRUMENT_REGION()
CALL_HAL(magnitude64f, cv_hal_magnitude64f, x, y, mag, len);
CV_IPP_RUN_FAST(CV_INSTRUMENT_FUN_IPP(ippsMagnitude_64f, x, y, mag, len) >= 0);
CV_IPP_RUN(!IPP_DISABLE_PERF_MAG_SSE42 || (ipp::getIppFeatures()&ippCPUID_AVX), CV_INSTRUMENT_FUN_IPP(ippsMagnitude_64f, x, y, mag, len) >= 0);
CV_CPU_DISPATCH(magnitude64f, (x, y, mag, len),
CV_CPU_DISPATCH_MODES_ALL);
+20 -67
View File
@@ -3100,18 +3100,8 @@ dotProd_(const T* src1, const T* src2, int len)
static double dotProd_8u(const uchar* src1, const uchar* src2, int len)
{
double r = 0;
#if ARITHM_USE_IPP && IPP_DISABLE_BLOCK
CV_IPP_CHECK()
{
if (0 <= CV_INSTRUMENT_FUN_IPP(ippiDotProd_8u64f_C1R, (src1, (int)(len*sizeof(src1[0])),
src2, (int)(len*sizeof(src2[0])),
ippiSize(len, 1), &r)))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return r;
}
setIppErrorStatus();
}
#if ARITHM_USE_IPP
CV_IPP_RUN_FAST(CV_INSTRUMENT_FUN_IPP(ippiDotProd_8u64f_C1R, src1, len*sizeof(uchar), src2, len*sizeof(uchar), ippiSize(len, 1), &r) >= 0, r);
#endif
int i = 0;
@@ -3298,51 +3288,27 @@ static double dotProd_8s(const schar* src1, const schar* src2, int len)
static double dotProd_16u(const ushort* src1, const ushort* src2, int len)
{
#if (ARITHM_USE_IPP == 1)
CV_IPP_CHECK()
{
double r = 0;
if (0 <= CV_INSTRUMENT_FUN_IPP(ippiDotProd_16u64f_C1R, src1, (int)(len*sizeof(src1[0])), src2, (int)(len*sizeof(src2[0])), ippiSize(len, 1), &r))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return r;
}
setIppErrorStatus();
}
#if ARITHM_USE_IPP
double r = 0;
CV_IPP_RUN_FAST(CV_INSTRUMENT_FUN_IPP(ippiDotProd_16u64f_C1R, src1, len*sizeof(ushort), src2, len*sizeof(ushort), ippiSize(len, 1), &r) >= 0, r);
#endif
return dotProd_(src1, src2, len);
}
static double dotProd_16s(const short* src1, const short* src2, int len)
{
#if (ARITHM_USE_IPP == 1) && (IPP_VERSION_X100 != 900) // bug in IPP 9.0.0
CV_IPP_CHECK()
{
double r = 0;
if (0 <= CV_INSTRUMENT_FUN_IPP(ippiDotProd_16s64f_C1R, src1, (int)(len*sizeof(src1[0])), src2, (int)(len*sizeof(src2[0])), ippiSize(len, 1), &r))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return r;
}
setIppErrorStatus();
}
#if ARITHM_USE_IPP && (IPP_VERSION_X100 != 900) // bug in IPP 9.0.0
double r = 0;
CV_IPP_RUN_FAST(CV_INSTRUMENT_FUN_IPP(ippiDotProd_16s64f_C1R, src1, len*sizeof(short), src2, len*sizeof(short), ippiSize(len, 1), &r) >= 0, r);
#endif
return dotProd_(src1, src2, len);
}
static double dotProd_32s(const int* src1, const int* src2, int len)
{
#if (ARITHM_USE_IPP == 1)
CV_IPP_CHECK()
{
double r = 0;
if (0 <= CV_INSTRUMENT_FUN_IPP(ippiDotProd_32s64f_C1R, src1, (int)(len*sizeof(src1[0])), src2, (int)(len*sizeof(src2[0])), ippiSize(len, 1), &r))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return r;
}
setIppErrorStatus();
}
#if ARITHM_USE_IPP
double r = 0;
CV_IPP_RUN_FAST(CV_INSTRUMENT_FUN_IPP(ippiDotProd_32s64f_C1R, src1, len*sizeof(int), src2, len*sizeof(int), ippiSize(len, 1), &r) >= 0, r);
#endif
return dotProd_(src1, src2, len);
}
@@ -3350,19 +3316,13 @@ static double dotProd_32s(const int* src1, const int* src2, int len)
static double dotProd_32f(const float* src1, const float* src2, int len)
{
double r = 0.0;
#if ARITHM_USE_IPP
CV_IPP_RUN_FAST(CV_INSTRUMENT_FUN_IPP(ippiDotProd_32f64f_C1R, src1, len*sizeof(float), src2, len*sizeof(float), ippiSize(len, 1), &r, ippAlgHintFast) >= 0, r);
#endif
int i = 0;
#if (ARITHM_USE_IPP == 1)
CV_IPP_CHECK()
{
if (0 <= CV_INSTRUMENT_FUN_IPP(ippsDotProd_32f64f, src1, src2, len, &r))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return r;
}
setIppErrorStatus();
}
#elif CV_NEON
#if CV_NEON
int len0 = len & -4, blockSize0 = (1 << 13), blockSize;
float32x4_t v_zero = vdupq_n_f32(0.0f);
CV_DECL_ALIGNED(16) float buf[4];
@@ -3389,18 +3349,11 @@ static double dotProd_32f(const float* src1, const float* src2, int len)
static double dotProd_64f(const double* src1, const double* src2, int len)
{
#if (ARITHM_USE_IPP == 1)
CV_IPP_CHECK()
{
double r = 0;
if (0 <= CV_INSTRUMENT_FUN_IPP(ippsDotProd_64f, src1, src2, len, &r))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return r;
}
setIppErrorStatus();
}
#if ARITHM_USE_IPP
double r = 0;
CV_IPP_RUN_FAST(CV_INSTRUMENT_FUN_IPP(ippsDotProd_64f, src1, src2, len, &r) >= 0, r);
#endif
return dotProd_(src1, src2, len);
}
+376 -328
View File
@@ -1309,30 +1309,51 @@ static bool ipp_countNonZero( Mat &src, int &res )
{
CV_INSTRUMENT_REGION_IPP()
Ipp32s count = 0;
IppStatus status = ippStsNoErr;
Ipp32s count = 0;
int depth = src.depth();
int type = src.type(), depth = CV_MAT_DEPTH(type);
IppiSize roiSize = { src.cols, src.rows };
Ipp32s srcstep = (Ipp32s)src.step;
if (src.isContinuous())
if(src.dims <= 2)
{
roiSize.width = (Ipp32s)src.total();
roiSize.height = 1;
srcstep = (Ipp32s)src.total() * CV_ELEM_SIZE(type);
IppStatus status;
IppiSize size = {src.cols*src.channels(), src.rows};
if(depth == CV_8U)
status = CV_INSTRUMENT_FUN_IPP(ippiCountInRange_8u_C1R, (const Ipp8u *)src.ptr(), (int)src.step, size, &count, 0, 0);
else if(depth == CV_32F)
status = CV_INSTRUMENT_FUN_IPP(ippiCountInRange_32f_C1R, (const Ipp32f *)src.ptr(), (int)src.step, size, &count, 0, 0);
else
return false;
if(status < 0)
return false;
res = size.width*size.height - count;
}
else
{
IppStatus status;
const Mat *arrays[] = {&src, NULL};
uchar *ptrs[1] = {NULL};
NAryMatIterator it(arrays, ptrs);
IppiSize size = {(int)it.size*src.channels(), 1};
for (size_t i = 0; i < it.nplanes; i++, ++it)
{
if(depth == CV_8U)
status = CV_INSTRUMENT_FUN_IPP(ippiCountInRange_8u_C1R, (const Ipp8u *)src.ptr(), (int)src.step, size, &count, 0, 0);
else if(depth == CV_32F)
status = CV_INSTRUMENT_FUN_IPP(ippiCountInRange_32f_C1R, (const Ipp32f *)src.ptr(), (int)src.step, size, &count, 0, 0);
else
return false;
if(status < 0)
return false;
res += (size.width*size.height - count);
}
}
if (depth == CV_8U)
status = CV_INSTRUMENT_FUN_IPP(ippiCountInRange_8u_C1R, (const Ipp8u *)src.data, srcstep, roiSize, &count, 0, 0);
else if (depth == CV_32F)
status = CV_INSTRUMENT_FUN_IPP(ippiCountInRange_32f_C1R, (const Ipp32f *)src.data, srcstep, roiSize, &count, 0, 0);
if (status >= 0)
{
res = ((Ipp32s)src.total() - count);
return true;
}
return false;
return true;
}
}
#endif
@@ -1356,7 +1377,7 @@ int cv::countNonZero( InputArray _src )
#endif
Mat src = _src.getMat();
CV_IPP_RUN(0 && (_src.dims() <= 2 || _src.isContinuous()), ipp_countNonZero(src, res), res);
CV_IPP_RUN_FAST(ipp_countNonZero(src, res), res);
CountNonZeroFunc func = getCountNonZeroTab(src.depth());
CV_Assert( func != 0 );
@@ -2373,109 +2394,273 @@ static bool openvx_minMaxIdx(Mat &src, double* minVal, double* maxVal, int* minI
#endif
#ifdef HAVE_IPP
static bool ipp_minMaxIdx( Mat &src, double* minVal, double* maxVal, int* minIdx, int* maxIdx, Mat &mask)
static IppStatus ipp_minMaxIndex_wrap(const void* pSrc, int srcStep, IppiSize size, IppDataType dataType,
float* pMinVal, float* pMaxVal, IppiPoint* pMinIndex, IppiPoint* pMaxIndex, const Ipp8u*, int)
{
switch(dataType)
{
case ipp8u: return CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_8u_C1R, (const Ipp8u*)pSrc, srcStep, size, pMinVal, pMaxVal, pMinIndex, pMaxIndex);
case ipp16u: return CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_16u_C1R, (const Ipp16u*)pSrc, srcStep, size, pMinVal, pMaxVal, pMinIndex, pMaxIndex);
case ipp32f: return CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_32f_C1R, (const Ipp32f*)pSrc, srcStep, size, pMinVal, pMaxVal, pMinIndex, pMaxIndex);
default: return ippStsDataTypeErr;
}
}
static IppStatus ipp_minMaxIndexMask_wrap(const void* pSrc, int srcStep, IppiSize size, IppDataType dataType,
float* pMinVal, float* pMaxVal, IppiPoint* pMinIndex, IppiPoint* pMaxIndex, const Ipp8u* pMask, int maskStep)
{
switch(dataType)
{
case ipp8u: return CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_8u_C1MR, (const Ipp8u*)pSrc, srcStep, pMask, maskStep, size, pMinVal, pMaxVal, pMinIndex, pMaxIndex);
case ipp16u: return CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_16u_C1MR, (const Ipp16u*)pSrc, srcStep, pMask, maskStep, size, pMinVal, pMaxVal, pMinIndex, pMaxIndex);
case ipp32f: return CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_32f_C1MR, (const Ipp32f*)pSrc, srcStep, pMask, maskStep, size, pMinVal, pMaxVal, pMinIndex, pMaxIndex);
default: return ippStsDataTypeErr;
}
}
static IppStatus ipp_minMax_wrap(const void* pSrc, int srcStep, IppiSize size, IppDataType dataType,
float* pMinVal, float* pMaxVal, IppiPoint*, IppiPoint*, const Ipp8u*, int)
{
IppStatus status;
switch(dataType)
{
#if IPP_VERSION_X100 > 201701 // wrong min values
case ipp8u:
{
Ipp8u val[2];
status = CV_INSTRUMENT_FUN_IPP(ippiMinMax_8u_C1R, (const Ipp8u*)pSrc, srcStep, size, &val[0], &val[1]);
*pMinVal = val[0];
*pMaxVal = val[1];
return status;
}
#endif
case ipp16u:
{
Ipp16u val[2];
status = CV_INSTRUMENT_FUN_IPP(ippiMinMax_16u_C1R, (const Ipp16u*)pSrc, srcStep, size, &val[0], &val[1]);
*pMinVal = val[0];
*pMaxVal = val[1];
return status;
}
case ipp16s:
{
Ipp16s val[2];
status = CV_INSTRUMENT_FUN_IPP(ippiMinMax_16s_C1R, (const Ipp16s*)pSrc, srcStep, size, &val[0], &val[1]);
*pMinVal = val[0];
*pMaxVal = val[1];
return status;
}
case ipp32f: return CV_INSTRUMENT_FUN_IPP(ippiMinMax_32f_C1R, (const Ipp32f*)pSrc, srcStep, size, pMinVal, pMaxVal);
default: return ipp_minMaxIndex_wrap(pSrc, srcStep, size, dataType, pMinVal, pMaxVal, NULL, NULL, NULL, 0);
}
}
static IppStatus ipp_minIdx_wrap(const void* pSrc, int srcStep, IppiSize size, IppDataType dataType,
float* pMinVal, float*, IppiPoint* pMinIndex, IppiPoint*, const Ipp8u*, int)
{
IppStatus status;
switch(dataType)
{
case ipp8u:
{
Ipp8u val;
status = CV_INSTRUMENT_FUN_IPP(ippiMinIndx_8u_C1R, (const Ipp8u*)pSrc, srcStep, size, &val, &pMinIndex->x, &pMinIndex->y);
*pMinVal = val;
return status;
}
case ipp16u:
{
Ipp16u val;
status = CV_INSTRUMENT_FUN_IPP(ippiMinIndx_16u_C1R, (const Ipp16u*)pSrc, srcStep, size, &val, &pMinIndex->x, &pMinIndex->y);
*pMinVal = val;
return status;
}
case ipp16s:
{
Ipp16s val;
status = CV_INSTRUMENT_FUN_IPP(ippiMinIndx_16s_C1R, (const Ipp16s*)pSrc, srcStep, size, &val, &pMinIndex->x, &pMinIndex->y);
*pMinVal = val;
return status;
}
case ipp32f: return CV_INSTRUMENT_FUN_IPP(ippiMinIndx_32f_C1R, (const Ipp32f*)pSrc, srcStep, size, pMinVal, &pMinIndex->x, &pMinIndex->y);
default: return ipp_minMaxIndex_wrap(pSrc, srcStep, size, dataType, pMinVal, NULL, pMinIndex, NULL, NULL, 0);
}
}
static IppStatus ipp_maxIdx_wrap(const void* pSrc, int srcStep, IppiSize size, IppDataType dataType,
float*, float* pMaxVal, IppiPoint*, IppiPoint* pMaxIndex, const Ipp8u*, int)
{
IppStatus status;
switch(dataType)
{
case ipp8u:
{
Ipp8u val;
status = CV_INSTRUMENT_FUN_IPP(ippiMaxIndx_8u_C1R, (const Ipp8u*)pSrc, srcStep, size, &val, &pMaxIndex->x, &pMaxIndex->y);
*pMaxVal = val;
return status;
}
case ipp16u:
{
Ipp16u val;
status = CV_INSTRUMENT_FUN_IPP(ippiMaxIndx_16u_C1R, (const Ipp16u*)pSrc, srcStep, size, &val, &pMaxIndex->x, &pMaxIndex->y);
*pMaxVal = val;
return status;
}
case ipp16s:
{
Ipp16s val;
status = CV_INSTRUMENT_FUN_IPP(ippiMaxIndx_16s_C1R, (const Ipp16s*)pSrc, srcStep, size, &val, &pMaxIndex->x, &pMaxIndex->y);
*pMaxVal = val;
return status;
}
case ipp32f: return CV_INSTRUMENT_FUN_IPP(ippiMaxIndx_32f_C1R, (const Ipp32f*)pSrc, srcStep, size, pMaxVal, &pMaxIndex->x, &pMaxIndex->y);
default: return ipp_minMaxIndex_wrap(pSrc, srcStep, size, dataType, NULL, pMaxVal, NULL, pMaxIndex, NULL, 0);
}
}
typedef IppStatus (*IppMinMaxSelector)(const void* pSrc, int srcStep, IppiSize size, IppDataType dataType,
float* pMinVal, float* pMaxVal, IppiPoint* pMinIndex, IppiPoint* pMaxIndex, const Ipp8u* pMask, int maskStep);
static bool ipp_minMaxIdx(Mat &src, double* _minVal, double* _maxVal, int* _minIdx, int* _maxIdx, Mat &mask)
{
#if IPP_VERSION_X100 >= 700
CV_INSTRUMENT_REGION_IPP()
#if IPP_VERSION_X100 >= 700
int type = src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
size_t total_size = src.total();
int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0;
if( src.dims == 2 || (src.isContinuous() && mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) )
IppStatus status;
IppDataType dataType = ippiGetDataType(src.depth());
float minVal = 0;
float maxVal = 0;
IppiPoint minIdx = {-1, -1};
IppiPoint maxIdx = {-1, -1};
float *pMinVal = (_minVal)?&minVal:NULL;
float *pMaxVal = (_maxVal)?&maxVal:NULL;
IppiPoint *pMinIdx = (_minIdx)?&minIdx:NULL;
IppiPoint *pMaxIdx = (_maxIdx)?&maxIdx:NULL;
IppMinMaxSelector ippMinMaxFun = ipp_minMaxIndexMask_wrap;
if(mask.empty())
{
IppiSize sz = { cols * cn, rows };
if(_maxVal && _maxIdx && !_minVal && !_minIdx)
ippMinMaxFun = ipp_maxIdx_wrap;
else if(!_maxVal && !_maxIdx && _minVal && _minIdx)
ippMinMaxFun = ipp_minIdx_wrap;
else if(_maxVal && !_maxIdx && _minVal && !_minIdx)
ippMinMaxFun = ipp_minMax_wrap;
else
ippMinMaxFun = ipp_minMaxIndex_wrap;
}
if( !mask.empty() )
if(src.dims <= 2)
{
IppiSize size = ippiSize(src.size());
size.width *= src.channels();
status = ippMinMaxFun(src.ptr(), (int)src.step, size, dataType, pMinVal, pMaxVal, pMinIdx, pMaxIdx, (Ipp8u*)mask.ptr(), (int)mask.step);
if(status < 0 || status == ippStsNoOperation)
return false;
if(_minVal)
*_minVal = minVal;
if(_maxVal)
*_maxVal = maxVal;
if(_minIdx)
{
typedef IppStatus (CV_STDCALL* ippiMaskMinMaxIndxFuncC1)(const void *, int, const void *, int,
IppiSize, Ipp32f *, Ipp32f *, IppiPoint *, IppiPoint *);
CV_SUPPRESS_DEPRECATED_START
ippiMaskMinMaxIndxFuncC1 ippiMinMaxIndx_C1MR =
type == CV_8UC1 ? (ippiMaskMinMaxIndxFuncC1)ippiMinMaxIndx_8u_C1MR :
#if IPP_VERSION_X100 < 900
type == CV_8SC1 ? (ippiMaskMinMaxIndxFuncC1)ippiMinMaxIndx_8s_C1MR :
#endif
type == CV_16UC1 ? (ippiMaskMinMaxIndxFuncC1)ippiMinMaxIndx_16u_C1MR :
type == CV_32FC1 ? (ippiMaskMinMaxIndxFuncC1)ippiMinMaxIndx_32f_C1MR : 0;
CV_SUPPRESS_DEPRECATED_END
if( ippiMinMaxIndx_C1MR )
if(!mask.empty() && !minIdx.y && !minIdx.x)
{
Ipp32f min, max;
IppiPoint minp, maxp;
if( CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_C1MR, src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, &min, &max, &minp, &maxp) >= 0 )
{
if( minVal )
*minVal = (double)min;
if( maxVal )
*maxVal = (double)max;
if( !minp.x && !minp.y && !maxp.x && !maxp.y && !mask.ptr()[0] )
minp.x = maxp.x = -1;
if( minIdx )
{
size_t minidx = minp.y * cols + minp.x + 1;
ofs2idx(src, minidx, minIdx);
}
if( maxIdx )
{
size_t maxidx = maxp.y * cols + maxp.x + 1;
ofs2idx(src, maxidx, maxIdx);
}
return true;
}
_minIdx[0] = -1;
_minIdx[1] = -1;
}
else
{
_minIdx[0] = minIdx.y;
_minIdx[1] = minIdx.x;
}
}
else
if(_maxIdx)
{
typedef IppStatus (CV_STDCALL* ippiMinMaxIndxFuncC1)(const void *, int, IppiSize, Ipp32f *, Ipp32f *, IppiPoint *, IppiPoint *);
CV_SUPPRESS_DEPRECATED_START
ippiMinMaxIndxFuncC1 ippiMinMaxIndx_C1R =
#if IPP_VERSION_X100 != 900 // bug in 9.0.0 avx2 optimization
depth == CV_8U ? (ippiMinMaxIndxFuncC1)ippiMinMaxIndx_8u_C1R :
#endif
#if IPP_VERSION_X100 < 900
depth == CV_8S ? (ippiMinMaxIndxFuncC1)ippiMinMaxIndx_8s_C1R :
#endif
depth == CV_16U ? (ippiMinMaxIndxFuncC1)ippiMinMaxIndx_16u_C1R :
#if IPP_DISABLE_BLOCK && !((defined _MSC_VER && defined _M_IX86) || defined __i386__)
// See bug #4955: the function fails with SEGFAULT when the source matrix contains NANs
// IPPICV version is 9.0.1.
depth == CV_32F ? (ippiMinMaxIndxFuncC1)ippiMinMaxIndx_32f_C1R :
#endif
0;
CV_SUPPRESS_DEPRECATED_END
if( ippiMinMaxIndx_C1R )
if(!mask.empty() && !maxIdx.y && !maxIdx.x)
{
Ipp32f min, max;
IppiPoint minp, maxp;
if( CV_INSTRUMENT_FUN_IPP(ippiMinMaxIndx_C1R, src.ptr(), (int)src.step[0], sz, &min, &max, &minp, &maxp) >= 0 )
{
if( minVal )
*minVal = (double)min;
if( maxVal )
*maxVal = (double)max;
if( minIdx )
{
size_t minidx = minp.y * cols + minp.x + 1;
ofs2idx(src, minidx, minIdx);
}
if( maxIdx )
{
size_t maxidx = maxp.y * cols + maxp.x + 1;
ofs2idx(src, maxidx, maxIdx);
}
return true;
}
_maxIdx[0] = -1;
_maxIdx[1] = -1;
}
else
{
_maxIdx[0] = maxIdx.y;
_maxIdx[1] = maxIdx.x;
}
}
}
else
{
const Mat *arrays[] = {&src, mask.empty()?NULL:&mask, NULL};
uchar *ptrs[3] = {NULL};
NAryMatIterator it(arrays, ptrs);
IppiSize size = ippiSize(it.size*src.channels(), 1);
int srcStep = (int)(size.width*src.elemSize1());
int maskStep = size.width;
size_t idxPos = 1;
size_t minIdxAll = 0;
size_t maxIdxAll = 0;
float minValAll = IPP_MAXABS_32F;
float maxValAll = -IPP_MAXABS_32F;
for(size_t i = 0; i < it.nplanes; i++, ++it, idxPos += size.width)
{
status = ippMinMaxFun(ptrs[0], srcStep, size, dataType, pMinVal, pMaxVal, pMinIdx, pMaxIdx, ptrs[1], maskStep);
if(status < 0)
return false;
#if IPP_VERSION_X100 > 201701
// Zero-mask check, function should return ippStsNoOperation warning
if(status == ippStsNoOperation)
continue;
#else
// Crude zero-mask check, waiting for fix in IPP function
if(ptrs[1])
{
Mat localMask(Size(size.width, 1), CV_8U, ptrs[1], maskStep);
if(!cv::countNonZero(localMask))
continue;
}
#endif
if(_minVal && minVal < minValAll)
{
minValAll = minVal;
minIdxAll = idxPos+minIdx.x;
}
if(_maxVal && maxVal > maxValAll)
{
maxValAll = maxVal;
maxIdxAll = idxPos+maxIdx.x;
}
}
if(!src.empty() && mask.empty())
{
if(minIdxAll == 0)
minIdxAll = 1;
if(maxValAll == 0)
maxValAll = 1;
}
if(_minVal)
*_minVal = minValAll;
if(_maxVal)
*_maxVal = maxValAll;
if(_minIdx)
ofs2idx(src, minIdxAll, _minIdx);
if(_maxIdx)
ofs2idx(src, maxIdxAll, _maxIdx);
}
return true;
#else
CV_UNUSED(src); CV_UNUSED(minVal); CV_UNUSED(maxVal); CV_UNUSED(minIdx); CV_UNUSED(maxIdx); CV_UNUSED(mask);
return false;
#endif
}
#endif
@@ -2499,7 +2684,7 @@ void cv::minMaxIdx(InputArray _src, double* minVal,
CV_OVX_RUN(true,
openvx_minMaxIdx(src, minVal, maxVal, minIdx, maxIdx, mask))
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_minMaxIdx(src, minVal, maxVal, minIdx, maxIdx, mask))
CV_IPP_RUN_FAST(ipp_minMaxIdx(src, minVal, maxVal, minIdx, maxIdx, mask))
MinMaxIdxFunc func = getMinmaxTab(depth);
CV_Assert( func != 0 );
@@ -2837,42 +3022,31 @@ static bool ipp_norm(Mat &src, int normType, Mat &mask, double &result)
CV_INSTRUMENT_REGION_IPP()
#if IPP_VERSION_X100 >= 700
int cn = src.channels();
size_t total_size = src.total();
int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0;
if( (src.dims == 2 || (src.isContinuous() && mask.isContinuous()))
&& cols > 0 && (size_t)rows*cols == total_size
&& (normType == NORM_INF || normType == NORM_L1 ||
normType == NORM_L2 || normType == NORM_L2SQR) )
&& cols > 0 && (size_t)rows*cols == total_size )
{
IppiSize sz = { cols, rows };
int type = src.type();
if( !mask.empty() )
{
IppiSize sz = { cols, rows };
int type = src.type();
typedef IppStatus (CV_STDCALL* ippiMaskNormFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *);
ippiMaskNormFuncC1 ippiNorm_C1MR =
normType == NORM_INF ?
(type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_8u_C1MR :
#if IPP_VERSION_X100 < 900
type == CV_8SC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_8s_C1MR :
#endif
// type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_16u_C1MR :
type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_32f_C1MR :
0) :
normType == NORM_L1 ?
(type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_8u_C1MR :
#if IPP_VERSION_X100 < 900
type == CV_8SC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_8s_C1MR :
#endif
type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_32f_C1MR :
0) :
normType == NORM_L2 || normType == NORM_L2SQR ?
(type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_8u_C1MR :
#if IPP_VERSION_X100 < 900
type == CV_8SC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_8s_C1MR :
#endif
type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_32f_C1MR :
0) : 0;
@@ -2885,39 +3059,29 @@ static bool ipp_norm(Mat &src, int normType, Mat &mask, double &result)
return true;
}
}
#if IPP_DISABLE_BLOCK
typedef IppStatus (CV_STDCALL* ippiMaskNormFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *);
ippiMaskNormFuncC3 ippiNorm_C3CMR =
normType == NORM_INF ?
(type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_8u_C3CMR :
#if IPP_VERSION_X100 < 900
type == CV_8SC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_8s_C3CMR :
#endif
type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_16u_C3CMR :
type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_32f_C3CMR :
0) :
normType == NORM_L1 ?
(type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_8u_C3CMR :
#if IPP_VERSION_X100 < 900
type == CV_8SC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_8s_C3CMR :
#endif
type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_16u_C3CMR :
type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_32f_C3CMR :
0) :
normType == NORM_L2 || normType == NORM_L2SQR ?
(type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_8u_C3CMR :
#if IPP_VERSION_X100 < 900
type == CV_8SC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_8s_C3CMR :
#endif
type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_16u_C3CMR :
type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_32f_C3CMR :
0) : 0;
if( ippiNorm_C3CMR )
{
Ipp64f norm1, norm2, norm3;
if( CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, (src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 1, &norm1)) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, (src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 2, &norm2)) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, (src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 3, &norm3)) >= 0)
if( CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 1, &norm1) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 2, &norm2) >= 0 &&
CV_INSTRUMENT_FUN_IPP(ippiNorm_C3CMR, src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 3, &norm3) >= 0)
{
Ipp64f norm =
normType == NORM_INF ? std::max(std::max(norm1, norm2), norm3) :
@@ -2928,81 +3092,46 @@ static bool ipp_norm(Mat &src, int normType, Mat &mask, double &result)
return true;
}
}
#endif
}
else
{
IppiSize sz = { cols*src.channels(), rows };
int type = src.depth();
typedef IppStatus (CV_STDCALL* ippiNormFuncHint)(const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint);
typedef IppStatus (CV_STDCALL* ippiNormFuncNoHint)(const void *, int, IppiSize, Ipp64f *);
ippiNormFuncHint ippiNormHint =
normType == NORM_L1 ?
(type == CV_32FC1 ? (ippiNormFuncHint)ippiNorm_L1_32f_C1R :
type == CV_32FC3 ? (ippiNormFuncHint)ippiNorm_L1_32f_C3R :
type == CV_32FC4 ? (ippiNormFuncHint)ippiNorm_L1_32f_C4R :
0) :
normType == NORM_L2 || normType == NORM_L2SQR ?
(type == CV_32FC1 ? (ippiNormFuncHint)ippiNorm_L2_32f_C1R :
type == CV_32FC3 ? (ippiNormFuncHint)ippiNorm_L2_32f_C3R :
type == CV_32FC4 ? (ippiNormFuncHint)ippiNorm_L2_32f_C4R :
0) : 0;
ippiNormFuncNoHint ippiNorm =
normType == NORM_INF ?
(type == CV_8UC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_8u_C1R :
type == CV_8UC3 ? (ippiNormFuncNoHint)ippiNorm_Inf_8u_C3R :
type == CV_8UC4 ? (ippiNormFuncNoHint)ippiNorm_Inf_8u_C4R :
type == CV_16UC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_16u_C1R :
type == CV_16UC3 ? (ippiNormFuncNoHint)ippiNorm_Inf_16u_C3R :
type == CV_16UC4 ? (ippiNormFuncNoHint)ippiNorm_Inf_16u_C4R :
type == CV_16SC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_16s_C1R :
#if (IPP_VERSION_X100 >= 810)
type == CV_16SC3 ? (ippiNormFuncNoHint)ippiNorm_Inf_16s_C3R : //Aug 2013: problem in IPP 7.1, 8.0 : -32768
type == CV_16SC4 ? (ippiNormFuncNoHint)ippiNorm_Inf_16s_C4R : //Aug 2013: problem in IPP 7.1, 8.0 : -32768
#endif
type == CV_32FC1 ? (ippiNormFuncNoHint)ippiNorm_Inf_32f_C1R :
type == CV_32FC3 ? (ippiNormFuncNoHint)ippiNorm_Inf_32f_C3R :
type == CV_32FC4 ? (ippiNormFuncNoHint)ippiNorm_Inf_32f_C4R :
0) :
normType == NORM_L1 ?
(type == CV_8UC1 ? (ippiNormFuncNoHint)ippiNorm_L1_8u_C1R :
type == CV_8UC3 ? (ippiNormFuncNoHint)ippiNorm_L1_8u_C3R :
type == CV_8UC4 ? (ippiNormFuncNoHint)ippiNorm_L1_8u_C4R :
type == CV_16UC1 ? (ippiNormFuncNoHint)ippiNorm_L1_16u_C1R :
type == CV_16UC3 ? (ippiNormFuncNoHint)ippiNorm_L1_16u_C3R :
type == CV_16UC4 ? (ippiNormFuncNoHint)ippiNorm_L1_16u_C4R :
type == CV_16SC1 ? (ippiNormFuncNoHint)ippiNorm_L1_16s_C1R :
type == CV_16SC3 ? (ippiNormFuncNoHint)ippiNorm_L1_16s_C3R :
type == CV_16SC4 ? (ippiNormFuncNoHint)ippiNorm_L1_16s_C4R :
0) :
normType == NORM_L2 || normType == NORM_L2SQR ?
(type == CV_8UC1 ? (ippiNormFuncNoHint)ippiNorm_L2_8u_C1R :
type == CV_8UC3 ? (ippiNormFuncNoHint)ippiNorm_L2_8u_C3R :
type == CV_8UC4 ? (ippiNormFuncNoHint)ippiNorm_L2_8u_C4R :
type == CV_16UC1 ? (ippiNormFuncNoHint)ippiNorm_L2_16u_C1R :
type == CV_16UC3 ? (ippiNormFuncNoHint)ippiNorm_L2_16u_C3R :
type == CV_16UC4 ? (ippiNormFuncNoHint)ippiNorm_L2_16u_C4R :
type == CV_16SC1 ? (ippiNormFuncNoHint)ippiNorm_L2_16s_C1R :
type == CV_16SC3 ? (ippiNormFuncNoHint)ippiNorm_L2_16s_C3R :
type == CV_16SC4 ? (ippiNormFuncNoHint)ippiNorm_L2_16s_C4R :
0) : 0;
// Make sure only zero or one version of the function pointer is valid
CV_Assert(!ippiNormHint || !ippiNorm);
if( ippiNormHint || ippiNorm )
{
Ipp64f norm_array[4];
IppStatus ret = ippiNormHint ? CV_INSTRUMENT_FUN_IPP(ippiNormHint, src.ptr(), (int)src.step[0], sz, norm_array, ippAlgHintAccurate) :
CV_INSTRUMENT_FUN_IPP(ippiNorm, src.ptr(), (int)src.step[0], sz, norm_array);
Ipp64f norm;
IppStatus ret = ippiNormHint ? CV_INSTRUMENT_FUN_IPP(ippiNormHint, src.ptr(), (int)src.step[0], sz, &norm, ippAlgHintAccurate) :
CV_INSTRUMENT_FUN_IPP(ippiNorm, src.ptr(), (int)src.step[0], sz, &norm);
if( ret >= 0 )
{
Ipp64f norm = (normType == NORM_L2 || normType == NORM_L2SQR) ? norm_array[0] * norm_array[0] : norm_array[0];
for( int i = 1; i < cn; i++ )
{
norm =
normType == NORM_INF ? std::max(norm, norm_array[i]) :
normType == NORM_L1 ? norm + norm_array[i] :
normType == NORM_L2 || normType == NORM_L2SQR ? norm + norm_array[i] * norm_array[i] :
0;
}
result = (normType == NORM_L2 ? (double)std::sqrt(norm) : (double)norm);
result = (normType == NORM_L2SQR) ? norm * norm : norm;
return true;
}
}
@@ -3248,53 +3377,38 @@ static bool ipp_norm(InputArray _src1, InputArray _src2, int normType, InputArra
if( normType & CV_RELATIVE )
{
normType &= NORM_TYPE_MASK;
CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR ||
((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src1.type() == CV_8U) );
size_t total_size = src1.total();
int rows = src1.size[0], cols = rows ? (int)(total_size/rows) : 0;
if( (src1.dims == 2 || (src1.isContinuous() && src2.isContinuous() && mask.isContinuous()))
&& cols > 0 && (size_t)rows*cols == total_size
&& (normType == NORM_INF || normType == NORM_L1 ||
normType == NORM_L2 || normType == NORM_L2SQR) )
&& cols > 0 && (size_t)rows*cols == total_size )
{
IppiSize sz = { cols, rows };
int type = src1.type();
if( !mask.empty() )
{
typedef IppStatus (CV_STDCALL* ippiMaskNormRelFuncC1)(const void *, int, const void *, int, const void *, int, IppiSize, Ipp64f *);
ippiMaskNormRelFuncC1 ippiNormDiff_C1MR =
IppiSize sz = { cols, rows };
int type = src1.type();
typedef IppStatus (CV_STDCALL* ippiMaskNormDiffFuncC1)(const void *, int, const void *, int, const void *, int, IppiSize, Ipp64f *);
ippiMaskNormDiffFuncC1 ippiNormRel_C1MR =
normType == NORM_INF ?
(type == CV_8UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_Inf_8u_C1MR :
#if IPP_VERSION_X100 < 900
#ifndef __APPLE__
type == CV_8SC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_Inf_8s_C1MR :
#endif
#endif
type == CV_16UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_Inf_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_Inf_32f_C1MR :
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_Inf_8u_C1MR :
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_Inf_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_Inf_32f_C1MR :
0) :
normType == NORM_L1 ?
(type == CV_8UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L1_8u_C1MR :
#if IPP_VERSION_X100 < 900
#ifndef __APPLE__
type == CV_8SC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L1_8s_C1MR :
#endif
#endif
type == CV_16UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L1_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L1_32f_C1MR :
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L1_8u_C1MR :
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L1_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L1_32f_C1MR :
0) :
normType == NORM_L2 || normType == NORM_L2SQR ?
(type == CV_8UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L2_8u_C1MR :
#if IPP_VERSION_X100 < 900
type == CV_8SC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L2_8s_C1MR :
#endif
type == CV_16UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L2_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L2_32f_C1MR :
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L2_8u_C1MR :
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L2_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormRel_L2_32f_C1MR :
0) : 0;
if( ippiNormDiff_C1MR )
if( ippiNormRel_C1MR )
{
Ipp64f norm;
if( CV_INSTRUMENT_FUN_IPP(ippiNormDiff_C1MR, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], mask.ptr(), (int)mask.step[0], sz, &norm) >= 0 )
if( CV_INSTRUMENT_FUN_IPP(ippiNormRel_C1MR, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], mask.ptr(), (int)mask.step[0], sz, &norm) >= 0 )
{
result = (normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm);
return true;
@@ -3303,47 +3417,43 @@ static bool ipp_norm(InputArray _src1, InputArray _src2, int normType, InputArra
}
else
{
typedef IppStatus (CV_STDCALL* ippiNormRelFuncNoHint)(const void *, int, const void *, int, IppiSize, Ipp64f *);
IppiSize sz = { cols*src1.channels(), rows };
int type = src1.depth();
typedef IppStatus (CV_STDCALL* ippiNormRelFuncHint)(const void *, int, const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint);
ippiNormRelFuncNoHint ippiNormDiff =
typedef IppStatus (CV_STDCALL* ippiNormRelFuncNoHint)(const void *, int, const void *, int, IppiSize, Ipp64f *);
ippiNormRelFuncHint ippiNormRelHint =
normType == NORM_L1 ?
(type == CV_32F ? (ippiNormRelFuncHint)ippiNormRel_L1_32f_C1R :
0) :
normType == NORM_L2 || normType == NORM_L2SQR ?
(type == CV_32F ? (ippiNormRelFuncHint)ippiNormRel_L2_32f_C1R :
0) : 0;
ippiNormRelFuncNoHint ippiNormRel =
normType == NORM_INF ?
(type == CV_8UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_8u_C1R :
type == CV_16UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_16u_C1R :
type == CV_16SC1 ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_16s_C1R :
type == CV_32FC1 ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_32f_C1R :
(type == CV_8U ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_8u_C1R :
type == CV_16U ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_16u_C1R :
type == CV_16S ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_16s_C1R :
type == CV_32F ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_32f_C1R :
0) :
normType == NORM_L1 ?
(type == CV_8UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L1_8u_C1R :
type == CV_16UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L1_16u_C1R :
type == CV_16SC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L1_16s_C1R :
(type == CV_8U ? (ippiNormRelFuncNoHint)ippiNormRel_L1_8u_C1R :
type == CV_16U ? (ippiNormRelFuncNoHint)ippiNormRel_L1_16u_C1R :
type == CV_16S ? (ippiNormRelFuncNoHint)ippiNormRel_L1_16s_C1R :
0) :
normType == NORM_L2 || normType == NORM_L2SQR ?
(type == CV_8UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L2_8u_C1R :
type == CV_16UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L2_16u_C1R :
type == CV_16SC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L2_16s_C1R :
(type == CV_8U ? (ippiNormRelFuncNoHint)ippiNormRel_L2_8u_C1R :
type == CV_16U ? (ippiNormRelFuncNoHint)ippiNormRel_L2_16u_C1R :
type == CV_16S ? (ippiNormRelFuncNoHint)ippiNormRel_L2_16s_C1R :
0) : 0;
ippiNormRelFuncHint ippiNormDiffHint =
normType == NORM_L1 ?
(type == CV_32FC1 ? (ippiNormRelFuncHint)ippiNormRel_L1_32f_C1R :
0) :
normType == NORM_L2 || normType == NORM_L2SQR ?
(type == CV_32FC1 ? (ippiNormRelFuncHint)ippiNormRel_L2_32f_C1R :
0) : 0;
if (ippiNormDiff)
if( ippiNormRelHint || ippiNormRel )
{
Ipp64f norm;
if( CV_INSTRUMENT_FUN_IPP(ippiNormDiff, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm) >= 0 )
IppStatus ret = ippiNormRelHint ? CV_INSTRUMENT_FUN_IPP(ippiNormRelHint, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm, ippAlgHintAccurate) :
CV_INSTRUMENT_FUN_IPP(ippiNormRel, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm);
if( ret >= 0 )
{
result = (double)norm;
return true;
}
}
if (ippiNormDiffHint)
{
Ipp64f norm;
if( CV_INSTRUMENT_FUN_IPP(ippiNormDiffHint, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm, ippAlgHintAccurate) >= 0 )
{
result = (double)norm;
result = (normType == NORM_L2SQR) ? norm * norm : norm;
return true;
}
}
@@ -3352,47 +3462,32 @@ static bool ipp_norm(InputArray _src1, InputArray _src2, int normType, InputArra
return false;
}
normType &= 7;
CV_Assert( normType == NORM_INF || normType == NORM_L1 ||
normType == NORM_L2 || normType == NORM_L2SQR ||
((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src1.type() == CV_8U) );
normType &= NORM_TYPE_MASK;
size_t total_size = src1.total();
int rows = src1.size[0], cols = rows ? (int)(total_size/rows) : 0;
if( (src1.dims == 2 || (src1.isContinuous() && src2.isContinuous() && mask.isContinuous()))
&& cols > 0 && (size_t)rows*cols == total_size
&& (normType == NORM_INF || normType == NORM_L1 ||
normType == NORM_L2 || normType == NORM_L2SQR) )
&& cols > 0 && (size_t)rows*cols == total_size )
{
IppiSize sz = { cols, rows };
int type = src1.type();
if( !mask.empty() )
{
IppiSize sz = { cols, rows };
int type = src1.type();
typedef IppStatus (CV_STDCALL* ippiMaskNormDiffFuncC1)(const void *, int, const void *, int, const void *, int, IppiSize, Ipp64f *);
ippiMaskNormDiffFuncC1 ippiNormDiff_C1MR =
normType == NORM_INF ?
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_Inf_8u_C1MR :
#if IPP_VERSION_X100 < 900
type == CV_8SC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_Inf_8s_C1MR :
#endif
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_Inf_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_Inf_32f_C1MR :
0) :
normType == NORM_L1 ?
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L1_8u_C1MR :
#if IPP_VERSION_X100 < 900
#ifndef __APPLE__
type == CV_8SC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L1_8s_C1MR :
#endif
#endif
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L1_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L1_32f_C1MR :
0) :
normType == NORM_L2 || normType == NORM_L2SQR ?
(type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L2_8u_C1MR :
#if IPP_VERSION_X100 < 900
type == CV_8SC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L2_8s_C1MR :
#endif
type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L2_16u_C1MR :
type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L2_32f_C1MR :
0) : 0;
@@ -3405,30 +3500,20 @@ static bool ipp_norm(InputArray _src1, InputArray _src2, int normType, InputArra
return true;
}
}
#ifndef __APPLE__
typedef IppStatus (CV_STDCALL* ippiMaskNormDiffFuncC3)(const void *, int, const void *, int, const void *, int, IppiSize, int, Ipp64f *);
ippiMaskNormDiffFuncC3 ippiNormDiff_C3CMR =
normType == NORM_INF ?
(type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_8u_C3CMR :
#if IPP_VERSION_X100 < 900
type == CV_8SC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_8s_C3CMR :
#endif
type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_16u_C3CMR :
type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_32f_C3CMR :
0) :
normType == NORM_L1 ?
(type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L1_8u_C3CMR :
#if IPP_VERSION_X100 < 900
type == CV_8SC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L1_8s_C3CMR :
#endif
type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L1_16u_C3CMR :
type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L1_32f_C3CMR :
0) :
normType == NORM_L2 || normType == NORM_L2SQR ?
(type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_8u_C3CMR :
#if IPP_VERSION_X100 < 900
type == CV_8SC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_8s_C3CMR :
#endif
type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_16u_C3CMR :
type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_32f_C3CMR :
0) : 0;
@@ -3448,83 +3533,46 @@ static bool ipp_norm(InputArray _src1, InputArray _src2, int normType, InputArra
return true;
}
}
#endif
}
else
{
IppiSize sz = { cols*src1.channels(), rows };
int type = src1.depth();
typedef IppStatus (CV_STDCALL* ippiNormDiffFuncHint)(const void *, int, const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint);
typedef IppStatus (CV_STDCALL* ippiNormDiffFuncNoHint)(const void *, int, const void *, int, IppiSize, Ipp64f *);
ippiNormDiffFuncHint ippiNormDiffHint =
normType == NORM_L1 ?
(type == CV_32FC1 ? (ippiNormDiffFuncHint)ippiNormDiff_L1_32f_C1R :
type == CV_32FC3 ? (ippiNormDiffFuncHint)ippiNormDiff_L1_32f_C3R :
type == CV_32FC4 ? (ippiNormDiffFuncHint)ippiNormDiff_L1_32f_C4R :
(type == CV_32F ? (ippiNormDiffFuncHint)ippiNormDiff_L1_32f_C1R :
0) :
normType == NORM_L2 || normType == NORM_L2SQR ?
(type == CV_32FC1 ? (ippiNormDiffFuncHint)ippiNormDiff_L2_32f_C1R :
type == CV_32FC3 ? (ippiNormDiffFuncHint)ippiNormDiff_L2_32f_C3R :
type == CV_32FC4 ? (ippiNormDiffFuncHint)ippiNormDiff_L2_32f_C4R :
(type == CV_32F ? (ippiNormDiffFuncHint)ippiNormDiff_L2_32f_C1R :
0) : 0;
ippiNormDiffFuncNoHint ippiNormDiff =
normType == NORM_INF ?
(type == CV_8UC1 ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_8u_C1R :
type == CV_8UC3 ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_8u_C3R :
type == CV_8UC4 ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_8u_C4R :
type == CV_16UC1 ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_16u_C1R :
type == CV_16UC3 ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_16u_C3R :
type == CV_16UC4 ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_16u_C4R :
type == CV_16SC1 ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_16s_C1R :
#if (IPP_VERSION_X100 >= 810)
type == CV_16SC3 ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_16s_C3R : //Aug 2013: problem in IPP 7.1, 8.0 : -32768
type == CV_16SC4 ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_16s_C4R : //Aug 2013: problem in IPP 7.1, 8.0 : -32768
#endif
type == CV_32FC1 ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_32f_C1R :
type == CV_32FC3 ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_32f_C3R :
type == CV_32FC4 ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_32f_C4R :
(type == CV_8U ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_8u_C1R :
type == CV_16U ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_16u_C1R :
type == CV_16S ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_16s_C1R :
type == CV_32F ? (ippiNormDiffFuncNoHint)ippiNormDiff_Inf_32f_C1R :
0) :
normType == NORM_L1 ?
(type == CV_8UC1 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_8u_C1R :
type == CV_8UC3 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_8u_C3R :
type == CV_8UC4 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_8u_C4R :
type == CV_16UC1 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16u_C1R :
type == CV_16UC3 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16u_C3R :
type == CV_16UC4 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16u_C4R :
#if !(IPP_VERSION_X100 == 820 || IPP_VERSION_X100 == 821) // Oct 2014: Accuracy issue with IPP 8.2 / 8.2.1
type == CV_16SC1 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16s_C1R :
#endif
type == CV_16SC3 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16s_C3R :
type == CV_16SC4 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16s_C4R :
(type == CV_8U ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_8u_C1R :
type == CV_16U ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16u_C1R :
type == CV_16S ? (ippiNormDiffFuncNoHint)ippiNormDiff_L1_16s_C1R :
0) :
normType == NORM_L2 || normType == NORM_L2SQR ?
(type == CV_8UC1 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_8u_C1R :
type == CV_8UC3 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_8u_C3R :
type == CV_8UC4 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_8u_C4R :
type == CV_16UC1 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_16u_C1R :
type == CV_16UC3 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_16u_C3R :
type == CV_16UC4 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_16u_C4R :
type == CV_16SC1 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_16s_C1R :
type == CV_16SC3 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_16s_C3R :
type == CV_16SC4 ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_16s_C4R :
(type == CV_8U ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_8u_C1R :
type == CV_16U ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_16u_C1R :
type == CV_16S ? (ippiNormDiffFuncNoHint)ippiNormDiff_L2_16s_C1R :
0) : 0;
// Make sure only zero or one version of the function pointer is valid
CV_Assert(!ippiNormDiffHint || !ippiNormDiff);
if( ippiNormDiffHint || ippiNormDiff )
{
Ipp64f norm_array[4];
IppStatus ret = ippiNormDiffHint ? CV_INSTRUMENT_FUN_IPP(ippiNormDiffHint, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, norm_array, ippAlgHintAccurate) :
CV_INSTRUMENT_FUN_IPP(ippiNormDiff, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, norm_array);
Ipp64f norm;
IppStatus ret = ippiNormDiffHint ? CV_INSTRUMENT_FUN_IPP(ippiNormDiffHint, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm, ippAlgHintAccurate) :
CV_INSTRUMENT_FUN_IPP(ippiNormDiff, src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm);
if( ret >= 0 )
{
Ipp64f norm = (normType == NORM_L2 || normType == NORM_L2SQR) ? norm_array[0] * norm_array[0] : norm_array[0];
for( int i = 1; i < src1.channels(); i++ )
{
norm =
normType == NORM_INF ? std::max(norm, norm_array[i]) :
normType == NORM_L1 ? norm + norm_array[i] :
normType == NORM_L2 || normType == NORM_L2SQR ? norm + norm_array[i] * norm_array[i] :
0;
}
result = (normType == NORM_L2 ? (double)std::sqrt(norm) : (double)norm);
result = (normType == NORM_L2SQR) ? norm * norm : norm;
return true;
}
}