Merge pull request #4135 from lupustr3:ipp_code_refactoring

pull/4145/merge
Vadim Pisarevsky 10 years ago
commit 56e637d5f4
  1. 1
      modules/core/include/opencv2/core/base.hpp
  2. 58
      modules/core/include/opencv2/core/private.hpp
  3. 87
      modules/core/src/convert.cpp
  4. 339
      modules/core/src/copy.cpp
  5. 137
      modules/core/src/matrix.cpp
  6. 1408
      modules/core/src/stat.cpp
  7. 498
      modules/imgproc/src/accum.cpp
  8. 1339
      modules/imgproc/src/color.cpp
  9. 81
      modules/imgproc/src/corner.cpp
  10. 176
      modules/imgproc/src/deriv.cpp
  11. 161
      modules/imgproc/src/filter.cpp
  12. 37
      modules/imgproc/src/histogram.cpp
  13. 99
      modules/imgproc/src/imgwarp.cpp
  14. 23
      modules/imgproc/src/morph.cpp
  15. 198
      modules/imgproc/src/pyramids.cpp
  16. 346
      modules/imgproc/src/smooth.cpp
  17. 104
      modules/imgproc/src/sumpixels.cpp
  18. 147
      modules/imgproc/src/templmatch.cpp
  19. 36
      modules/imgproc/src/thresh.cpp

@ -305,6 +305,7 @@ enum BorderTypes {
#define CV_SUPPRESS_DEPRECATED_START
#define CV_SUPPRESS_DEPRECATED_END
#endif
#define CV_UNUSED(name) (void)name
//! @endcond
/*! @brief Signals an error and raises the exception.

@ -235,9 +235,67 @@ static inline IppDataType ippiGetDataType(int depth)
# define IPP_VERSION_X100 0
#endif
#ifdef HAVE_IPP_ICV_ONLY
#define HAVE_ICV 1
#else
#define HAVE_ICV 0
#endif
#define CV_IPP_CHECK_COND (cv::ipp::useIPP())
#define CV_IPP_CHECK() if(CV_IPP_CHECK_COND)
#ifdef HAVE_IPP
#ifdef CV_IPP_RUN_VERBOSE
#define CV_IPP_RUN_(condition, func, ...) \
{ \
if (cv::ipp::useIPP() && (condition) && func) \
{ \
printf("%s: IPP implementation is running\n", CV_Func); \
fflush(stdout); \
CV_IMPL_ADD(CV_IMPL_IPP); \
return __VA_ARGS__; \
} \
else \
{ \
printf("%s: Plain implementation is running\n", CV_Func); \
fflush(stdout); \
} \
}
#elif defined CV_IPP_RUN_ASSERT
#define CV_IPP_RUN_(condition, func, ...) \
{ \
if (cv::ipp::useIPP() && (condition)) \
{ \
if(func) \
{ \
CV_IMPL_ADD(CV_IMPL_IPP); \
} \
else \
{ \
setIppErrorStatus(); \
CV_Error(cv::Error::StsAssert, #func); \
} \
return __VA_ARGS__; \
} \
}
#else
#define CV_IPP_RUN_(condition, func, ...) \
if (cv::ipp::useIPP() && (condition) && func) \
{ \
CV_IMPL_ADD(CV_IMPL_IPP); \
return __VA_ARGS__; \
}
#endif
#else
#define CV_IPP_RUN_(condition, func, ...)
#endif
#define CV_IPP_RUN(condition, func, ...) CV_IPP_RUN_(condition, func, __VA_ARGS__)
#ifndef IPPI_CALL
# define IPPI_CALL(func) CV_Assert((func) >= 0)
#endif

@ -5194,18 +5194,7 @@ dtype* dst, size_t dstep, Size size, double* scale) \
static void cvt##suffix( const stype* src, size_t sstep, const uchar*, size_t, \
dtype* dst, size_t dstep, Size size, double*) \
{ \
CV_IPP_CHECK()\
{\
if (src && dst)\
{\
if (ippiConvert_##ippFavor(src, (int)sstep, dst, (int)dstep, ippiSize(size.width, size.height)) >= 0) \
{\
CV_IMPL_ADD(CV_IMPL_IPP)\
return; \
}\
setIppErrorStatus(); \
}\
}\
CV_IPP_RUN(src && dst, ippiConvert_##ippFavor(src, (int)sstep, dst, (int)dstep, ippiSize(size.width, size.height)) >= 0)\
cvt_(src, sstep, dst, dstep, size); \
}
@ -5213,18 +5202,7 @@ static void cvt##suffix( const stype* src, size_t sstep, const uchar*, size_t, \
static void cvt##suffix( const stype* src, size_t sstep, const uchar*, size_t, \
dtype* dst, size_t dstep, Size size, double*) \
{ \
CV_IPP_CHECK()\
{\
if (src && dst)\
{\
if (ippiConvert_##ippFavor(src, (int)sstep, dst, (int)dstep, ippiSize(size.width, size.height), ippRndFinancial, 0) >= 0) \
{\
CV_IMPL_ADD(CV_IMPL_IPP)\
return; \
}\
setIppErrorStatus(); \
}\
}\
CV_IPP_RUN(src && dst, ippiConvert_##ippFavor(src, (int)sstep, dst, (int)dstep, ippiSize(size.width, size.height), ippRndFinancial, 0) >= 0)\
cvt_(src, sstep, dst, dstep, size); \
}
#else
@ -5860,6 +5838,45 @@ private:
IppLUTParallelBody_LUTCN& operator=(const IppLUTParallelBody_LUTCN&);
};
} // namespace ipp
static bool ipp_lut(Mat &src, Mat &lut, Mat &dst)
{
int lutcn = lut.channels();
if(src.dims > 2)
return false;
bool ok = false;
Ptr<ParallelLoopBody> body;
size_t elemSize1 = CV_ELEM_SIZE1(dst.depth());
#if 0 // 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)
{
ParallelLoopBody* p = new ipp::IppLUTParallelBody_LUTCN(src, lut, dst, &ok);
body.reset(p);
}
if (body != NULL && ok)
{
Range all(0, dst.rows);
if (dst.total()>>18)
parallel_for_(all, *body, (double)std::max((size_t)1, dst.total()>>16));
else
(*body)(all);
if (ok)
return true;
}
return false;
}
#endif // IPP
class LUTParallelBody : public ParallelLoopBody
@ -5923,29 +5940,13 @@ void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst )
_dst.create(src.dims, src.size, CV_MAKETYPE(_lut.depth(), cn));
Mat dst = _dst.getMat();
CV_IPP_RUN(_src.dims() <= 2, ipp_lut(src, lut, dst));
if (_src.dims() <= 2)
{
bool ok = false;
Ptr<ParallelLoopBody> body;
#if defined(HAVE_IPP)
CV_IPP_CHECK()
{
size_t elemSize1 = CV_ELEM_SIZE1(dst.depth());
#if 0 // 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)
{
ParallelLoopBody* p = new ipp::IppLUTParallelBody_LUTCN(src, lut, dst, &ok);
body.reset(p);
}
}
#endif
if (body == NULL || ok == false)
{
ok = false;

@ -82,17 +82,7 @@ copyMask_(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, ucha
template<> void
copyMask_<uchar>(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size)
{
#if defined HAVE_IPP
CV_IPP_CHECK()
{
if (ippiCopy_8u_C1MR(_src, (int)sstep, _dst, (int)dstep, ippiSize(size), mask, (int)mstep) >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
}
#endif
CV_IPP_RUN(true, ippiCopy_8u_C1MR(_src, (int)sstep, _dst, (int)dstep, ippiSize(size), mask, (int)mstep) >= 0)
for( ; size.height--; mask += mstep, _src += sstep, _dst += dstep )
{
@ -132,17 +122,7 @@ copyMask_<uchar>(const uchar* _src, size_t sstep, const uchar* mask, size_t mste
template<> void
copyMask_<ushort>(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, uchar* _dst, size_t dstep, Size size)
{
#if defined HAVE_IPP
CV_IPP_CHECK()
{
if (ippiCopy_16u_C1MR((const Ipp16u *)_src, (int)sstep, (Ipp16u *)_dst, (int)dstep, ippiSize(size), mask, (int)mstep) >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
}
#endif
CV_IPP_RUN(true, ippiCopy_16u_C1MR((const Ipp16u *)_src, (int)sstep, (Ipp16u *)_dst, (int)dstep, ippiSize(size), mask, (int)mstep) >= 0)
for( ; size.height--; mask += mstep, _src += sstep, _dst += dstep )
{
@ -214,15 +194,7 @@ static void copyMask##suffix(const uchar* src, size_t sstep, const uchar* mask,
static void copyMask##suffix(const uchar* src, size_t sstep, const uchar* mask, size_t mstep, \
uchar* dst, size_t dstep, Size size, void*) \
{ \
CV_IPP_CHECK()\
{\
if (ippiCopy_##ippfavor((const ipptype *)src, (int)sstep, (ipptype *)dst, (int)dstep, ippiSize(size), (const Ipp8u *)mask, (int)mstep) >= 0) \
{\
CV_IMPL_ADD(CV_IMPL_IPP);\
return;\
}\
setIppErrorStatus(); \
}\
CV_IPP_RUN(true, ippiCopy_##ippfavor((const ipptype *)src, (int)sstep, (ipptype *)dst, (int)dstep, ippiSize(size), (const Ipp8u *)mask, (int)mstep) >= 0)\
copyMask_<type>(src, sstep, mask, mstep, dst, dstep, size); \
}
#else
@ -319,17 +291,7 @@ void Mat::copyTo( OutputArray _dst ) const
Size sz = getContinuousSize(*this, dst);
size_t len = sz.width*elemSize();
#if defined HAVE_IPP
CV_IPP_CHECK()
{
if (ippiCopy_8u_C1R(sptr, (int)step, dptr, (int)dst.step, ippiSize((int)len, sz.height)) >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP)
return;
}
setIppErrorStatus();
}
#endif
CV_IPP_RUN(true, ippiCopy_8u_C1R(sptr, (int)step, dptr, (int)dst.step, ippiSize((int)len, sz.height)) >= 0)
for( ; sz.height--; sptr += step, dptr += dst.step )
memcpy( dptr, sptr, len );
@ -461,98 +423,99 @@ Mat& Mat::operator = (const Scalar& s)
return *this;
}
Mat& Mat::setTo(InputArray _value, InputArray _mask)
#if defined HAVE_IPP
static bool ipp_Mat_setTo(Mat *src, Mat &value, Mat &mask)
{
if( empty() )
return *this;
int cn = src->channels(), depth0 = src->depth();
Mat value = _value.getMat(), mask = _mask.getMat();
CV_Assert( checkScalar(value, type(), _value.kind(), _InputArray::MAT ));
CV_Assert( mask.empty() || (mask.type() == CV_8U && size == mask.size) );
#if defined HAVE_IPP
CV_IPP_CHECK()
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))
{
int cn = channels(), depth0 = depth();
uchar _buf[32];
void * buf = _buf;
convertAndUnrollScalar( value, src->type(), _buf, 1 );
if (!mask.empty() && (dims <= 2 || (isContinuous() && mask.isContinuous())) &&
(/*depth0 == CV_8U ||*/ depth0 == CV_16U || depth0 == CV_16S || depth0 == CV_32S || depth0 == CV_32F) &&
(cn == 1 || cn == 3 || cn == 4))
{
uchar _buf[32];
void * buf = _buf;
convertAndUnrollScalar( value, type(), _buf, 1 );
IppStatus status = (IppStatus)-1;
IppiSize roisize = { src->cols, src->rows };
int mstep = (int)mask.step[0], dstep = (int)src->step[0];
IppStatus status = (IppStatus)-1;
IppiSize roisize = { cols, rows };
int mstep = (int)mask.step[0], dstep = (int)step[0];
if (src->isContinuous() && mask.isContinuous())
{
roisize.width = (int)src->total();
roisize.height = 1;
}
if (isContinuous() && mask.isContinuous())
{
roisize.width = (int)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 = ippiSet_16u_C1MR(*(Ipp16u *)buf, (Ipp16u *)src->data, dstep, roisize, mask.data, mstep);
else if (depth0 == CV_16S)
status = ippiSet_16s_C1MR(*(Ipp16s *)buf, (Ipp16s *)src->data, dstep, roisize, mask.data, mstep);
else if (depth0 == CV_32S)
status = ippiSet_32s_C1MR(*(Ipp32s *)buf, (Ipp32s *)src->data, dstep, roisize, mask.data, mstep);
else if (depth0 == CV_32F)
status = ippiSet_32f_C1MR(*(Ipp32f *)buf, (Ipp32f *)src->data, dstep, roisize, mask.data, mstep);
}
else if (cn == 3 || cn == 4)
{
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 = ippiSet_16u_C1MR(*(Ipp16u *)buf, (Ipp16u *)data, dstep, roisize, mask.data, mstep);
else if (depth0 == CV_16S)
status = ippiSet_16s_C1MR(*(Ipp16s *)buf, (Ipp16s *)data, dstep, roisize, mask.data, mstep);
else if (depth0 == CV_32S)
status = ippiSet_32s_C1MR(*(Ipp32s *)buf, (Ipp32s *)data, dstep, roisize, mask.data, mstep);
else if (depth0 == CV_32F)
status = ippiSet_32f_C1MR(*(Ipp32f *)buf, (Ipp32f *)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 = ippiSet_##ippfavor##_C##ippcn##MR(ippvalue, (ipptype *)data, dstep, roisize, mask.data, mstep); \
} while ((void)0, 0)
do \
{ \
typedef Ipp##ippfavor ipptype; \
ipptype ippvalue[4] = { ((ipptype *)buf)[0], ((ipptype *)buf)[1], ((ipptype *)buf)[2], ((ipptype *)buf)[3] }; \
status = 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) \
do \
{ \
/*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);
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)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return *this;
}
setIppErrorStatus();
}
if (status >= 0)
return true;
}
return false;
}
#endif
Mat& Mat::setTo(InputArray _value, InputArray _mask)
{
if( empty() )
return *this;
Mat value = _value.getMat(), mask = _mask.getMat();
CV_Assert( checkScalar(value, type(), _value.kind(), _InputArray::MAT ));
CV_Assert( mask.empty() || (mask.type() == CV_8U && size == mask.size) );
CV_IPP_RUN(true, ipp_Mat_setTo((cv::Mat*)this, value, mask), *this)
size_t esz = elemSize();
BinaryFunc copymask = getCopyMaskFunc(esz);
@ -725,6 +688,76 @@ 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 )
{
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 ippFunc = 0;
ippiMirrorI ippFuncI = 0;
if (src.data == dst.data)
{
CV_SUPPRESS_DEPRECATED_START
ippFuncI =
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
}
else
{
ippFunc =
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 };
if (ippFunc != 0)
{
if (ippFunc(src.ptr(), (int)src.step, dst.ptr(), (int)dst.step, ippiSize(src.cols, src.rows), axis) >= 0)
return true;
}
else if (ippFuncI != 0)
{
if (ippFuncI(dst.ptr(), (int)dst.step, roisize, axis) >= 0)
return true;
}
return false;
}
#endif
void flip( InputArray _src, OutputArray _dst, int flip_mode )
{
CV_Assert( _src.dims() <= 2 );
@ -751,80 +784,10 @@ void flip( InputArray _src, OutputArray _dst, int flip_mode )
int type = src.type();
_dst.create( size, type );
Mat dst = _dst.getMat();
size_t esz = CV_ELEM_SIZE(type);
#if defined HAVE_IPP
CV_IPP_CHECK()
{
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 ippFunc = 0;
ippiMirrorI ippFuncI = 0;
CV_IPP_RUN(true, ipp_flip(src, dst, flip_mode));
if (src.data == dst.data)
{
CV_SUPPRESS_DEPRECATED_START
ippFuncI =
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
}
else
{
ippFunc =
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 };
if (ippFunc != 0)
{
if (ippFunc(src.ptr(), (int)src.step, dst.ptr(), (int)dst.step, ippiSize(src.cols, src.rows), axis) >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
}
else if (ippFuncI != 0)
{
if (ippFuncI(dst.ptr(), (int)dst.step, roisize, axis) >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
}
}
#endif
size_t esz = CV_ELEM_SIZE(type);
if( flip_mode <= 0 )
flipVert( src.ptr(), src.step, dst.ptr(), dst.step, src.size(), esz );

@ -3092,8 +3092,74 @@ static bool ocl_transpose( InputArray _src, OutputArray _dst )
#endif
#ifdef HAVE_IPP
static bool ipp_transpose( Mat &src, Mat &dst )
{
int type = src.type();
typedef IppStatus (CV_STDCALL * ippiTranspose)(const void * pSrc, int srcStep, void * pDst, int dstStep, IppiSize roiSize);
typedef IppStatus (CV_STDCALL * ippiTransposeI)(const void * pSrcDst, int srcDstStep, IppiSize roiSize);
ippiTranspose ippFunc = 0;
ippiTransposeI ippFuncI = 0;
if (dst.data == src.data && dst.cols == dst.rows)
{
CV_SUPPRESS_DEPRECATED_START
ippFuncI =
type == CV_8UC1 ? (ippiTransposeI)ippiTranspose_8u_C1IR :
type == CV_8UC3 ? (ippiTransposeI)ippiTranspose_8u_C3IR :
type == CV_8UC4 ? (ippiTransposeI)ippiTranspose_8u_C4IR :
type == CV_16UC1 ? (ippiTransposeI)ippiTranspose_16u_C1IR :
type == CV_16UC3 ? (ippiTransposeI)ippiTranspose_16u_C3IR :
type == CV_16UC4 ? (ippiTransposeI)ippiTranspose_16u_C4IR :
type == CV_16SC1 ? (ippiTransposeI)ippiTranspose_16s_C1IR :
type == CV_16SC3 ? (ippiTransposeI)ippiTranspose_16s_C3IR :
type == CV_16SC4 ? (ippiTransposeI)ippiTranspose_16s_C4IR :
type == CV_32SC1 ? (ippiTransposeI)ippiTranspose_32s_C1IR :
type == CV_32SC3 ? (ippiTransposeI)ippiTranspose_32s_C3IR :
type == CV_32SC4 ? (ippiTransposeI)ippiTranspose_32s_C4IR :
type == CV_32FC1 ? (ippiTransposeI)ippiTranspose_32f_C1IR :
type == CV_32FC3 ? (ippiTransposeI)ippiTranspose_32f_C3IR :
type == CV_32FC4 ? (ippiTransposeI)ippiTranspose_32f_C4IR : 0;
CV_SUPPRESS_DEPRECATED_END
}
else
{
ippFunc =
type == CV_8UC1 ? (ippiTranspose)ippiTranspose_8u_C1R :
type == CV_8UC3 ? (ippiTranspose)ippiTranspose_8u_C3R :
type == CV_8UC4 ? (ippiTranspose)ippiTranspose_8u_C4R :
type == CV_16UC1 ? (ippiTranspose)ippiTranspose_16u_C1R :
type == CV_16UC3 ? (ippiTranspose)ippiTranspose_16u_C3R :
type == CV_16UC4 ? (ippiTranspose)ippiTranspose_16u_C4R :
type == CV_16SC1 ? (ippiTranspose)ippiTranspose_16s_C1R :
type == CV_16SC3 ? (ippiTranspose)ippiTranspose_16s_C3R :
type == CV_16SC4 ? (ippiTranspose)ippiTranspose_16s_C4R :
type == CV_32SC1 ? (ippiTranspose)ippiTranspose_32s_C1R :
type == CV_32SC3 ? (ippiTranspose)ippiTranspose_32s_C3R :
type == CV_32SC4 ? (ippiTranspose)ippiTranspose_32s_C4R :
type == CV_32FC1 ? (ippiTranspose)ippiTranspose_32f_C1R :
type == CV_32FC3 ? (ippiTranspose)ippiTranspose_32f_C3R :
type == CV_32FC4 ? (ippiTranspose)ippiTranspose_32f_C4R : 0;
}
IppiSize roiSize = { src.cols, src.rows };
if (ippFunc != 0)
{
if (ippFunc(src.ptr(), (int)src.step, dst.ptr(), (int)dst.step, roiSize) >= 0)
return true;
}
else if (ippFuncI != 0)
{
if (ippFuncI(dst.ptr(), (int)dst.step, roiSize) >= 0)
return true;
}
return false;
}
#endif
}
void cv::transpose( InputArray _src, OutputArray _dst )
{
int type = _src.type(), esz = CV_ELEM_SIZE(type);
@ -3120,76 +3186,7 @@ void cv::transpose( InputArray _src, OutputArray _dst )
return;
}
#if defined HAVE_IPP
CV_IPP_CHECK()
{
typedef IppStatus (CV_STDCALL * ippiTranspose)(const void * pSrc, int srcStep, void * pDst, int dstStep, IppiSize roiSize);
typedef IppStatus (CV_STDCALL * ippiTransposeI)(const void * pSrcDst, int srcDstStep, IppiSize roiSize);
ippiTranspose ippFunc = 0;
ippiTransposeI ippFuncI = 0;
if (dst.data == src.data && dst.cols == dst.rows)
{
CV_SUPPRESS_DEPRECATED_START
ippFuncI =
type == CV_8UC1 ? (ippiTransposeI)ippiTranspose_8u_C1IR :
type == CV_8UC3 ? (ippiTransposeI)ippiTranspose_8u_C3IR :
type == CV_8UC4 ? (ippiTransposeI)ippiTranspose_8u_C4IR :
type == CV_16UC1 ? (ippiTransposeI)ippiTranspose_16u_C1IR :
type == CV_16UC3 ? (ippiTransposeI)ippiTranspose_16u_C3IR :
type == CV_16UC4 ? (ippiTransposeI)ippiTranspose_16u_C4IR :
type == CV_16SC1 ? (ippiTransposeI)ippiTranspose_16s_C1IR :
type == CV_16SC3 ? (ippiTransposeI)ippiTranspose_16s_C3IR :
type == CV_16SC4 ? (ippiTransposeI)ippiTranspose_16s_C4IR :
type == CV_32SC1 ? (ippiTransposeI)ippiTranspose_32s_C1IR :
type == CV_32SC3 ? (ippiTransposeI)ippiTranspose_32s_C3IR :
type == CV_32SC4 ? (ippiTransposeI)ippiTranspose_32s_C4IR :
type == CV_32FC1 ? (ippiTransposeI)ippiTranspose_32f_C1IR :
type == CV_32FC3 ? (ippiTransposeI)ippiTranspose_32f_C3IR :
type == CV_32FC4 ? (ippiTransposeI)ippiTranspose_32f_C4IR : 0;
CV_SUPPRESS_DEPRECATED_END
}
else
{
ippFunc =
type == CV_8UC1 ? (ippiTranspose)ippiTranspose_8u_C1R :
type == CV_8UC3 ? (ippiTranspose)ippiTranspose_8u_C3R :
type == CV_8UC4 ? (ippiTranspose)ippiTranspose_8u_C4R :
type == CV_16UC1 ? (ippiTranspose)ippiTranspose_16u_C1R :
type == CV_16UC3 ? (ippiTranspose)ippiTranspose_16u_C3R :
type == CV_16UC4 ? (ippiTranspose)ippiTranspose_16u_C4R :
type == CV_16SC1 ? (ippiTranspose)ippiTranspose_16s_C1R :
type == CV_16SC3 ? (ippiTranspose)ippiTranspose_16s_C3R :
type == CV_16SC4 ? (ippiTranspose)ippiTranspose_16s_C4R :
type == CV_32SC1 ? (ippiTranspose)ippiTranspose_32s_C1R :
type == CV_32SC3 ? (ippiTranspose)ippiTranspose_32s_C3R :
type == CV_32SC4 ? (ippiTranspose)ippiTranspose_32s_C4R :
type == CV_32FC1 ? (ippiTranspose)ippiTranspose_32f_C1R :
type == CV_32FC3 ? (ippiTranspose)ippiTranspose_32f_C3R :
type == CV_32FC4 ? (ippiTranspose)ippiTranspose_32f_C4R : 0;
}
IppiSize roiSize = { src.cols, src.rows };
if (ippFunc != 0)
{
if (ippFunc(src.ptr(), (int)src.step, dst.ptr(), (int)dst.step, roiSize) >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
}
else if (ippFuncI != 0)
{
if (ippFuncI(dst.ptr(), (int)dst.step, roiSize) >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
}
}
#endif
CV_IPP_RUN(true, ipp_transpose(src, dst))
if( dst.data == src.data )
{

File diff suppressed because it is too large Load Diff

@ -843,78 +843,87 @@ static bool ocl_accumulate( InputArray _src, InputArray _src2, InputOutputArray
}
void cv::accumulate( InputArray _src, InputOutputArray _dst, InputArray _mask )
#if defined(HAVE_IPP)
namespace cv
{
static bool ipp_accumulate(InputArray _src, InputOutputArray _dst, InputArray _mask)
{
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype), dcn = CV_MAT_CN(dtype);
CV_Assert( _src.sameSize(_dst) && dcn == scn );
CV_Assert( _mask.empty() || (_src.sameSize(_mask) && _mask.type() == CV_8U) );
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_accumulate(_src, noArray(), _dst, 0.0, _mask, ACCUMULATE))
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype);
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
#if defined HAVE_IPP
CV_IPP_CHECK()
if (src.dims <= 2 || (src.isContinuous() && dst.isContinuous() && (mask.empty() || mask.isContinuous())))
{
if (src.dims <= 2 || (src.isContinuous() && dst.isContinuous() && (mask.empty() || mask.isContinuous())))
typedef IppStatus (CV_STDCALL * ippiAdd)(const void * pSrc, int srcStep, Ipp32f * pSrcDst, int srcdstStep, IppiSize roiSize);
typedef IppStatus (CV_STDCALL * ippiAddMask)(const void * pSrc, int srcStep, const Ipp8u * pMask, int maskStep, Ipp32f * pSrcDst,
int srcDstStep, IppiSize roiSize);
ippiAdd ippFunc = 0;
ippiAddMask ippFuncMask = 0;
if (mask.empty())
{
CV_SUPPRESS_DEPRECATED_START
ippFunc = sdepth == CV_8U && ddepth == CV_32F ? (ippiAdd)ippiAdd_8u32f_C1IR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAdd)ippiAdd_16u32f_C1IR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAdd)ippiAdd_32f_C1IR : 0;
CV_SUPPRESS_DEPRECATED_END
}
else if (scn == 1)
{
typedef IppStatus (CV_STDCALL * ippiAdd)(const void * pSrc, int srcStep, Ipp32f * pSrcDst, int srcdstStep, IppiSize roiSize);
typedef IppStatus (CV_STDCALL * ippiAddMask)(const void * pSrc, int srcStep, const Ipp8u * pMask, int maskStep, Ipp32f * pSrcDst,
int srcDstStep, IppiSize roiSize);
ippiAdd ippFunc = 0;
ippiAddMask ippFuncMask = 0;
ippFuncMask = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddMask)ippiAdd_8u32f_C1IMR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddMask)ippiAdd_16u32f_C1IMR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddMask)ippiAdd_32f_C1IMR : 0;
}
if (mask.empty())
{
CV_SUPPRESS_DEPRECATED_START
ippFunc = sdepth == CV_8U && ddepth == CV_32F ? (ippiAdd)ippiAdd_8u32f_C1IR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAdd)ippiAdd_16u32f_C1IR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAdd)ippiAdd_32f_C1IR : 0;
CV_SUPPRESS_DEPRECATED_END
}
else if (scn == 1)
{
ippFuncMask = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddMask)ippiAdd_8u32f_C1IMR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddMask)ippiAdd_16u32f_C1IMR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddMask)ippiAdd_32f_C1IMR : 0;
}
if (ippFunc || ippFuncMask)
{
IppStatus status = ippStsErr;
if (ippFunc || ippFuncMask)
Size size = src.size();
int srcstep = (int)src.step, dststep = (int)dst.step, maskstep = (int)mask.step;
if (src.isContinuous() && dst.isContinuous() && mask.isContinuous())
{
IppStatus status = ippStsNoErr;
Size size = src.size();
int srcstep = (int)src.step, dststep = (int)dst.step, maskstep = (int)mask.step;
if (src.isContinuous() && dst.isContinuous() && mask.isContinuous())
{
srcstep = static_cast<int>(src.total() * src.elemSize());
dststep = static_cast<int>(dst.total() * dst.elemSize());
maskstep = static_cast<int>(mask.total() * mask.elemSize());
size.width = static_cast<int>(src.total());
size.height = 1;
}
size.width *= scn;
if (mask.empty())
status = ippFunc(src.ptr(), srcstep, dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
else
status = ippFuncMask(src.ptr(), srcstep, mask.ptr<Ipp8u>(), maskstep,
dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
if (status >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
srcstep = static_cast<int>(src.total() * src.elemSize());
dststep = static_cast<int>(dst.total() * dst.elemSize());
maskstep = static_cast<int>(mask.total() * mask.elemSize());
size.width = static_cast<int>(src.total());
size.height = 1;
}
size.width *= scn;
if (ippFunc)
status = ippFunc(src.ptr(), srcstep, dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
else if(ippFuncMask)
status = ippFuncMask(src.ptr(), srcstep, mask.ptr<Ipp8u>(), maskstep,
dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
if (status >= 0)
return true;
}
}
return false;
}
}
#endif
void cv::accumulate( InputArray _src, InputOutputArray _dst, InputArray _mask )
{
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype), dcn = CV_MAT_CN(dtype);
CV_Assert( _src.sameSize(_dst) && dcn == scn );
CV_Assert( _mask.empty() || (_src.sameSize(_mask) && _mask.type() == CV_8U) );
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_accumulate(_src, noArray(), _dst, 0.0, _mask, ACCUMULATE))
CV_IPP_RUN((_src.dims() <= 2 || (_src.isContinuous() && _dst.isContinuous() && (_mask.empty() || _mask.isContinuous()))),
ipp_accumulate(_src, _dst, _mask));
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
int fidx = getAccTabIdx(sdepth, ddepth);
AccFunc func = fidx >= 0 ? accTab[fidx] : 0;
CV_Assert( func != 0 );
@ -928,76 +937,84 @@ void cv::accumulate( InputArray _src, InputOutputArray _dst, InputArray _mask )
func(ptrs[0], ptrs[1], ptrs[2], len, scn);
}
void cv::accumulateSquare( InputArray _src, InputOutputArray _dst, InputArray _mask )
#if defined(HAVE_IPP)
namespace cv
{
static bool ipp_accumulate_square(InputArray _src, InputOutputArray _dst, InputArray _mask)
{
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype), dcn = CV_MAT_CN(dtype);
CV_Assert( _src.sameSize(_dst) && dcn == scn );
CV_Assert( _mask.empty() || (_src.sameSize(_mask) && _mask.type() == CV_8U) );
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_accumulate(_src, noArray(), _dst, 0.0, _mask, ACCUMULATE_SQUARE))
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype);
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
#if defined(HAVE_IPP)
CV_IPP_CHECK()
if (src.dims <= 2 || (src.isContinuous() && dst.isContinuous() && (mask.empty() || mask.isContinuous())))
{
if (src.dims <= 2 || (src.isContinuous() && dst.isContinuous() && (mask.empty() || mask.isContinuous())))
typedef IppStatus (CV_STDCALL * ippiAddSquare)(const void * pSrc, int srcStep, Ipp32f * pSrcDst, int srcdstStep, IppiSize roiSize);
typedef IppStatus (CV_STDCALL * ippiAddSquareMask)(const void * pSrc, int srcStep, const Ipp8u * pMask, int maskStep, Ipp32f * pSrcDst,
int srcDstStep, IppiSize roiSize);
ippiAddSquare ippFunc = 0;
ippiAddSquareMask ippFuncMask = 0;
if (mask.empty())
{
typedef IppStatus (CV_STDCALL * ippiAddSquare)(const void * pSrc, int srcStep, Ipp32f * pSrcDst, int srcdstStep, IppiSize roiSize);
typedef IppStatus (CV_STDCALL * ippiAddSquareMask)(const void * pSrc, int srcStep, const Ipp8u * pMask, int maskStep, Ipp32f * pSrcDst,
int srcDstStep, IppiSize roiSize);
ippiAddSquare ippFunc = 0;
ippiAddSquareMask ippFuncMask = 0;
ippFunc = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddSquare)ippiAddSquare_8u32f_C1IR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddSquare)ippiAddSquare_16u32f_C1IR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddSquare)ippiAddSquare_32f_C1IR : 0;
}
else if (scn == 1)
{
ippFuncMask = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddSquareMask)ippiAddSquare_8u32f_C1IMR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddSquareMask)ippiAddSquare_16u32f_C1IMR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddSquareMask)ippiAddSquare_32f_C1IMR : 0;
}
if (mask.empty())
{
ippFunc = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddSquare)ippiAddSquare_8u32f_C1IR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddSquare)ippiAddSquare_16u32f_C1IR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddSquare)ippiAddSquare_32f_C1IR : 0;
}
else if (scn == 1)
{
ippFuncMask = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddSquareMask)ippiAddSquare_8u32f_C1IMR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddSquareMask)ippiAddSquare_16u32f_C1IMR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddSquareMask)ippiAddSquare_32f_C1IMR : 0;
}
if (ippFunc || ippFuncMask)
{
IppStatus status = ippStsErr;
if (ippFunc || ippFuncMask)
Size size = src.size();
int srcstep = (int)src.step, dststep = (int)dst.step, maskstep = (int)mask.step;
if (src.isContinuous() && dst.isContinuous() && mask.isContinuous())
{
IppStatus status = ippStsNoErr;
Size size = src.size();
int srcstep = (int)src.step, dststep = (int)dst.step, maskstep = (int)mask.step;
if (src.isContinuous() && dst.isContinuous() && mask.isContinuous())
{
srcstep = static_cast<int>(src.total() * src.elemSize());
dststep = static_cast<int>(dst.total() * dst.elemSize());
maskstep = static_cast<int>(mask.total() * mask.elemSize());
size.width = static_cast<int>(src.total());
size.height = 1;
}
size.width *= scn;
if (mask.empty())
status = ippFunc(src.ptr(), srcstep, dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
else
status = ippFuncMask(src.ptr(), srcstep, mask.ptr<Ipp8u>(), maskstep,
dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
if (status >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
srcstep = static_cast<int>(src.total() * src.elemSize());
dststep = static_cast<int>(dst.total() * dst.elemSize());
maskstep = static_cast<int>(mask.total() * mask.elemSize());
size.width = static_cast<int>(src.total());
size.height = 1;
}
size.width *= scn;
if (ippFunc)
status = ippFunc(src.ptr(), srcstep, dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
else if(ippFuncMask)
status = ippFuncMask(src.ptr(), srcstep, mask.ptr<Ipp8u>(), maskstep,
dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
if (status >= 0)
return true;
}
}
return false;
}
}
#endif
void cv::accumulateSquare( InputArray _src, InputOutputArray _dst, InputArray _mask )
{
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype), dcn = CV_MAT_CN(dtype);
CV_Assert( _src.sameSize(_dst) && dcn == scn );
CV_Assert( _mask.empty() || (_src.sameSize(_mask) && _mask.type() == CV_8U) );
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_accumulate(_src, noArray(), _dst, 0.0, _mask, ACCUMULATE_SQUARE))
CV_IPP_RUN((_src.dims() <= 2 || (_src.isContinuous() && _dst.isContinuous() && (_mask.empty() || _mask.isContinuous()))),
ipp_accumulate_square(_src, _dst, _mask));
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
int fidx = getAccTabIdx(sdepth, ddepth);
AccFunc func = fidx >= 0 ? accSqrTab[fidx] : 0;
CV_Assert( func != 0 );
@ -1011,6 +1028,74 @@ void cv::accumulateSquare( InputArray _src, InputOutputArray _dst, InputArray _m
func(ptrs[0], ptrs[1], ptrs[2], len, scn);
}
#if defined(HAVE_IPP)
namespace cv
{
static bool ipp_accumulate_product(InputArray _src1, InputArray _src2,
InputOutputArray _dst, InputArray _mask)
{
int stype = _src1.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype);
Mat src1 = _src1.getMat(), src2 = _src2.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
if (src1.dims <= 2 || (src1.isContinuous() && src2.isContinuous() && dst.isContinuous()))
{
typedef IppStatus (CV_STDCALL * ippiAddProduct)(const void * pSrc1, int src1Step, const void * pSrc2,
int src2Step, Ipp32f * pSrcDst, int srcDstStep, IppiSize roiSize);
typedef IppStatus (CV_STDCALL * ippiAddProductMask)(const void * pSrc1, int src1Step, const void * pSrc2, int src2Step,
const Ipp8u * pMask, int maskStep, Ipp32f * pSrcDst, int srcDstStep, IppiSize roiSize);
ippiAddProduct ippFunc = 0;
ippiAddProductMask ippFuncMask = 0;
if (mask.empty())
{
ippFunc = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddProduct)ippiAddProduct_8u32f_C1IR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddProduct)ippiAddProduct_16u32f_C1IR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddProduct)ippiAddProduct_32f_C1IR : 0;
}
else if (scn == 1)
{
ippFuncMask = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddProductMask)ippiAddProduct_8u32f_C1IMR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddProductMask)ippiAddProduct_16u32f_C1IMR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddProductMask)ippiAddProduct_32f_C1IMR : 0;
}
if (ippFunc || ippFuncMask)
{
IppStatus status = ippStsErr;
Size size = src1.size();
int src1step = (int)src1.step, src2step = (int)src2.step, dststep = (int)dst.step, maskstep = (int)mask.step;
if (src1.isContinuous() && src2.isContinuous() && dst.isContinuous() && mask.isContinuous())
{
src1step = static_cast<int>(src1.total() * src1.elemSize());
src2step = static_cast<int>(src2.total() * src2.elemSize());
dststep = static_cast<int>(dst.total() * dst.elemSize());
maskstep = static_cast<int>(mask.total() * mask.elemSize());
size.width = static_cast<int>(src1.total());
size.height = 1;
}
size.width *= scn;
if (ippFunc)
status = ippFunc(src1.ptr(), src1step, src2.ptr(), src2step, dst.ptr<Ipp32f>(),
dststep, ippiSize(size.width, size.height));
else if(ippFuncMask)
status = ippFuncMask(src1.ptr(), src1step, src2.ptr(), src2step, mask.ptr<Ipp8u>(), maskstep,
dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
if (status >= 0)
return true;
}
}
return false;
}
}
#endif
void cv::accumulateProduct( InputArray _src1, InputArray _src2,
InputOutputArray _dst, InputArray _mask )
{
@ -1024,67 +1109,10 @@ void cv::accumulateProduct( InputArray _src1, InputArray _src2,
CV_OCL_RUN(_src1.dims() <= 2 && _dst.isUMat(),
ocl_accumulate(_src1, _src2, _dst, 0.0, _mask, ACCUMULATE_PRODUCT))
Mat src1 = _src1.getMat(), src2 = _src2.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
#if defined(HAVE_IPP)
CV_IPP_CHECK()
{
if (src1.dims <= 2 || (src1.isContinuous() && src2.isContinuous() && dst.isContinuous()))
{
typedef IppStatus (CV_STDCALL * ippiAddProduct)(const void * pSrc1, int src1Step, const void * pSrc2,
int src2Step, Ipp32f * pSrcDst, int srcDstStep, IppiSize roiSize);
typedef IppStatus (CV_STDCALL * ippiAddProductMask)(const void * pSrc1, int src1Step, const void * pSrc2, int src2Step,
const Ipp8u * pMask, int maskStep, Ipp32f * pSrcDst, int srcDstStep, IppiSize roiSize);
ippiAddProduct ippFunc = 0;
ippiAddProductMask ippFuncMask = 0;
if (mask.empty())
{
ippFunc = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddProduct)ippiAddProduct_8u32f_C1IR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddProduct)ippiAddProduct_16u32f_C1IR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddProduct)ippiAddProduct_32f_C1IR : 0;
}
else if (scn == 1)
{
ippFuncMask = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddProductMask)ippiAddProduct_8u32f_C1IMR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddProductMask)ippiAddProduct_16u32f_C1IMR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddProductMask)ippiAddProduct_32f_C1IMR : 0;
}
CV_IPP_RUN( (_src1.dims() <= 2 || (_src1.isContinuous() && _src2.isContinuous() && _dst.isContinuous())),
ipp_accumulate_product(_src1, _src2, _dst, _mask));
if (ippFunc || ippFuncMask)
{
IppStatus status = ippStsNoErr;
Size size = src1.size();
int src1step = (int)src1.step, src2step = (int)src2.step, dststep = (int)dst.step, maskstep = (int)mask.step;
if (src1.isContinuous() && src2.isContinuous() && dst.isContinuous() && mask.isContinuous())
{
src1step = static_cast<int>(src1.total() * src1.elemSize());
src2step = static_cast<int>(src2.total() * src2.elemSize());
dststep = static_cast<int>(dst.total() * dst.elemSize());
maskstep = static_cast<int>(mask.total() * mask.elemSize());
size.width = static_cast<int>(src1.total());
size.height = 1;
}
size.width *= scn;
if (mask.empty())
status = ippFunc(src1.ptr(), src1step, src2.ptr(), src2step, dst.ptr<Ipp32f>(),
dststep, ippiSize(size.width, size.height));
else
status = ippFuncMask(src1.ptr(), src1step, src2.ptr(), src2step, mask.ptr<Ipp8u>(), maskstep,
dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height));
if (status >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
}
}
}
#endif
Mat src1 = _src1.getMat(), src2 = _src2.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
int fidx = getAccTabIdx(sdepth, ddepth);
AccProdFunc func = fidx >= 0 ? accProdTab[fidx] : 0;
@ -1099,79 +1127,89 @@ void cv::accumulateProduct( InputArray _src1, InputArray _src2,
func(ptrs[0], ptrs[1], ptrs[2], ptrs[3], len, scn);
}
void cv::accumulateWeighted( InputArray _src, InputOutputArray _dst,
#if defined(HAVE_IPP)
namespace cv
{
static bool ipp_accumulate_weighted( InputArray _src, InputOutputArray _dst,
double alpha, InputArray _mask )
{
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype), dcn = CV_MAT_CN(dtype);
CV_Assert( _src.sameSize(_dst) && dcn == scn );
CV_Assert( _mask.empty() || (_src.sameSize(_mask) && _mask.type() == CV_8U) );
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_accumulate(_src, noArray(), _dst, alpha, _mask, ACCUMULATE_WEIGHTED))
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype);
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
#if defined(HAVE_IPP)
CV_IPP_CHECK()
if (src.dims <= 2 || (src.isContinuous() && dst.isContinuous() && mask.isContinuous()))
{
if (src.dims <= 2 || (src.isContinuous() && dst.isContinuous() && mask.isContinuous()))
typedef IppStatus (CV_STDCALL * ippiAddWeighted)(const void * pSrc, int srcStep, Ipp32f * pSrcDst, int srcdstStep,
IppiSize roiSize, Ipp32f alpha);
typedef IppStatus (CV_STDCALL * ippiAddWeightedMask)(const void * pSrc, int srcStep, const Ipp8u * pMask,
int maskStep, Ipp32f * pSrcDst,
int srcDstStep, IppiSize roiSize, Ipp32f alpha);
ippiAddWeighted ippFunc = 0;
ippiAddWeightedMask ippFuncMask = 0;
if (mask.empty())
{
typedef IppStatus (CV_STDCALL * ippiAddWeighted)(const void * pSrc, int srcStep, Ipp32f * pSrcDst, int srcdstStep,
IppiSize roiSize, Ipp32f alpha);
typedef IppStatus (CV_STDCALL * ippiAddWeightedMask)(const void * pSrc, int srcStep, const Ipp8u * pMask,
int maskStep, Ipp32f * pSrcDst,
int srcDstStep, IppiSize roiSize, Ipp32f alpha);
ippiAddWeighted ippFunc = 0;
ippiAddWeightedMask ippFuncMask = 0;
if (mask.empty())
{
ippFunc = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddWeighted)ippiAddWeighted_8u32f_C1IR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddWeighted)ippiAddWeighted_16u32f_C1IR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddWeighted)ippiAddWeighted_32f_C1IR : 0;
}
else if (scn == 1)
{
ippFuncMask = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddWeightedMask)ippiAddWeighted_8u32f_C1IMR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddWeightedMask)ippiAddWeighted_16u32f_C1IMR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddWeightedMask)ippiAddWeighted_32f_C1IMR : 0;
}
ippFunc = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddWeighted)ippiAddWeighted_8u32f_C1IR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddWeighted)ippiAddWeighted_16u32f_C1IR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddWeighted)ippiAddWeighted_32f_C1IR : 0;
}
else if (scn == 1)
{
ippFuncMask = sdepth == CV_8U && ddepth == CV_32F ? (ippiAddWeightedMask)ippiAddWeighted_8u32f_C1IMR :
sdepth == CV_16U && ddepth == CV_32F ? (ippiAddWeightedMask)ippiAddWeighted_16u32f_C1IMR :
sdepth == CV_32F && ddepth == CV_32F ? (ippiAddWeightedMask)ippiAddWeighted_32f_C1IMR : 0;
}
if (ippFunc || ippFuncMask)
if (ippFunc || ippFuncMask)
{
IppStatus status = ippStsErr;
Size size = src.size();
int srcstep = (int)src.step, dststep = (int)dst.step, maskstep = (int)mask.step;
if (src.isContinuous() && dst.isContinuous() && mask.isContinuous())
{
IppStatus status = ippStsNoErr;
Size size = src.size();
int srcstep = (int)src.step, dststep = (int)dst.step, maskstep = (int)mask.step;
if (src.isContinuous() && dst.isContinuous() && mask.isContinuous())
{
srcstep = static_cast<int>(src.total() * src.elemSize());
dststep = static_cast<int>(dst.total() * dst.elemSize());
maskstep = static_cast<int>(mask.total() * mask.elemSize());
size.width = static_cast<int>((int)src.total());
size.height = 1;
}
size.width *= scn;
if (mask.empty())
status = ippFunc(src.ptr(), srcstep, dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height), (Ipp32f)alpha);
else
status = ippFuncMask(src.ptr(), srcstep, mask.ptr<Ipp8u>(), maskstep,
dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height), (Ipp32f)alpha);
if (status >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
srcstep = static_cast<int>(src.total() * src.elemSize());
dststep = static_cast<int>(dst.total() * dst.elemSize());
maskstep = static_cast<int>(mask.total() * mask.elemSize());
size.width = static_cast<int>((int)src.total());
size.height = 1;
}
size.width *= scn;
if (ippFunc)
status = ippFunc(src.ptr(), srcstep, dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height), (Ipp32f)alpha);
else if(ippFuncMask)
status = ippFuncMask(src.ptr(), srcstep, mask.ptr<Ipp8u>(), maskstep,
dst.ptr<Ipp32f>(), dststep, ippiSize(size.width, size.height), (Ipp32f)alpha);
if (status >= 0)
return true;
}
}
return false;
}
}
#endif
void cv::accumulateWeighted( InputArray _src, InputOutputArray _dst,
double alpha, InputArray _mask )
{
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), scn = CV_MAT_CN(stype);
int dtype = _dst.type(), ddepth = CV_MAT_DEPTH(dtype), dcn = CV_MAT_CN(dtype);
CV_Assert( _src.sameSize(_dst) && dcn == scn );
CV_Assert( _mask.empty() || (_src.sameSize(_mask) && _mask.type() == CV_8U) );
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_accumulate(_src, noArray(), _dst, alpha, _mask, ACCUMULATE_WEIGHTED))
CV_IPP_RUN((_src.dims() <= 2 || (_src.isContinuous() && _dst.isContinuous() && _mask.isContinuous())), ipp_accumulate_weighted(_src, _dst, alpha, _mask));
Mat src = _src.getMat(), dst = _dst.getMat(), mask = _mask.getMat();
int fidx = getAccTabIdx(sdepth, ddepth);
AccWFunc func = fidx >= 0 ? accWTab[fidx] : 0;
CV_Assert( func != 0 );

File diff suppressed because it is too large Load Diff

@ -523,16 +523,16 @@ static bool ocl_preCornerDetect( InputArray _src, OutputArray _dst, int ksize, i
}
void cv::cornerMinEigenVal( InputArray _src, OutputArray _dst, int blockSize, int ksize, int borderType )
#if defined(HAVE_IPP)
namespace cv
{
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_cornerMinEigenValVecs(_src, _dst, blockSize, ksize, 0.0, borderType, MINEIGENVAL))
static bool ipp_cornerMinEigenVal( InputArray _src, OutputArray _dst, int blockSize, int ksize, int borderType )
{
#if IPP_VERSION_MAJOR >= 8
Mat src = _src.getMat();
_dst.create( src.size(), CV_32FC1 );
Mat dst = _dst.getMat();
#if defined(HAVE_IPP) && (IPP_VERSION_MAJOR >= 8)
CV_IPP_CHECK()
{
typedef IppStatus (CV_STDCALL * ippiMinEigenValGetBufferSize)(IppiSize, int, int, int*);
typedef IppStatus (CV_STDCALL * ippiMinEigenVal)(const void*, int, Ipp32f*, int, IppiSize, IppiKernelType, int, int, Ipp8u*);
@ -583,28 +583,57 @@ void cv::cornerMinEigenVal( InputArray _src, OutputArray _dst, int blockSize, in
if (ok >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
return true;
}
}
setIppErrorStatus();
}
}
}
#else
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(blockSize); CV_UNUSED(borderType);
#endif
cornerEigenValsVecs( src, dst, blockSize, ksize, MINEIGENVAL, 0, borderType );
return false;
}
}
#endif
void cv::cornerHarris( InputArray _src, OutputArray _dst, int blockSize, int ksize, double k, int borderType )
void cv::cornerMinEigenVal( InputArray _src, OutputArray _dst, int blockSize, int ksize, int borderType )
{
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_cornerMinEigenValVecs(_src, _dst, blockSize, ksize, k, borderType, HARRIS))
ocl_cornerMinEigenValVecs(_src, _dst, blockSize, ksize, 0.0, borderType, MINEIGENVAL))
#ifdef HAVE_IPP
int kerSize = ksize;
if (ksize < 0)
{
kerSize = 3;
}
bool isolated = (borderType & BORDER_ISOLATED) != 0;
int borderTypeNI = borderType & ~BORDER_ISOLATED;
#endif
CV_IPP_RUN(((borderTypeNI == BORDER_REPLICATE && (!_src.isSubmatrix() || isolated)) &&
(kerSize == 3 || kerSize == 5) && (blockSize == 3 || blockSize == 5)) && IPP_VERSION_MAJOR >= 8,
ipp_cornerMinEigenVal( _src, _dst, blockSize, ksize, borderType ));
Mat src = _src.getMat();
_dst.create( src.size(), CV_32FC1 );
Mat dst = _dst.getMat();
cornerEigenValsVecs( src, dst, blockSize, ksize, MINEIGENVAL, 0, borderType );
}
#if defined(HAVE_IPP)
namespace cv
{
static bool ipp_cornerHarris( InputArray _src, OutputArray _dst, int blockSize, int ksize, double k, int borderType )
{
#if IPP_VERSION_X100 >= 801 && 0
CV_IPP_CHECK()
Mat src = _src.getMat();
_dst.create( src.size(), CV_32FC1 );
Mat dst = _dst.getMat();
{
int type = src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
int borderTypeNI = borderType & ~BORDER_ISOLATED;
@ -643,14 +672,38 @@ void cv::cornerHarris( InputArray _src, OutputArray _dst, int blockSize, int ksi
if (status >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
return true;
}
}
setIppErrorStatus();
}
}
#else
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(blockSize); CV_UNUSED(ksize); CV_UNUSED(k); CV_UNUSED(borderType);
#endif
return false;
}
}
#endif
void cv::cornerHarris( InputArray _src, OutputArray _dst, int blockSize, int ksize, double k, int borderType )
{
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_cornerMinEigenValVecs(_src, _dst, blockSize, ksize, k, borderType, HARRIS))
#ifdef HAVE_IPP
int borderTypeNI = borderType & ~BORDER_ISOLATED;
bool isolated = (borderType & BORDER_ISOLATED) != 0;
#endif
CV_IPP_RUN(((ksize == 3 || ksize == 5) && (_src.type() == CV_8UC1 || _src.type() == CV_32FC1) &&
(borderTypeNI == BORDER_CONSTANT || borderTypeNI == BORDER_REPLICATE) && CV_MAT_CN(_src.type()) == 1 &&
(!_src.isSubmatrix() || isolated)) && IPP_VERSION_X100 >= 801 && 0, ipp_cornerHarris( _src, _dst, blockSize, ksize, k, borderType ));
Mat src = _src.getMat();
_dst.create( src.size(), CV_32FC1 );
Mat dst = _dst.getMat();
cornerEigenValsVecs( src, dst, blockSize, ksize, HARRIS, k, borderType );
}

@ -547,7 +547,39 @@ static bool IPPDerivSobel(InputArray _src, OutputArray _dst, int ddepth, int dx,
}
return false;
}
#ifdef HAVE_IPP
static bool ipp_sobel(InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, int ksize, double scale, double delta, int borderType)
{
if (ksize < 0)
{
if (IPPDerivScharr(_src, _dst, ddepth, dx, dy, scale, delta, borderType))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return true;
}
}
else if (0 < ksize)
{
if (IPPDerivSobel(_src, _dst, ddepth, dx, dy, ksize, scale, delta, borderType))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return true;
}
}
return false;
}
static bool ipp_scharr(InputArray _src, OutputArray _dst, int ddepth, int dx, int dy, double scale, double delta, int borderType)
{
#if IPP_VERSION_MAJOR >= 7
if (IPPDerivScharr(_src, _dst, ddepth, dx, dy, scale, delta, borderType))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return true;
}
#endif
return false;
}
#endif
}
#endif
@ -572,27 +604,10 @@ void cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
}
#endif
#ifdef HAVE_IPP
CV_IPP_CHECK()
{
if (ksize < 0)
{
if (IPPDerivScharr(_src, _dst, ddepth, dx, dy, scale, delta, borderType))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
}
else if (0 < ksize)
{
if (IPPDerivSobel(_src, _dst, ddepth, dx, dy, ksize, scale, delta, borderType))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
}
}
#endif
CV_IPP_RUN(true, ipp_sobel(_src, _dst, ddepth, dx, dy, ksize, scale, delta, borderType));
int ktype = std::max(CV_32F, std::max(ddepth, sdepth));
Mat kx, ky;
@ -628,16 +643,10 @@ void cv::Scharr( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
}
#endif
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
CV_IPP_CHECK()
{
if (IPPDerivScharr(_src, _dst, ddepth, dx, dy, scale, delta, borderType))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
}
#endif
CV_IPP_RUN(true, ipp_scharr(_src, _dst, ddepth, dx, dy, scale, delta, borderType));
int ktype = std::max(CV_32F, std::max(ddepth, sdepth));
Mat kx, ky;
@ -799,33 +808,30 @@ static bool ocl_Laplacian5(InputArray _src, OutputArray _dst,
#endif
void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
double scale, double delta, int borderType )
#if defined(HAVE_IPP)
namespace cv
{
static bool ipp_Laplacian(InputArray _src, OutputArray _dst, int ddepth, int ksize,
double scale, double delta, int borderType)
{
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if (ddepth < 0)
ddepth = sdepth;
_dst.create( _src.size(), CV_MAKETYPE(ddepth, cn) );
#ifdef HAVE_IPP
CV_IPP_CHECK()
{
if ((ksize == 3 || ksize == 5) && ((borderType & BORDER_ISOLATED) != 0 || !_src.isSubmatrix()) &&
((stype == CV_8UC1 && ddepth == CV_16S) || (ddepth == CV_32F && stype == CV_32FC1)) && !ocl::useOpenCL())
{
int iscale = saturate_cast<int>(scale), idelta = saturate_cast<int>(delta);
bool floatScale = std::fabs(scale - iscale) > DBL_EPSILON, needScale = iscale != 1;
bool floatDelta = std::fabs(delta - idelta) > DBL_EPSILON, needDelta = delta != 0;
int borderTypeNI = borderType & ~BORDER_ISOLATED;
Mat src = _src.getMat(), dst = _dst.getMat();
int iscale = saturate_cast<int>(scale), idelta = saturate_cast<int>(delta);
bool floatScale = std::fabs(scale - iscale) > DBL_EPSILON, needScale = iscale != 1;
bool floatDelta = std::fabs(delta - idelta) > DBL_EPSILON, needDelta = delta != 0;
int borderTypeNI = borderType & ~BORDER_ISOLATED;
Mat src = _src.getMat(), dst = _dst.getMat();
if (src.data != dst.data)
{
Ipp32s bufsize;
IppStatus status = (IppStatus)-1;
IppiSize roisize = { src.cols, src.rows };
IppiMaskSize masksize = ksize == 3 ? ippMskSize3x3 : ippMskSize5x5;
IppiBorderType borderTypeIpp = ippiGetBorderType(borderTypeNI);
if (src.data != dst.data)
{
Ipp32s bufsize;
IppStatus status = (IppStatus)-1;
IppiSize roisize = { src.cols, src.rows };
IppiMaskSize masksize = ksize == 3 ? ippMskSize3x3 : ippMskSize5x5;
IppiBorderType borderTypeIpp = ippiGetBorderType(borderTypeNI);
#define IPP_FILTER_LAPLACIAN(ippsrctype, ippdsttype, ippfavor) \
do \
@ -839,39 +845,51 @@ void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
} \
} while ((void)0, 0)
CV_SUPPRESS_DEPRECATED_START
if (sdepth == CV_8U && ddepth == CV_16S && !floatScale && !floatDelta)
{
IPP_FILTER_LAPLACIAN(Ipp8u, Ipp16s, 8u16s);
if (needScale && status >= 0)
status = ippiMulC_16s_C1IRSfs((Ipp16s)iscale, dst.ptr<Ipp16s>(), (int)dst.step, roisize, 0);
if (needDelta && status >= 0)
status = ippiAddC_16s_C1IRSfs((Ipp16s)idelta, dst.ptr<Ipp16s>(), (int)dst.step, roisize, 0);
}
else if (sdepth == CV_32F && ddepth == CV_32F)
{
IPP_FILTER_LAPLACIAN(Ipp32f, Ipp32f, 32f);
CV_SUPPRESS_DEPRECATED_START
if (sdepth == CV_8U && ddepth == CV_16S && !floatScale && !floatDelta)
{
IPP_FILTER_LAPLACIAN(Ipp8u, Ipp16s, 8u16s);
if (needScale && status >= 0)
status = ippiMulC_32f_C1IR((Ipp32f)scale, dst.ptr<Ipp32f>(), (int)dst.step, roisize);
if (needDelta && status >= 0)
status = ippiAddC_32f_C1IR((Ipp32f)delta, dst.ptr<Ipp32f>(), (int)dst.step, roisize);
}
CV_SUPPRESS_DEPRECATED_END
if (needScale && status >= 0)
status = ippiMulC_16s_C1IRSfs((Ipp16s)iscale, dst.ptr<Ipp16s>(), (int)dst.step, roisize, 0);
if (needDelta && status >= 0)
status = ippiAddC_16s_C1IRSfs((Ipp16s)idelta, dst.ptr<Ipp16s>(), (int)dst.step, roisize, 0);
}
else if (sdepth == CV_32F && ddepth == CV_32F)
{
IPP_FILTER_LAPLACIAN(Ipp32f, Ipp32f, 32f);
if (status >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
}
if (needScale && status >= 0)
status = ippiMulC_32f_C1IR((Ipp32f)scale, dst.ptr<Ipp32f>(), (int)dst.step, roisize);
if (needDelta && status >= 0)
status = ippiAddC_32f_C1IR((Ipp32f)delta, dst.ptr<Ipp32f>(), (int)dst.step, roisize);
}
#undef IPP_FILTER_LAPLACIAN
CV_SUPPRESS_DEPRECATED_END
if (status >= 0)
return true;
}
#undef IPP_FILTER_LAPLACIAN
return false;
}
}
#endif
void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
double scale, double delta, int borderType )
{
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if (ddepth < 0)
ddepth = sdepth;
_dst.create( _src.size(), CV_MAKETYPE(ddepth, cn) );
CV_IPP_RUN((ksize == 3 || ksize == 5) && ((borderType & BORDER_ISOLATED) != 0 || !_src.isSubmatrix()) &&
((stype == CV_8UC1 && ddepth == CV_16S) || (ddepth == CV_32F && stype == CV_32FC1)) && (!cv::ocl::useOpenCL()),
ipp_Laplacian(_src, _dst, ddepth, ksize, scale, delta, borderType));
#ifdef HAVE_TEGRA_OPTIMIZATION
if (tegra::useTegra() && scale == 1.0 && delta == 0)
{

@ -4555,6 +4555,96 @@ cv::Ptr<cv::FilterEngine> cv::createLinearFilter( int _srcType, int _dstType,
_rowBorderType, _columnBorderType, _borderValue );
}
#ifdef HAVE_IPP
namespace cv
{
static bool ipp_filter2D( InputArray _src, OutputArray _dst, int ddepth,
InputArray _kernel, Point anchor0,
double delta, int borderType )
{
#if !HAVE_ICV
Mat src = _src.getMat(), kernel = _kernel.getMat();
if( ddepth < 0 )
ddepth = src.depth();
_dst.create( src.size(), CV_MAKETYPE(ddepth, src.channels()) );
Mat dst = _dst.getMat();
Point anchor = normalizeAnchor(anchor0, kernel.size());
typedef IppStatus (CV_STDCALL * ippiFilterBorder)(const void * pSrc, int srcStep, void * pDst, int dstStep, IppiSize dstRoiSize,
IppiBorderType border, const void * borderValue,
const IppiFilterBorderSpec* pSpec, Ipp8u* pBuffer);
int stype = src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype),
ktype = kernel.type(), kdepth = CV_MAT_DEPTH(ktype);
bool isolated = (borderType & BORDER_ISOLATED) != 0;
Point ippAnchor(kernel.cols >> 1, kernel.rows >> 1);
int borderTypeNI = borderType & ~BORDER_ISOLATED;
IppiBorderType ippBorderType = ippiGetBorderType(borderTypeNI);
if (borderTypeNI == BORDER_CONSTANT || borderTypeNI == BORDER_REPLICATE)
{
ippiFilterBorder ippFunc =
stype == CV_8UC1 ? (ippiFilterBorder)ippiFilterBorder_8u_C1R :
stype == CV_8UC3 ? (ippiFilterBorder)ippiFilterBorder_8u_C3R :
stype == CV_8UC4 ? (ippiFilterBorder)ippiFilterBorder_8u_C4R :
stype == CV_16UC1 ? (ippiFilterBorder)ippiFilterBorder_16u_C1R :
stype == CV_16UC3 ? (ippiFilterBorder)ippiFilterBorder_16u_C3R :
stype == CV_16UC4 ? (ippiFilterBorder)ippiFilterBorder_16u_C4R :
stype == CV_16SC1 ? (ippiFilterBorder)ippiFilterBorder_16s_C1R :
stype == CV_16SC3 ? (ippiFilterBorder)ippiFilterBorder_16s_C3R :
stype == CV_16SC4 ? (ippiFilterBorder)ippiFilterBorder_16s_C4R :
stype == CV_32FC1 ? (ippiFilterBorder)ippiFilterBorder_32f_C1R :
stype == CV_32FC3 ? (ippiFilterBorder)ippiFilterBorder_32f_C3R :
stype == CV_32FC4 ? (ippiFilterBorder)ippiFilterBorder_32f_C4R : 0;
if (sdepth == ddepth && (ktype == CV_16SC1 || ktype == CV_32FC1) &&
ippFunc && (int)ippBorderType >= 0 && (!src.isSubmatrix() || isolated) &&
std::fabs(delta - 0) < DBL_EPSILON && ippAnchor == anchor && dst.data != src.data)
{
IppiSize kernelSize = { kernel.cols, kernel.rows }, dstRoiSize = { dst.cols, dst.rows };
IppDataType dataType = ippiGetDataType(ddepth), kernelType = ippiGetDataType(kdepth);
Ipp32s specSize = 0, bufsize = 0;
IppStatus status = (IppStatus)-1;
if ((status = ippiFilterBorderGetSize(kernelSize, dstRoiSize, dataType, kernelType, cn, &specSize, &bufsize)) >= 0)
{
IppiFilterBorderSpec * spec = (IppiFilterBorderSpec *)ippMalloc(specSize);
Ipp8u * buffer = ippsMalloc_8u(bufsize);
Ipp32f borderValue[4] = { 0, 0, 0, 0 };
Mat reversedKernel;
flip(kernel, reversedKernel, -1);
if ((kdepth == CV_32F && (status = ippiFilterBorderInit_32f((const Ipp32f *)reversedKernel.data, kernelSize,
dataType, cn, ippRndFinancial, spec)) >= 0 ) ||
(kdepth == CV_16S && (status = ippiFilterBorderInit_16s((const Ipp16s *)reversedKernel.data,
kernelSize, 0, dataType, cn, ippRndFinancial, spec)) >= 0))
{
status = ippFunc(src.data, (int)src.step, dst.data, (int)dst.step, dstRoiSize,
ippBorderType, borderValue, spec, buffer);
}
ippsFree(buffer);
ippsFree(spec);
}
if (status >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return true;
}
}
}
#else
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(ddepth); CV_UNUSED(_kernel), CV_UNUSED(anchor0), CV_UNUSED(delta), CV_UNUSED(borderType);
#endif
return false;
}
}
#endif
void cv::filter2D( InputArray _src, OutputArray _dst, int ddepth,
InputArray _kernel, Point anchor0,
@ -4579,77 +4669,8 @@ void cv::filter2D( InputArray _src, OutputArray _dst, int ddepth,
Mat dst = _dst.getMat();
Point anchor = normalizeAnchor(anchor0, kernel.size());
#if IPP_VERSION_X100 > 0 && !defined HAVE_IPP_ICV_ONLY
CV_IPP_CHECK()
{
typedef IppStatus (CV_STDCALL * ippiFilterBorder)(const void * pSrc, int srcStep, void * pDst, int dstStep, IppiSize dstRoiSize,
IppiBorderType border, const void * borderValue,
const IppiFilterBorderSpec* pSpec, Ipp8u* pBuffer);
int stype = src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype),
ktype = kernel.type(), kdepth = CV_MAT_DEPTH(ktype);
bool isolated = (borderType & BORDER_ISOLATED) != 0;
Point ippAnchor(kernel.cols >> 1, kernel.rows >> 1);
int borderTypeNI = borderType & ~BORDER_ISOLATED;
IppiBorderType ippBorderType = ippiGetBorderType(borderTypeNI);
if (borderTypeNI == BORDER_CONSTANT || borderTypeNI == BORDER_REPLICATE)
{
ippiFilterBorder ippFunc =
stype == CV_8UC1 ? (ippiFilterBorder)ippiFilterBorder_8u_C1R :
stype == CV_8UC3 ? (ippiFilterBorder)ippiFilterBorder_8u_C3R :
stype == CV_8UC4 ? (ippiFilterBorder)ippiFilterBorder_8u_C4R :
stype == CV_16UC1 ? (ippiFilterBorder)ippiFilterBorder_16u_C1R :
stype == CV_16UC3 ? (ippiFilterBorder)ippiFilterBorder_16u_C3R :
stype == CV_16UC4 ? (ippiFilterBorder)ippiFilterBorder_16u_C4R :
stype == CV_16SC1 ? (ippiFilterBorder)ippiFilterBorder_16s_C1R :
stype == CV_16SC3 ? (ippiFilterBorder)ippiFilterBorder_16s_C3R :
stype == CV_16SC4 ? (ippiFilterBorder)ippiFilterBorder_16s_C4R :
stype == CV_32FC1 ? (ippiFilterBorder)ippiFilterBorder_32f_C1R :
stype == CV_32FC3 ? (ippiFilterBorder)ippiFilterBorder_32f_C3R :
stype == CV_32FC4 ? (ippiFilterBorder)ippiFilterBorder_32f_C4R : 0;
if (sdepth == ddepth && (ktype == CV_16SC1 || ktype == CV_32FC1) &&
ippFunc && (int)ippBorderType >= 0 && (!src.isSubmatrix() || isolated) &&
std::fabs(delta - 0) < DBL_EPSILON && ippAnchor == anchor && dst.data != src.data)
{
IppiSize kernelSize = { kernel.cols, kernel.rows }, dstRoiSize = { dst.cols, dst.rows };
IppDataType dataType = ippiGetDataType(ddepth), kernelType = ippiGetDataType(kdepth);
Ipp32s specSize = 0, bufsize = 0;
IppStatus status = (IppStatus)-1;
if ((status = ippiFilterBorderGetSize(kernelSize, dstRoiSize, dataType, kernelType, cn, &specSize, &bufsize)) >= 0)
{
IppiFilterBorderSpec * spec = (IppiFilterBorderSpec *)ippMalloc(specSize);
Ipp8u * buffer = ippsMalloc_8u(bufsize);
Ipp32f borderValue[4] = { 0, 0, 0, 0 };
Mat reversedKernel;
flip(kernel, reversedKernel, -1);
if ((kdepth == CV_32F && (status = ippiFilterBorderInit_32f((const Ipp32f *)reversedKernel.data, kernelSize,
dataType, cn, ippRndFinancial, spec)) >= 0 ) ||
(kdepth == CV_16S && (status = ippiFilterBorderInit_16s((const Ipp16s *)reversedKernel.data,
kernelSize, 0, dataType, cn, ippRndFinancial, spec)) >= 0))
{
status = ippFunc(src.data, (int)src.step, dst.data, (int)dst.step, dstRoiSize,
ippBorderType, borderValue, spec, buffer);
}
ippsFree(buffer);
ippsFree(spec);
}
CV_IPP_RUN(true, ipp_filter2D(_src, _dst, ddepth, _kernel, anchor0, delta, borderType));
if (status >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
}
}
}
#endif
#ifdef HAVE_TEGRA_OPTIMIZATION
if( tegra::useTegra() && tegra::filter2D(src, dst, kernel, anchor, delta, borderType) )

@ -1220,7 +1220,10 @@ private:
}
void cv::calcHist( const Mat* images, int nimages, const int* channels,
#if defined(HAVE_IPP)
namespace cv
{
static bool ipp_calchist(const Mat* images, int nimages, const int* channels,
InputArray _mask, OutputArray _hist, int dims, const int* histSize,
const float** ranges, bool uniform, bool accumulate )
{
@ -1228,13 +1231,10 @@ void cv::calcHist( const Mat* images, int nimages, const int* channels,
CV_Assert(dims > 0 && histSize);
const uchar* const histdata = _hist.getMat().ptr();
_hist.create(dims, histSize, CV_32F);
Mat hist = _hist.getMat(), ihist = hist;
ihist.flags = (ihist.flags & ~CV_MAT_TYPE_MASK)|CV_32S;
#ifdef HAVE_IPP
CV_IPP_CHECK()
{
if (nimages == 1 && images[0].type() == CV_8UC1 && dims == 1 && channels &&
channels[0] == 0 && mask.empty() && images[0].dims <= 2 &&
@ -1256,14 +1256,37 @@ void cv::calcHist( const Mat* images, int nimages, const int* channels,
if (ok)
{
ihist.convertTo(hist, CV_32F);
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
return;
CV_IMPL_ADD(CV_IMPL_IPP);
return true;
}
setIppErrorStatus();
}
}
return false;
}
}
#endif
void cv::calcHist( const Mat* images, int nimages, const int* channels,
InputArray _mask, OutputArray _hist, int dims, const int* histSize,
const float** ranges, bool uniform, bool accumulate )
{
CV_IPP_RUN(nimages == 1 && images[0].type() == CV_8UC1 && dims == 1 && channels &&
channels[0] == 0 && _mask.getMat().empty() && images[0].dims <= 2 &&
!accumulate && uniform,
ipp_calchist(images, nimages, channels,
_mask, _hist, dims, histSize,
ranges, uniform, accumulate));
Mat mask = _mask.getMat();
CV_Assert(dims > 0 && histSize);
const uchar* const histdata = _hist.getMat().ptr();
_hist.create(dims, histSize, CV_32F);
Mat hist = _hist.getMat(), ihist = hist;
ihist.flags = (ihist.flags & ~CV_MAT_TYPE_MASK)|CV_32S;
if( !accumulate || histdata != hist.data )
hist = Scalar(0.);
else

@ -3092,8 +3092,33 @@ static bool ocl_resize( InputArray _src, OutputArray _dst, Size dsize,
#endif
#if IPP_VERSION_X100 >= 701
static bool ipp_resize_mt( Mat src, Mat dst,
double inv_scale_x, double inv_scale_y, int interpolation)
{
int mode = -1;
if (interpolation == INTER_LINEAR && src.rows >= 2 && src.cols >= 2)
mode = ippLinear;
else if (interpolation == INTER_CUBIC && src.rows >= 4 && src.cols >= 4)
mode = ippCubic;
else
return false;
bool ok = true;
Range range(0, src.rows);
IPPresizeInvoker invoker(src, dst, inv_scale_x, inv_scale_y, mode, &ok);
parallel_for_(range, invoker, dst.total()/(double)(1<<16));
if( ok )
return true;
return false;
}
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
@ -3219,6 +3244,17 @@ void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
inv_scale_y = (double)dsize.height/ssize.height;
}
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
double scale_x = 1./inv_scale_x, scale_y = 1./inv_scale_y;
int iscale_x = saturate_cast<int>(scale_x);
int iscale_y = saturate_cast<int>(scale_y);
bool is_area_fast = std::abs(scale_x - iscale_x) < DBL_EPSILON &&
std::abs(scale_y - iscale_y) < DBL_EPSILON;
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat() && _src.cols() > 10 && _src.rows() > 10,
ocl_resize(_src, _dst, dsize, inv_scale_x, inv_scale_y, interpolation))
@ -3231,53 +3267,23 @@ void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
return;
#endif
int type = src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
double scale_x = 1./inv_scale_x, scale_y = 1./inv_scale_y;
int k, sx, sy, dx, dy;
int iscale_x = saturate_cast<int>(scale_x);
int iscale_y = saturate_cast<int>(scale_y);
#ifdef HAVE_IPP
int mode = -1;
if (interpolation == INTER_LINEAR && _src.rows() >= 2 && _src.cols() >= 2)
mode = INTER_LINEAR;
else if (interpolation == INTER_CUBIC && _src.rows() >= 4 && _src.cols() >= 4)
mode = INTER_CUBIC;
bool is_area_fast = std::abs(scale_x - iscale_x) < DBL_EPSILON &&
std::abs(scale_y - iscale_y) < DBL_EPSILON;
#if IPP_VERSION_X100 >= 701
CV_IPP_CHECK()
{
#define IPP_RESIZE_EPS 1e-10
double ex = fabs((double)dsize.width / src.cols - inv_scale_x) / inv_scale_x;
double ey = fabs((double)dsize.height / src.rows - inv_scale_y) / inv_scale_y;
if ( ((ex < IPP_RESIZE_EPS && ey < IPP_RESIZE_EPS && depth != CV_64F) || (ex == 0 && ey == 0 && depth == CV_64F)) &&
(interpolation == INTER_LINEAR || interpolation == INTER_CUBIC) &&
!(interpolation == INTER_LINEAR && is_area_fast && iscale_x == 2 && iscale_y == 2 && depth == CV_8U))
{
int mode = -1;
if (interpolation == INTER_LINEAR && src.rows >= 2 && src.cols >= 2)
mode = ippLinear;
else if (interpolation == INTER_CUBIC && src.rows >= 4 && src.cols >= 4)
mode = ippCubic;
if( mode >= 0 && (cn == 1 || cn == 3 || cn == 4) &&
(depth == CV_16U || depth == CV_16S || depth == CV_32F ||
(depth == CV_64F && mode == ippLinear)))
{
bool ok = true;
Range range(0, src.rows);
IPPresizeInvoker invoker(src, dst, inv_scale_x, inv_scale_y, mode, &ok);
parallel_for_(range, invoker, dst.total()/(double)(1<<16));
if( ok )
{
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
return;
}
setIppErrorStatus();
}
}
#undef IPP_RESIZE_EPS
}
const double IPP_RESIZE_EPS = 1e-10;
double ex = fabs((double)dsize.width / _src.cols() - inv_scale_x) / inv_scale_x;
double ey = fabs((double)dsize.height / _src.rows() - inv_scale_y) / inv_scale_y;
#endif
CV_IPP_RUN(IPP_VERSION_X100 >= 701 && ((ex < IPP_RESIZE_EPS && ey < IPP_RESIZE_EPS && depth != CV_64F) || (ex == 0 && ey == 0 && depth == CV_64F)) &&
(interpolation == INTER_LINEAR || interpolation == INTER_CUBIC) &&
!(interpolation == INTER_LINEAR && is_area_fast && iscale_x == 2 && iscale_y == 2 && depth == CV_8U) &&
mode >= 0 && (cn == 1 || cn == 3 || cn == 4) && (depth == CV_16U || depth == CV_16S || depth == CV_32F ||
(depth == CV_64F && mode == INTER_LINEAR)), ipp_resize_mt(src, dst, inv_scale_x, inv_scale_y, interpolation))
if( interpolation == INTER_NEAREST )
{
@ -3285,6 +3291,9 @@ void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
return;
}
int k, sx, sy, dx, dy;
{
// in case of scale_x && scale_y is equal to 2
// INTER_AREA (fast) also is equal to INTER_LINEAR

@ -1136,10 +1136,11 @@ private:
Scalar borderValue;
};
#if IPP_VERSION_X100 >= 801
static bool IPPMorphReplicate(int op, const Mat &src, Mat &dst, const Mat &kernel,
#ifdef HAVE_IPP
static bool ipp_MorphReplicate(int op, const Mat &src, Mat &dst, const Mat &kernel,
const Size& ksize, const Point &anchor, bool rectKernel)
{
#if IPP_VERSION_X100 >= 801
int type = src.type();
const Mat* _src = &src;
Mat temp;
@ -1257,10 +1258,13 @@ static bool IPPMorphReplicate(int op, const Mat &src, Mat &dst, const Mat &kerne
}
#undef IPP_MORPH_CASE
}
#else
CV_UNUSED(op); CV_UNUSED(src); CV_UNUSED(dst); CV_UNUSED(kernel); CV_UNUSED(ksize); CV_UNUSED(anchor); CV_UNUSED(rectKernel);
#endif
return false;
}
static bool IPPMorphOp(int op, InputArray _src, OutputArray _dst,
static bool ipp_MorphOp(int op, InputArray _src, OutputArray _dst,
const Mat& _kernel, Point anchor, int iterations,
int borderType, const Scalar &borderValue)
{
@ -1331,7 +1335,7 @@ static bool IPPMorphOp(int op, InputArray _src, OutputArray _dst,
if( iterations > 1 )
return false;
return IPPMorphReplicate( op, src, dst, kernel, ksize, anchor, rectKernel );
return ipp_MorphReplicate( op, src, dst, kernel, ksize, anchor, rectKernel );
}
#endif
@ -1711,16 +1715,7 @@ static void morphOp( int op, InputArray _src, OutputArray _dst,
iterations = 1;
}
#if IPP_VERSION_X100 >= 801
CV_IPP_CHECK()
{
if( IPPMorphOp(op, _src, _dst, kernel, anchor, iterations, borderType, borderValue) )
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
}
#endif
CV_IPP_RUN(IPP_VERSION_X100 >= 801, ipp_MorphOp(op, _src, _dst, kernel, anchor, iterations, borderType, borderValue))
Mat src = _src.getMat();
_dst.create( src.size(), src.type() );

@ -1166,65 +1166,92 @@ static bool ocl_pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz, int
}
void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )
#if defined(HAVE_IPP)
namespace cv
{
CV_Assert(borderType != BORDER_CONSTANT);
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_pyrDown(_src, _dst, _dsz, borderType))
static bool ipp_pyrdown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )
{
#if IPP_VERSION_X100 >= 801 && 0
Size dsz = _dsz.area() == 0 ? Size((_src.cols() + 1)/2, (_src.rows() + 1)/2) : _dsz;
bool isolated = (borderType & BORDER_ISOLATED) != 0;
int borderTypeNI = borderType & ~BORDER_ISOLATED;
Mat src = _src.getMat();
Size dsz = _dsz.area() == 0 ? Size((src.cols + 1)/2, (src.rows + 1)/2) : _dsz;
_dst.create( dsz, src.type() );
Mat dst = _dst.getMat();
int depth = src.depth();
#ifdef HAVE_TEGRA_OPTIMIZATION
if(borderType == BORDER_DEFAULT && tegra::useTegra() && tegra::pyrDown(src, dst))
return;
#endif
#if IPP_VERSION_X100 >= 801 && 0
CV_IPP_CHECK()
{
bool isolated = (borderType & BORDER_ISOLATED) != 0;
int borderTypeNI = borderType & ~BORDER_ISOLATED;
if (borderTypeNI == BORDER_DEFAULT && (!src.isSubmatrix() || isolated) && dsz == Size((src.cols + 1)/2, (src.rows + 1)/2))
if (borderTypeNI == BORDER_DEFAULT && (!src.isSubmatrix() || isolated) && dsz == Size(src.cols*2, src.rows*2))
{
typedef IppStatus (CV_STDCALL * ippiPyrDown)(const void* pSrc, int srcStep, void* pDst, int dstStep, IppiSize srcRoi, Ipp8u* buffer);
typedef IppStatus (CV_STDCALL * ippiPyrUp)(const void* pSrc, int srcStep, void* pDst, int dstStep, IppiSize srcRoi, Ipp8u* buffer);
int type = src.type();
CV_SUPPRESS_DEPRECATED_START
ippiPyrDown pyrDownFunc = type == CV_8UC1 ? (ippiPyrDown) ippiPyrDown_Gauss5x5_8u_C1R :
type == CV_8UC3 ? (ippiPyrDown) ippiPyrDown_Gauss5x5_8u_C3R :
type == CV_32FC1 ? (ippiPyrDown) ippiPyrDown_Gauss5x5_32f_C1R :
type == CV_32FC3 ? (ippiPyrDown) ippiPyrDown_Gauss5x5_32f_C3R : 0;
ippiPyrUp pyrUpFunc = type == CV_8UC1 ? (ippiPyrUp) ippiPyrUp_Gauss5x5_8u_C1R :
type == CV_8UC3 ? (ippiPyrUp) ippiPyrUp_Gauss5x5_8u_C3R :
type == CV_32FC1 ? (ippiPyrUp) ippiPyrUp_Gauss5x5_32f_C1R :
type == CV_32FC3 ? (ippiPyrUp) ippiPyrUp_Gauss5x5_32f_C3R : 0;
CV_SUPPRESS_DEPRECATED_END
if (pyrDownFunc)
if (pyrUpFunc)
{
int bufferSize;
IppiSize srcRoi = { src.cols, src.rows };
IppDataType dataType = depth == CV_8U ? ipp8u : ipp32f;
CV_SUPPRESS_DEPRECATED_START
IppStatus ok = ippiPyrDownGetBufSize_Gauss5x5(srcRoi.width, dataType, src.channels(), &bufferSize);
IppStatus ok = ippiPyrUpGetBufSize_Gauss5x5(srcRoi.width, dataType, src.channels(), &bufferSize);
CV_SUPPRESS_DEPRECATED_END
if (ok >= 0)
{
Ipp8u* buffer = ippsMalloc_8u(bufferSize);
ok = pyrDownFunc(src.data, (int) src.step, dst.data, (int) dst.step, srcRoi, buffer);
ok = pyrUpFunc(src.data, (int) src.step, dst.data, (int) dst.step, srcRoi, buffer);
ippsFree(buffer);
if (ok >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
return true;
}
setIppErrorStatus();
}
}
}
}
#else
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(_dsz); CV_UNUSED(borderType);
#endif
return false;
}
}
#endif
void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )
{
CV_Assert(borderType != BORDER_CONSTANT);
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_pyrDown(_src, _dst, _dsz, borderType))
Mat src = _src.getMat();
Size dsz = _dsz.area() == 0 ? Size((src.cols + 1)/2, (src.rows + 1)/2) : _dsz;
_dst.create( dsz, src.type() );
Mat dst = _dst.getMat();
int depth = src.depth();
#ifdef HAVE_TEGRA_OPTIMIZATION
if(borderType == BORDER_DEFAULT && tegra::useTegra() && tegra::pyrDown(src, dst))
return;
#endif
#ifdef HAVE_IPP
bool isolated = (borderType & BORDER_ISOLATED) != 0;
int borderTypeNI = borderType & ~BORDER_ISOLATED;
#endif
CV_IPP_RUN(borderTypeNI == BORDER_DEFAULT && (!_src.isSubmatrix() || isolated) && dsz == Size((_src.cols() + 1)/2, (_src.rows() + 1)/2),
ipp_pyrdown( _src, _dst, _dsz, borderType));
PyrFunc func = 0;
if( depth == CV_8U )
@ -1243,26 +1270,21 @@ void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borde
func( src, dst, borderType );
}
void cv::pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )
{
CV_Assert(borderType == BORDER_DEFAULT);
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_pyrUp(_src, _dst, _dsz, borderType))
#if defined(HAVE_IPP)
namespace cv
{
static bool ipp_pyrup( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )
{
#if IPP_VERSION_X100 >= 801 && 0
Size sz = _src.dims() <= 2 ? _src.size() : Size();
Size dsz = _dsz.area() == 0 ? Size(_src.cols()*2, _src.rows()*2) : _dsz;
Mat src = _src.getMat();
Size dsz = _dsz.area() == 0 ? Size(src.cols*2, src.rows*2) : _dsz;
_dst.create( dsz, src.type() );
Mat dst = _dst.getMat();
int depth = src.depth();
#ifdef HAVE_TEGRA_OPTIMIZATION
if(borderType == BORDER_DEFAULT && tegra::useTegra() && tegra::pyrUp(src, dst))
return;
#endif
#if IPP_VERSION_X100 >= 801 && 0
CV_IPP_CHECK()
{
bool isolated = (borderType & BORDER_ISOLATED) != 0;
int borderTypeNI = borderType & ~BORDER_ISOLATED;
@ -1294,15 +1316,47 @@ void cv::pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz, int borderT
if (ok >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
return true;
}
setIppErrorStatus();
}
}
}
}
#else
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(_dsz); CV_UNUSED(borderType);
#endif
return false;
}
}
#endif
void cv::pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )
{
CV_Assert(borderType == BORDER_DEFAULT);
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_pyrUp(_src, _dst, _dsz, borderType))
Mat src = _src.getMat();
Size dsz = _dsz.area() == 0 ? Size(src.cols*2, src.rows*2) : _dsz;
_dst.create( dsz, src.type() );
Mat dst = _dst.getMat();
int depth = src.depth();
#ifdef HAVE_TEGRA_OPTIMIZATION
if(borderType == BORDER_DEFAULT && tegra::useTegra() && tegra::pyrUp(src, dst))
return;
#endif
#ifdef HAVE_IPP
bool isolated = (borderType & BORDER_ISOLATED) != 0;
int borderTypeNI = borderType & ~BORDER_ISOLATED;
#endif
CV_IPP_RUN(borderTypeNI == BORDER_DEFAULT && (!_src.isSubmatrix() || isolated) && dsz == Size(_src.cols()*2, _src.rows()*2),
ipp_pyrup( _src, _dst, _dsz, borderType));
PyrFunc func = 0;
if( depth == CV_8U )
func = pyrUp_<FixPtCast<uchar, 6>, PyrUpVec_32s8u >;
@ -1320,28 +1374,19 @@ void cv::pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz, int borderT
func( src, dst, borderType );
}
void cv::buildPyramid( InputArray _src, OutputArrayOfArrays _dst, int maxlevel, int borderType )
{
CV_Assert(borderType != BORDER_CONSTANT);
if (_src.dims() <= 2 && _dst.isUMatVector())
{
UMat src = _src.getUMat();
_dst.create( maxlevel + 1, 1, 0 );
_dst.getUMatRef(0) = src;
for( int i = 1; i <= maxlevel; i++ )
pyrDown( _dst.getUMatRef(i-1), _dst.getUMatRef(i), Size(), borderType );
return;
}
#if 0 //#ifdef HAVE_IPP
namespace cv
{
static bool ipp_buildpyramid( InputArray _src, OutputArrayOfArrays _dst, int maxlevel, int borderType )
{
#if IPP_VERSION_X100 >= 801 && 0
Mat src = _src.getMat();
_dst.create( maxlevel + 1, 1, 0 );
_dst.getMatRef(0) = src;
int i=1;
#if IPP_VERSION_X100 >= 801 && 0
CV_IPP_CHECK()
{
bool isolated = (borderType & BORDER_ISOLATED) != 0;
int borderTypeNI = borderType & ~BORDER_ISOLATED;
@ -1414,8 +1459,8 @@ void cv::buildPyramid( InputArray _src, OutputArrayOfArrays _dst, int maxlevel,
if (ok < 0)
{
setIppErrorStatus();
break;
pyrFreeFunc(gPyr->pState);
return false;
}
else
{
@ -1425,13 +1470,52 @@ void cv::buildPyramid( InputArray _src, OutputArrayOfArrays _dst, int maxlevel,
pyrFreeFunc(gPyr->pState);
}
else
setIppErrorStatus();
{
ippiPyramidFree(gPyr);
return false;
}
ippiPyramidFree(gPyr);
}
return true;
}
return false;
}
#else
CV_UNUSED(_src); CV_UNUSED(_dst); CV_UNUSED(maxlevel); CV_UNUSED(borderType);
#endif
return false;
}
}
#endif
void cv::buildPyramid( InputArray _src, OutputArrayOfArrays _dst, int maxlevel, int borderType )
{
CV_Assert(borderType != BORDER_CONSTANT);
if (_src.dims() <= 2 && _dst.isUMatVector())
{
UMat src = _src.getUMat();
_dst.create( maxlevel + 1, 1, 0 );
_dst.getUMatRef(0) = src;
for( int i = 1; i <= maxlevel; i++ )
pyrDown( _dst.getUMatRef(i-1), _dst.getUMatRef(i), Size(), borderType );
return;
}
Mat src = _src.getMat();
_dst.create( maxlevel + 1, 1, 0 );
_dst.getMatRef(0) = src;
int i=1;
#if (IPP_VERSION_X100 >= 801 && 0)
bool isolated = (borderType & BORDER_ISOLATED) != 0;
int borderTypeNI = borderType & ~BORDER_ISOLATED;
CV_IPP_RUN(((IPP_VERSION_X100 >= 801 && 0) && (borderTypeNI == BORDER_DEFAULT && (!_src.isSubmatrix() || isolated))),
ipp_buildpyramid( _src, _dst, maxlevel, borderType));
#endif
for( ; i <= maxlevel; i++ )
pyrDown( _dst.getMatRef(i-1), _dst.getMatRef(i), Size(), borderType );
}

@ -1303,17 +1303,24 @@ cv::Ptr<cv::FilterEngine> cv::createBoxFilter( int srcType, int dstType, Size ks
srcType, dstType, sumType, borderType );
}
void cv::boxFilter( InputArray _src, OutputArray _dst, int ddepth,
#if defined(HAVE_IPP)
namespace cv
{
static bool ipp_boxfilter( InputArray _src, OutputArray _dst, int ddepth,
Size ksize, Point anchor,
bool normalize, int borderType )
{
CV_OCL_RUN(_dst.isUMat(), ocl_boxFilter(_src, _dst, ddepth, ksize, anchor, borderType, normalize))
Mat src = _src.getMat();
int stype = src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if( ddepth < 0 )
ddepth = sdepth;
int ippBorderType = borderType & ~BORDER_ISOLATED;
Point ocvAnchor, ippAnchor;
ocvAnchor.x = anchor.x < 0 ? ksize.width / 2 : anchor.x;
ocvAnchor.y = anchor.y < 0 ? ksize.height / 2 : anchor.y;
ippAnchor.x = ksize.width / 2 - (ksize.width % 2 == 0 ? 1 : 0);
ippAnchor.y = ksize.height / 2 - (ksize.height % 2 == 0 ? 1 : 0);
Mat src = _src.getMat();
_dst.create( src.size(), CV_MAKETYPE(ddepth, cn) );
Mat dst = _dst.getMat();
if( borderType != BORDER_CONSTANT && normalize && (borderType & BORDER_ISOLATED) != 0 )
@ -1323,21 +1330,8 @@ void cv::boxFilter( InputArray _src, OutputArray _dst, int ddepth,
if( src.cols == 1 )
ksize.width = 1;
}
#ifdef HAVE_TEGRA_OPTIMIZATION
if ( tegra::useTegra() && tegra::box(src, dst, ksize, anchor, normalize, borderType) )
return;
#endif
#if defined(HAVE_IPP)
CV_IPP_CHECK()
{
int ippBorderType = borderType & ~BORDER_ISOLATED;
Point ocvAnchor, ippAnchor;
ocvAnchor.x = anchor.x < 0 ? ksize.width / 2 : anchor.x;
ocvAnchor.y = anchor.y < 0 ? ksize.height / 2 : anchor.y;
ippAnchor.x = ksize.width / 2 - (ksize.width % 2 == 0 ? 1 : 0);
ippAnchor.y = ksize.height / 2 - (ksize.height % 2 == 0 ? 1 : 0);
if (normalize && !src.isSubmatrix() && ddepth == sdepth &&
(/*ippBorderType == BORDER_REPLICATE ||*/ /* returns ippStsStepErr: Step value is not valid */
ippBorderType == BORDER_CONSTANT) && ocvAnchor == ippAnchor &&
@ -1361,10 +1355,9 @@ void cv::boxFilter( InputArray _src, OutputArray _dst, int ddepth,
if (status >= 0) \
{ \
CV_IMPL_ADD(CV_IMPL_IPP); \
return; \
return true; \
} \
} \
setIppErrorStatus(); \
} while ((void)0, 0)
if (stype == CV_8UC1)
@ -1399,13 +1392,57 @@ void cv::boxFilter( InputArray _src, OutputArray _dst, int ddepth,
}
#undef IPP_FILTER_BOX_BORDER
}
return false;
}
}
#endif
void cv::boxFilter( InputArray _src, OutputArray _dst, int ddepth,
Size ksize, Point anchor,
bool normalize, int borderType )
{
CV_OCL_RUN(_dst.isUMat(), ocl_boxFilter(_src, _dst, ddepth, ksize, anchor, borderType, normalize))
Mat src = _src.getMat();
int stype = src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if( ddepth < 0 )
ddepth = sdepth;
_dst.create( src.size(), CV_MAKETYPE(ddepth, cn) );
Mat dst = _dst.getMat();
if( borderType != BORDER_CONSTANT && normalize && (borderType & BORDER_ISOLATED) != 0 )
{
if( src.rows == 1 )
ksize.height = 1;
if( src.cols == 1 )
ksize.width = 1;
}
#ifdef HAVE_TEGRA_OPTIMIZATION
if ( tegra::useTegra() && tegra::box(src, dst, ksize, anchor, normalize, borderType) )
return;
#endif
#ifdef HAVE_IPP
int ippBorderType = borderType & ~BORDER_ISOLATED;
#endif
Point ocvAnchor, ippAnchor;
ocvAnchor.x = anchor.x < 0 ? ksize.width / 2 : anchor.x;
ocvAnchor.y = anchor.y < 0 ? ksize.height / 2 : anchor.y;
ippAnchor.x = ksize.width / 2 - (ksize.width % 2 == 0 ? 1 : 0);
ippAnchor.y = ksize.height / 2 - (ksize.height % 2 == 0 ? 1 : 0);
CV_IPP_RUN((normalize && !_src.isSubmatrix() && ddepth == sdepth &&
(/*ippBorderType == BORDER_REPLICATE ||*/ /* returns ippStsStepErr: Step value is not valid */
ippBorderType == BORDER_CONSTANT) && ocvAnchor == ippAnchor &&
_dst.cols() != ksize.width && _dst.rows() != ksize.height),
ipp_boxfilter( _src, _dst, ddepth, ksize, anchor, normalize, borderType));
Ptr<FilterEngine> f = createBoxFilter( src.type(), dst.type(),
ksize, anchor, normalize, borderType );
f->apply( src, dst );
}
void cv::blur( InputArray src, OutputArray dst,
Size ksize, Point anchor, int borderType )
{
@ -1624,6 +1661,103 @@ cv::Ptr<cv::FilterEngine> cv::createGaussianFilter( int type, Size ksize,
return createSeparableLinearFilter( type, type, kx, ky, Point(-1,-1), 0, borderType );
}
#ifdef HAVE_IPP
namespace cv
{
static bool ipp_GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,
double sigma1, double sigma2,
int borderType )
{
int type = _src.type();
Size size = _src.size();
if( borderType != BORDER_CONSTANT && (borderType & BORDER_ISOLATED) != 0 )
{
if( size.height == 1 )
ksize.height = 1;
if( size.width == 1 )
ksize.width = 1;
}
int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
if ((depth == CV_8U || depth == CV_16U || depth == CV_16S || depth == CV_32F) && (cn == 1 || cn == 3) &&
sigma1 == sigma2 && ksize.width == ksize.height && sigma1 != 0.0 )
{
IppiBorderType ippBorder = ippiGetBorderType(borderType);
if (ippBorderConst == ippBorder || ippBorderRepl == ippBorder)
{
Mat src = _src.getMat(), dst = _dst.getMat();
IppiSize roiSize = { src.cols, src.rows };
IppDataType dataType = ippiGetDataType(depth);
Ipp32s specSize = 0, bufferSize = 0;
if (ippiFilterGaussianGetBufferSize(roiSize, (Ipp32u)ksize.width, dataType, cn, &specSize, &bufferSize) >= 0)
{
IppFilterGaussianSpec * pSpec = (IppFilterGaussianSpec *)ippMalloc(specSize);
Ipp8u * pBuffer = (Ipp8u*)ippMalloc(bufferSize);
if (ippiFilterGaussianInit(roiSize, (Ipp32u)ksize.width, (Ipp32f)sigma1, ippBorder, dataType, 1, pSpec, pBuffer) >= 0)
{
#define IPP_FILTER_GAUSS_C1(ippfavor) \
{ \
typedef Ipp##ippfavor ippType; \
ippType borderValues = 0; \
status = ippiFilterGaussianBorder_##ippfavor##_C1R(src.ptr<ippType>(), (int)src.step, \
dst.ptr<ippType>(), (int)dst.step, roiSize, borderValues, pSpec, pBuffer); \
}
#define IPP_FILTER_GAUSS_CN(ippfavor, ippcn) \
{ \
typedef Ipp##ippfavor ippType; \
ippType borderValues[] = { 0, 0, 0 }; \
status = ippiFilterGaussianBorder_##ippfavor##_C##ippcn##R(src.ptr<ippType>(), (int)src.step, \
dst.ptr<ippType>(), (int)dst.step, roiSize, borderValues, pSpec, pBuffer); \
}
IppStatus status = ippStsErr;
#if !HAVE_ICV
if (type == CV_8UC1)
IPP_FILTER_GAUSS_C1(8u)
else if (type == CV_8UC3)
IPP_FILTER_GAUSS_CN(8u, 3)
else if (type == CV_16UC1)
IPP_FILTER_GAUSS_C1(16u)
else if (type == CV_16UC3)
IPP_FILTER_GAUSS_CN(16u, 3)
else if (type == CV_16SC1)
IPP_FILTER_GAUSS_C1(16s)
else if (type == CV_16SC3)
IPP_FILTER_GAUSS_CN(16s, 3)
else if (type == CV_32FC3)
IPP_FILTER_GAUSS_CN(32f, 3)
else
#endif
if (type == CV_32FC1)
IPP_FILTER_GAUSS_C1(32f)
if (pSpec)
ippFree(pSpec);
if (pBuffer)
ippFree(pBuffer);
if(status >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return true;
}
#undef IPP_FILTER_GAUSS_C1
#undef IPP_FILTER_GAUSS_CN
}
}
}
}
return false;
}
}
#endif
void cv::GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,
double sigma1, double sigma2,
@ -1654,72 +1788,9 @@ void cv::GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,
return;
#endif
#if IPP_VERSION_X100 >= 801 && 0 // these functions are slower in IPP 8.1
CV_IPP_CHECK()
{
int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
if ((depth == CV_8U || depth == CV_16U || depth == CV_16S || depth == CV_32F) && (cn == 1 || cn == 3) &&
sigma1 == sigma2 && ksize.width == ksize.height && sigma1 != 0.0 )
{
IppiBorderType ippBorder = ippiGetBorderType(borderType);
if (ippBorderConst == ippBorder || ippBorderRepl == ippBorder)
{
Mat src = _src.getMat(), dst = _dst.getMat();
IppiSize roiSize = { src.cols, src.rows };
IppDataType dataType = ippiGetDataType(depth);
Ipp32s specSize = 0, bufferSize = 0;
if (ippiFilterGaussianGetBufferSize(roiSize, (Ipp32u)ksize.width, dataType, cn, &specSize, &bufferSize) >= 0)
{
IppFilterGaussianSpec * pSpec = (IppFilterGaussianSpec *)ippMalloc(specSize);
Ipp8u * pBuffer = (Ipp8u*)ippMalloc(bufferSize);
CV_IPP_RUN(true, ipp_GaussianBlur( _src, _dst, ksize, sigma1, sigma2, borderType));
if (ippiFilterGaussianInit(roiSize, (Ipp32u)ksize.width, (Ipp32f)sigma1, ippBorder, dataType, 1, pSpec, pBuffer) >= 0)
{
#define IPP_FILTER_GAUSS(ippfavor, ippcn) \
do \
{ \
typedef Ipp##ippfavor ippType; \
ippType borderValues[] = { 0, 0, 0 }; \
IppStatus status = ippcn == 1 ? \
ippiFilterGaussianBorder_##ippfavor##_C1R(src.ptr<ippType>(), (int)src.step, \
dst.ptr<ippType>(), (int)dst.step, roiSize, borderValues[0], pSpec, pBuffer) : \
ippiFilterGaussianBorder_##ippfavor##_C3R(src.ptr<ippType>(), (int)src.step, \
dst.ptr<ippType>(), (int)dst.step, roiSize, borderValues, pSpec, pBuffer); \
ippFree(pBuffer); \
ippFree(pSpec); \
if (status >= 0) \
{ \
CV_IMPL_ADD(CV_IMPL_IPP); \
return; \
} \
} while ((void)0, 0)
if (type == CV_8UC1)
IPP_FILTER_GAUSS(8u, 1);
else if (type == CV_8UC3)
IPP_FILTER_GAUSS(8u, 3);
else if (type == CV_16UC1)
IPP_FILTER_GAUSS(16u, 1);
else if (type == CV_16UC3)
IPP_FILTER_GAUSS(16u, 3);
else if (type == CV_16SC1)
IPP_FILTER_GAUSS(16s, 1);
else if (type == CV_16SC3)
IPP_FILTER_GAUSS(16s, 3);
else if (type == CV_32FC1)
IPP_FILTER_GAUSS(32f, 1);
else if (type == CV_32FC3)
IPP_FILTER_GAUSS(32f, 3);
#undef IPP_FILTER_GAUSS
}
}
setIppErrorStatus();
}
}
}
#endif
Mat kx, ky;
createGaussianKernels(kx, ky, type, ksize, sigma1, sigma2);
@ -2632,6 +2703,63 @@ static bool ocl_medianFilter(InputArray _src, OutputArray _dst, int m)
}
#ifdef HAVE_IPP
namespace cv
{
static bool ipp_medianFilter( InputArray _src0, OutputArray _dst, int ksize )
{
#if IPP_VERSION_X100 >= 801
Mat src0 = _src0.getMat();
_dst.create( src0.size(), src0.type() );
Mat dst = _dst.getMat();
#define IPP_FILTER_MEDIAN_BORDER(ippType, ippDataType, flavor) \
do \
{ \
if (ippiFilterMedianBorderGetBufferSize(dstRoiSize, maskSize, \
ippDataType, CV_MAT_CN(type), &bufSize) >= 0) \
{ \
Ipp8u * buffer = ippsMalloc_8u(bufSize); \
IppStatus status = ippiFilterMedianBorder_##flavor(src.ptr<ippType>(), (int)src.step, \
dst.ptr<ippType>(), (int)dst.step, dstRoiSize, maskSize, \
ippBorderRepl, (ippType)0, buffer); \
ippsFree(buffer); \
if (status >= 0) \
{ \
CV_IMPL_ADD(CV_IMPL_IPP); \
return true; \
} \
} \
} \
while ((void)0, 0)
if( ksize <= 5 )
{
Ipp32s bufSize;
IppiSize dstRoiSize = ippiSize(dst.cols, dst.rows), maskSize = ippiSize(ksize, ksize);
Mat src;
if( dst.data != src0.data )
src = src0;
else
src0.copyTo(src);
int type = src0.type();
if (type == CV_8UC1)
IPP_FILTER_MEDIAN_BORDER(Ipp8u, ipp8u, 8u_C1R);
else if (type == CV_16UC1)
IPP_FILTER_MEDIAN_BORDER(Ipp16u, ipp16u, 16u_C1R);
else if (type == CV_16SC1)
IPP_FILTER_MEDIAN_BORDER(Ipp16s, ipp16s, 16s_C1R);
else if (type == CV_32FC1)
IPP_FILTER_MEDIAN_BORDER(Ipp32f, ipp32f, 32f_C1R);
}
#undef IPP_FILTER_MEDIAN_BORDER
#endif
return false;
}
}
#endif
void cv::medianBlur( InputArray _src0, OutputArray _dst, int ksize )
{
CV_Assert( (ksize % 2 == 1) && (_src0.dims() <= 2 ));
@ -2649,53 +2777,7 @@ void cv::medianBlur( InputArray _src0, OutputArray _dst, int ksize )
_dst.create( src0.size(), src0.type() );
Mat dst = _dst.getMat();
#if IPP_VERSION_X100 >= 801
CV_IPP_CHECK()
{
#define IPP_FILTER_MEDIAN_BORDER(ippType, ippDataType, flavor) \
do \
{ \
if (ippiFilterMedianBorderGetBufferSize(dstRoiSize, maskSize, \
ippDataType, CV_MAT_CN(type), &bufSize) >= 0) \
{ \
Ipp8u * buffer = ippsMalloc_8u(bufSize); \
IppStatus status = ippiFilterMedianBorder_##flavor(src.ptr<ippType>(), (int)src.step, \
dst.ptr<ippType>(), (int)dst.step, dstRoiSize, maskSize, \
ippBorderRepl, (ippType)0, buffer); \
ippsFree(buffer); \
if (status >= 0) \
{ \
CV_IMPL_ADD(CV_IMPL_IPP); \
return; \
} \
} \
setIppErrorStatus(); \
} \
while ((void)0, 0)
if( ksize <= 5 )
{
Ipp32s bufSize;
IppiSize dstRoiSize = ippiSize(dst.cols, dst.rows), maskSize = ippiSize(ksize, ksize);
Mat src;
if( dst.data != src0.data )
src = src0;
else
src0.copyTo(src);
int type = src0.type();
if (type == CV_8UC1)
IPP_FILTER_MEDIAN_BORDER(Ipp8u, ipp8u, 8u_C1R);
else if (type == CV_16UC1)
IPP_FILTER_MEDIAN_BORDER(Ipp16u, ipp16u, 16u_C1R);
else if (type == CV_16SC1)
IPP_FILTER_MEDIAN_BORDER(Ipp16s, ipp16s, 16s_C1R);
else if (type == CV_32FC1)
IPP_FILTER_MEDIAN_BORDER(Ipp32f, ipp32f, 32f_C1R);
}
#undef IPP_FILTER_MEDIAN_BORDER
}
#endif
CV_IPP_RUN(IPP_VERSION_X100 >= 801 && ksize <= 5, ipp_medianFilter(_src0,_dst, ksize));
#ifdef HAVE_TEGRA_OPTIMIZATION
if (tegra::useTegra() && tegra::medianBlur(src0, dst, ksize))

@ -424,6 +424,69 @@ static bool ocl_integral( InputArray _src, OutputArray _sum, OutputArray _sqsum,
}
#if defined(HAVE_IPP)
namespace cv
{
static bool ipp_integral(InputArray _src, OutputArray _sum, OutputArray _sqsum, OutputArray _tilted, int sdepth, int sqdepth)
{
#if !defined(HAVE_IPP_ICV_ONLY) // Disabled on ICV due invalid results
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
if( sdepth <= 0 )
sdepth = depth == CV_8U ? CV_32S : CV_64F;
if ( sqdepth <= 0 )
sqdepth = CV_64F;
sdepth = CV_MAT_DEPTH(sdepth), sqdepth = CV_MAT_DEPTH(sqdepth);
Size ssize = _src.size(), isize(ssize.width + 1, ssize.height + 1);
_sum.create( isize, CV_MAKETYPE(sdepth, cn) );
Mat src = _src.getMat(), sum =_sum.getMat(), sqsum, tilted;
if( _sqsum.needed() )
{
_sqsum.create( isize, CV_MAKETYPE(sqdepth, cn) );
sqsum = _sqsum.getMat();
};
if( ( depth == CV_8U ) && ( sdepth == CV_32F || sdepth == CV_32S ) && ( !_tilted.needed() ) && ( !_sqsum.needed() || sqdepth == CV_64F ) && ( cn == 1 ) )
{
IppStatus status = ippStsErr;
IppiSize srcRoiSize = ippiSize( src.cols, src.rows );
if( sdepth == CV_32F )
{
if( _sqsum.needed() )
{
status = ippiSqrIntegral_8u32f64f_C1R( (const Ipp8u*)src.data, (int)src.step, (Ipp32f*)sum.data, (int)sum.step, (Ipp64f*)sqsum.data, (int)sqsum.step, srcRoiSize, 0, 0 );
}
else
{
status = ippiIntegral_8u32f_C1R( (const Ipp8u*)src.data, (int)src.step, (Ipp32f*)sum.data, (int)sum.step, srcRoiSize, 0 );
}
}
else if( sdepth == CV_32S )
{
if( _sqsum.needed() )
{
status = ippiSqrIntegral_8u32s64f_C1R( (const Ipp8u*)src.data, (int)src.step, (Ipp32s*)sum.data, (int)sum.step, (Ipp64f*)sqsum.data, (int)sqsum.step, srcRoiSize, 0, 0 );
}
else
{
status = ippiIntegral_8u32s_C1R( (const Ipp8u*)src.data, (int)src.step, (Ipp32s*)sum.data, (int)sum.step, srcRoiSize, 0 );
}
}
if (0 <= status)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return true;
}
}
#else
CV_UNUSED(_src); CV_UNUSED(_sum); CV_UNUSED(_sqsum); CV_UNUSED(_tilted); CV_UNUSED(sdepth); CV_UNUSED(sqdepth);
#endif
return false;
}
}
#endif
void cv::integral( InputArray _src, OutputArray _sum, OutputArray _sqsum, OutputArray _tilted, int sdepth, int sqdepth )
{
@ -456,44 +519,9 @@ void cv::integral( InputArray _src, OutputArray _sum, OutputArray _sqsum, Output
sqsum = _sqsum.getMat();
};
#if defined(HAVE_IPP) && !defined(HAVE_IPP_ICV_ONLY) // Disabled on ICV due invalid results
CV_IPP_CHECK()
{
if( ( depth == CV_8U ) && ( sdepth == CV_32F || sdepth == CV_32S ) && ( !_tilted.needed() ) && ( !_sqsum.needed() || sqdepth == CV_64F ) && ( cn == 1 ) )
{
IppStatus status = ippStsErr;
IppiSize srcRoiSize = ippiSize( src.cols, src.rows );
if( sdepth == CV_32F )
{
if( _sqsum.needed() )
{
status = ippiSqrIntegral_8u32f64f_C1R( (const Ipp8u*)src.data, (int)src.step, (Ipp32f*)sum.data, (int)sum.step, (Ipp64f*)sqsum.data, (int)sqsum.step, srcRoiSize, 0, 0 );
}
else
{
status = ippiIntegral_8u32f_C1R( (const Ipp8u*)src.data, (int)src.step, (Ipp32f*)sum.data, (int)sum.step, srcRoiSize, 0 );
}
}
else if( sdepth == CV_32S )
{
if( _sqsum.needed() )
{
status = ippiSqrIntegral_8u32s64f_C1R( (const Ipp8u*)src.data, (int)src.step, (Ipp32s*)sum.data, (int)sum.step, (Ipp64f*)sqsum.data, (int)sqsum.step, srcRoiSize, 0, 0 );
}
else
{
status = ippiIntegral_8u32s_C1R( (const Ipp8u*)src.data, (int)src.step, (Ipp32s*)sum.data, (int)sum.step, srcRoiSize, 0 );
}
}
if (0 <= status)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
}
}
#endif
CV_IPP_RUN(( depth == CV_8U ) && ( sdepth == CV_32F || sdepth == CV_32S ) &&
( !_tilted.needed() ) && ( !_sqsum.needed() || sqdepth == CV_64F ) && ( cn == 1 ),
ipp_integral(_src, _sum, _sqsum, _tilted, sdepth, sqdepth));
if( _tilted.needed() )
{

@ -895,28 +895,13 @@ static void matchTemplateMask( InputArray _img, InputArray _templ, OutputArray _
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result, int method, InputArray _mask )
namespace cv
{
if (!_mask.empty())
{
cv::matchTemplateMask(_img, _templ, _result, method, _mask);
static void common_matchTemplate( Mat& img, Mat& templ, Mat& result, int method, int cn )
{
if( method == CV_TM_CCORR )
return;
}
int type = _img.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
CV_Assert( CV_TM_SQDIFF <= method && method <= CV_TM_CCOEFF_NORMED );
CV_Assert( (depth == CV_8U || depth == CV_32F) && type == _templ.type() && _img.dims() <= 2 );
bool needswap = _img.size().height < _templ.size().height || _img.size().width < _templ.size().width;
if (needswap)
{
CV_Assert(_img.size().height <= _templ.size().height && _img.size().width <= _templ.size().width);
}
CV_OCL_RUN(_img.dims() <= 2 && _result.isUMat(),
(!needswap ? ocl_matchTemplate(_img, _templ, _result, method) : ocl_matchTemplate(_templ, _img, _result, method)))
int numType = method == CV_TM_CCORR || method == CV_TM_CCORR_NORMED ? 0 :
method == CV_TM_CCOEFF || method == CV_TM_CCOEFF_NORMED ? 1 : 2;
@ -924,57 +909,6 @@ void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result,
method == CV_TM_SQDIFF_NORMED ||
method == CV_TM_CCOEFF_NORMED;
Mat img = _img.getMat(), templ = _templ.getMat();
if (needswap)
std::swap(img, templ);
Size corrSize(img.cols - templ.cols + 1, img.rows - templ.rows + 1);
_result.create(corrSize, CV_32F);
Mat result = _result.getMat();
#ifdef HAVE_TEGRA_OPTIMIZATION
if (tegra::useTegra() && tegra::matchTemplate(img, templ, result, method))
return;
#endif
#if defined HAVE_IPP
bool useIppMT = false;
CV_IPP_CHECK()
{
useIppMT = (templ.rows < img.rows/2 && templ.cols < img.cols/2);
if (method == CV_TM_SQDIFF && cn == 1 && useIppMT)
{
if (ipp_sqrDistance(img, templ, result))
{
CV_IMPL_ADD(CV_IMPL_IPP);
return;
}
setIppErrorStatus();
}
}
#endif
#if defined HAVE_IPP
if (cn == 1 && useIppMT)
{
if (!ipp_crossCorr(img, templ, result))
{
setIppErrorStatus();
crossCorr( img, templ, result, result.size(), result.type(), Point(0,0), 0, 0);
}
else
{
CV_IMPL_ADD(CV_IMPL_IPP);
}
}
else
#endif
crossCorr( img, templ, result, result.size(), result.type(), Point(0,0), 0, 0);
if( method == CV_TM_CCORR )
return;
double invArea = 1./((double)templ.rows * templ.cols);
Mat sum, sqsum;
@ -1081,8 +1015,81 @@ void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result,
}
}
}
}
#if defined HAVE_IPP
namespace cv
{
static bool ipp_matchTemplate( Mat& img, Mat& templ, Mat& result, int method, int cn )
{
bool useIppMT = (templ.rows < img.rows/2 && templ.cols < img.cols/2);
if(cn == 1 && useIppMT)
{
if(method == CV_TM_SQDIFF)
{
if (ipp_sqrDistance(img, templ, result))
return true;
}
else
{
if(ipp_crossCorr(img, templ, result))
{
common_matchTemplate(img, templ, result, method, cn);
return true;
}
}
}
return false;
}
}
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////
void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result, int method, InputArray _mask )
{
if (!_mask.empty())
{
cv::matchTemplateMask(_img, _templ, _result, method, _mask);
return;
}
int type = _img.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
CV_Assert( CV_TM_SQDIFF <= method && method <= CV_TM_CCOEFF_NORMED );
CV_Assert( (depth == CV_8U || depth == CV_32F) && type == _templ.type() && _img.dims() <= 2 );
bool needswap = _img.size().height < _templ.size().height || _img.size().width < _templ.size().width;
if (needswap)
{
CV_Assert(_img.size().height <= _templ.size().height && _img.size().width <= _templ.size().width);
}
CV_OCL_RUN(_img.dims() <= 2 && _result.isUMat(),
(!needswap ? ocl_matchTemplate(_img, _templ, _result, method) : ocl_matchTemplate(_templ, _img, _result, method)))
Mat img = _img.getMat(), templ = _templ.getMat();
if (needswap)
std::swap(img, templ);
Size corrSize(img.cols - templ.cols + 1, img.rows - templ.rows + 1);
_result.create(corrSize, CV_32F);
Mat result = _result.getMat();
#ifdef HAVE_TEGRA_OPTIMIZATION
if (tegra::useTegra() && tegra::matchTemplate(img, templ, result, method))
return;
#endif
CV_IPP_RUN(true, ipp_matchTemplate(img, templ, result, method, cn))
crossCorr( img, templ, result, result.size(), result.type(), Point(0,0), 0, 0);
common_matchTemplate(img, templ, result, method, cn);
}
CV_IMPL void
cvMatchTemplate( const CvArr* _img, const CvArr* _templ, CvArr* _result, int method )
{

@ -904,6 +904,24 @@ thresh_32f( const Mat& _src, Mat& _dst, float thresh, float maxval, int type )
}
}
#ifdef HAVE_IPP
static bool ipp_getThreshVal_Otsu_8u( const unsigned char* _src, int step, Size size, unsigned char &thresh)
{
#if IPP_VERSION_X100 >= 801 && !HAVE_ICV
int ippStatus = -1;
IppiSize srcSize = { size.width, size.height };
CV_SUPPRESS_DEPRECATED_START
ippStatus = ippiComputeThreshold_Otsu_8u_C1R(_src, step, srcSize, &thresh);
CV_SUPPRESS_DEPRECATED_END
if(ippStatus >= 0)
return true;
#else
CV_UNUSED(_src); CV_UNUSED(step); CV_UNUSED(size); CV_UNUSED(thresh);
#endif
return false;
}
#endif
static double
getThreshVal_Otsu_8u( const Mat& _src )
@ -917,21 +935,9 @@ getThreshVal_Otsu_8u( const Mat& _src )
step = size.width;
}
#if IPP_VERSION_X100 >= 801 && !defined(HAVE_IPP_ICV_ONLY)
CV_IPP_CHECK()
{
IppiSize srcSize = { size.width, size.height };
Ipp8u thresh;
CV_SUPPRESS_DEPRECATED_START
IppStatus ok = ippiComputeThreshold_Otsu_8u_C1R(_src.ptr(), step, srcSize, &thresh);
CV_SUPPRESS_DEPRECATED_END
if (ok >= 0)
{
CV_IMPL_ADD(CV_IMPL_IPP);
return thresh;
}
setIppErrorStatus();
}
#ifdef HAVE_IPP
unsigned char thresh;
CV_IPP_RUN(IPP_VERSION_X100 >= 801 && !HAVE_ICV, ipp_getThreshVal_Otsu_8u(_src.ptr(), step, size, thresh), thresh);
#endif
const int N = 256;

Loading…
Cancel
Save