From a5a21019b2c6a40d116e0d29d6f4a6aa6816b0ed Mon Sep 17 00:00:00 2001 From: Dmitry Budnikov Date: Fri, 15 May 2015 11:15:00 +0300 Subject: [PATCH] ipp_countNonZero build fix; Removed IPP port for tiny arithm.cpp functions Additional warnings fix on various platforms. Build without OPENCL and GCC warnings fixed Fixed warnings, trailing spaces and removed unused secure_cpy. IPP code refactored. IPP code path implemented as separate static functions to simplify future work with IPP code and make it more readable. --- modules/core/include/opencv2/core/base.hpp | 1 + modules/core/include/opencv2/core/private.hpp | 58 ++ modules/core/src/convert.cpp | 96 +- modules/core/src/copy.cpp | 345 +++---- modules/core/src/matrix.cpp | 140 +-- modules/core/src/precomp.hpp | 1 + modules/core/src/stat.cpp | 1058 ++++++++++--------- modules/imgproc/src/accum.cpp | 498 ++++----- modules/imgproc/src/color.cpp | 1344 +++++++++++-------------- modules/imgproc/src/corner.cpp | 81 +- modules/imgproc/src/deriv.cpp | 176 ++-- modules/imgproc/src/filter.cpp | 161 +-- modules/imgproc/src/histogram.cpp | 37 +- modules/imgproc/src/imgwarp.cpp | 101 +- modules/imgproc/src/morph.cpp | 13 +- modules/imgproc/src/pyramids.cpp | 198 ++-- modules/imgproc/src/smooth.cpp | 346 ++++--- modules/imgproc/src/sumpixels.cpp | 104 +- modules/imgproc/src/templmatch.cpp | 147 +-- modules/imgproc/src/thresh.cpp | 37 +- 20 files changed, 2635 insertions(+), 2307 deletions(-) diff --git a/modules/core/include/opencv2/core/base.hpp b/modules/core/include/opencv2/core/base.hpp index 83cc311..3d440da 100644 --- a/modules/core/include/opencv2/core/base.hpp +++ b/modules/core/include/opencv2/core/base.hpp @@ -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. diff --git a/modules/core/include/opencv2/core/private.hpp b/modules/core/include/opencv2/core/private.hpp index 4f9f487..5bda617 100644 --- a/modules/core/include/opencv2/core/private.hpp +++ b/modules/core/include/opencv2/core/private.hpp @@ -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 diff --git a/modules/core/src/convert.cpp b/modules/core/src/convert.cpp index 090acf5..cebbb15 100644 --- a/modules/core/src/convert.cpp +++ b/modules/core/src/convert.cpp @@ -5194,17 +5194,9 @@ 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 (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(true, ippiConvert_##ippFavor(src, (int)sstep, dst, (int)dstep, ippiSize(size.width, size.height)) >= 0)\ }\ cvt_(src, sstep, dst, dstep, size); \ } @@ -5213,17 +5205,9 @@ 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 (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(true, ippiConvert_##ippFavor(src, (int)sstep, dst, (int)dstep, ippiSize(size.width, size.height), ippRndFinancial, 0) >= 0)\ }\ cvt_(src, sstep, dst, dstep, size); \ } @@ -5907,6 +5891,55 @@ private: } +namespace cv +{ +#if defined(HAVE_IPP) +static bool ipp_lut(InputArray _src, InputArray _lut, OutputArray _dst) +{ + int cn = _src.channels(); + int lutcn = _lut.channels(); + + Mat src = _src.getMat(), lut = _lut.getMat(); + _dst.create(src.dims, src.size, CV_MAKETYPE(_lut.depth(), cn)); + Mat dst = _dst.getMat(); + + if (_src.dims() <= 2) + { + bool ok = false; + Ptr 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 +} + + void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst ) { int cn = _src.channels(), depth = _src.depth(); @@ -5919,6 +5952,10 @@ void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst ) CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2, ocl_LUT(_src, _lut, _dst)) + CV_IPP_RUN((_src.dims() <= 2 && ((lutcn == 1 || lutcn == 3 || lutcn == 4) && CV_ELEM_SIZE1(_dst.depth()) == 1) && lutcn != 1), //lutcn == 1 ipp implementation switched off + ipp_lut(_src, _lut, _dst)); + + Mat src = _src.getMat(), lut = _lut.getMat(); _dst.create(src.dims, src.size, CV_MAKETYPE(_lut.depth(), cn)); Mat dst = _dst.getMat(); @@ -5927,25 +5964,6 @@ void cv::LUT( InputArray _src, InputArray _lut, OutputArray _dst ) { bool ok = false; Ptr 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; diff --git a/modules/core/src/copy.cpp b/modules/core/src/copy.cpp index aa6eb2f..ba09b54 100644 --- a/modules/core/src/copy.cpp +++ b/modules/core/src/copy.cpp @@ -82,17 +82,7 @@ copyMask_(const uchar* _src, size_t sstep, const uchar* mask, size_t mstep, ucha template<> void copyMask_(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_(const uchar* _src, size_t sstep, const uchar* mask, size_t mste template<> void copyMask_(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_(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,101 @@ 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, InputArray _value, InputArray _mask) { - if( empty() ) - return *this; - Mat value = _value.getMat(), mask = _mask.getMat(); + int cn = src->channels(), depth0 = src->depth(); - 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 +690,80 @@ static bool ocl_flip(InputArray _src, OutputArray _dst, int flipCode ) #endif +#if defined HAVE_IPP +static bool ipp_flip( InputArray _src, OutputArray _dst, int flip_mode ) +{ + Size size = _src.size(); + Mat src = _src.getMat(); + int type = src.type(); + _dst.create( size, type ); + Mat dst = _dst.getMat(); + + 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 ); @@ -747,85 +786,15 @@ void flip( InputArray _src, OutputArray _dst, int flip_mode ) CV_OCL_RUN( _dst.isUMat(), ocl_flip(_src, _dst, flip_mode)) + CV_IPP_RUN(true, ipp_flip(_src, _dst, flip_mode)); + + Mat src = _src.getMat(); 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; - - 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 - if( flip_mode <= 0 ) flipVert( src.ptr(), src.step, dst.ptr(), dst.step, src.size(), esz ); else diff --git a/modules/core/src/matrix.cpp b/modules/core/src/matrix.cpp index b273c8a..ea82d68 100644 --- a/modules/core/src/matrix.cpp +++ b/modules/core/src/matrix.cpp @@ -3088,8 +3088,78 @@ static bool ocl_transpose( InputArray _src, OutputArray _dst ) #endif + +#ifdef HAVE_IPP +static bool ipp_transpose( InputArray _src, OutputArray _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; + + Mat dst = _dst.getMat(); + Mat src = _src.getMat(); + + 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); @@ -3116,76 +3186,8 @@ 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; - } + CV_IPP_RUN(true, ipp_transpose(_src, _dst)) - 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 if( dst.data == src.data ) { diff --git a/modules/core/src/precomp.hpp b/modules/core/src/precomp.hpp index 88b60e4..81b9674 100644 --- a/modules/core/src/precomp.hpp +++ b/modules/core/src/precomp.hpp @@ -72,6 +72,7 @@ #define GET_OPTIMIZED(func) (func) #endif + namespace cv { diff --git a/modules/core/src/stat.cpp b/modules/core/src/stat.cpp index 81f9a24..811fa2c 100644 --- a/modules/core/src/stat.cpp +++ b/modules/core/src/stat.cpp @@ -1140,64 +1140,79 @@ static bool ocl_sum( InputArray _src, Scalar & res, int sum_op, InputArray _mask } +#if defined (HAVE_IPP) +namespace cv +{ + static bool ipp_sum(Mat src, Scalar & _res) +{ +#if (IPP_VERSION_MAJOR >= 7) + int cn = src.channels(); + size_t total_size = src.total(); + int rows = src.size[0], cols = rows ? (int)(total_size / rows) : 0; + if (src.dims == 2 || (src.isContinuous() && cols > 0 && (size_t)rows*cols == total_size)) + { + IppiSize sz = { cols, rows }; + int type = src.type(); + typedef IppStatus(CV_STDCALL* ippiSumFuncHint)(const void*, int, IppiSize, double *, IppHintAlgorithm); + typedef IppStatus(CV_STDCALL* ippiSumFuncNoHint)(const void*, int, IppiSize, double *); + ippiSumFuncHint ippFuncHint = + type == CV_32FC1 ? (ippiSumFuncHint)ippiSum_32f_C1R : + type == CV_32FC3 ? (ippiSumFuncHint)ippiSum_32f_C3R : + type == CV_32FC4 ? (ippiSumFuncHint)ippiSum_32f_C4R : + 0; + ippiSumFuncNoHint ippFuncNoHint = + type == CV_8UC1 ? (ippiSumFuncNoHint)ippiSum_8u_C1R : + type == CV_8UC3 ? (ippiSumFuncNoHint)ippiSum_8u_C3R : + type == CV_8UC4 ? (ippiSumFuncNoHint)ippiSum_8u_C4R : + type == CV_16UC1 ? (ippiSumFuncNoHint)ippiSum_16u_C1R : + type == CV_16UC3 ? (ippiSumFuncNoHint)ippiSum_16u_C3R : + type == CV_16UC4 ? (ippiSumFuncNoHint)ippiSum_16u_C4R : + type == CV_16SC1 ? (ippiSumFuncNoHint)ippiSum_16s_C1R : + type == CV_16SC3 ? (ippiSumFuncNoHint)ippiSum_16s_C3R : + type == CV_16SC4 ? (ippiSumFuncNoHint)ippiSum_16s_C4R : + 0; + CV_Assert(!ippFuncHint || !ippFuncNoHint); + if (ippFuncHint || ippFuncNoHint) + { + Ipp64f res[4]; + IppStatus ret = ippFuncHint ? ippFuncHint(src.ptr(), (int)src.step[0], sz, res, ippAlgHintAccurate) : + ippFuncNoHint(src.ptr(), (int)src.step[0], sz, res); + CV_Assert(cn <= 4); + cn = min(cn, 4); + if (ret >= 0) + { + for( int i = 0; i < cn; i++ ) + _res[i] = res[i]; + return true; + } + return false; + } + } +#endif + return false; +} +} +#endif + cv::Scalar cv::sum( InputArray _src ) { -#ifdef HAVE_OPENCL Scalar _res; +#ifdef HAVE_OPENCL CV_OCL_RUN_(OCL_PERFORMANCE_CHECK(_src.isUMat()) && _src.dims() <= 2, ocl_sum(_src, _res, OCL_OP_SUM), _res) #endif +#ifdef HAVE_IPP + size_t total_size = _src.total(); + int rows = _src.rows(); + int cols = rows ? (int)(total_size / rows) : 0; +#endif Mat src = _src.getMat(); + CV_IPP_RUN((_src.dims() == 2 || (_src.isContinuous() && cols > 0 && (size_t)rows*cols == total_size)) && IPP_VERSION_MAJOR >= 7, + ipp_sum(src, _res), _res); int k, cn = src.channels(), depth = src.depth(); -#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CV_IPP_CHECK() - { - size_t total_size = src.total(); - int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0; - if( src.dims == 2 || (src.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) ) - { - IppiSize sz = { cols, rows }; - int type = src.type(); - typedef IppStatus (CV_STDCALL* ippiSumFuncHint)(const void*, int, IppiSize, double *, IppHintAlgorithm); - typedef IppStatus (CV_STDCALL* ippiSumFuncNoHint)(const void*, int, IppiSize, double *); - ippiSumFuncHint ippFuncHint = - type == CV_32FC1 ? (ippiSumFuncHint)ippiSum_32f_C1R : - type == CV_32FC3 ? (ippiSumFuncHint)ippiSum_32f_C3R : - type == CV_32FC4 ? (ippiSumFuncHint)ippiSum_32f_C4R : - 0; - ippiSumFuncNoHint ippFuncNoHint = - type == CV_8UC1 ? (ippiSumFuncNoHint)ippiSum_8u_C1R : - type == CV_8UC3 ? (ippiSumFuncNoHint)ippiSum_8u_C3R : - type == CV_8UC4 ? (ippiSumFuncNoHint)ippiSum_8u_C4R : - type == CV_16UC1 ? (ippiSumFuncNoHint)ippiSum_16u_C1R : - type == CV_16UC3 ? (ippiSumFuncNoHint)ippiSum_16u_C3R : - type == CV_16UC4 ? (ippiSumFuncNoHint)ippiSum_16u_C4R : - type == CV_16SC1 ? (ippiSumFuncNoHint)ippiSum_16s_C1R : - type == CV_16SC3 ? (ippiSumFuncNoHint)ippiSum_16s_C3R : - type == CV_16SC4 ? (ippiSumFuncNoHint)ippiSum_16s_C4R : - 0; - CV_Assert(!ippFuncHint || !ippFuncNoHint); - if( ippFuncHint || ippFuncNoHint ) - { - Ipp64f res[4]; - IppStatus ret = ippFuncHint ? ippFuncHint(src.ptr(), (int)src.step[0], sz, res, ippAlgHintAccurate) : - ippFuncNoHint(src.ptr(), (int)src.step[0], sz, res); - if( ret >= 0 ) - { - Scalar sc; - for( int i = 0; i < cn; i++ ) - sc[i] = res[i]; - CV_IMPL_ADD(CV_IMPL_IPP); - return sc; - } - setIppErrorStatus(); - } - } - } -#endif SumFunc func = getSumFunc(depth); CV_Assert( cn <= 4 && func != 0 ); @@ -1247,6 +1262,7 @@ cv::Scalar cv::sum( InputArray _src ) return s; } + #ifdef HAVE_OPENCL namespace cv { @@ -1291,51 +1307,61 @@ static bool ocl_countNonZero( InputArray _src, int & res ) #endif +#if defined HAVE_IPP +namespace cv { + +static bool ipp_countNonZero( Mat src, int & res ) +{ +#if !defined HAVE_IPP_ICV_ONLY + Ipp32s count = 0; + IppStatus status = ippStsNoErr; + + int type = src.type(), depth = CV_MAT_DEPTH(type); + IppiSize roiSize = { src.cols, src.rows }; + Ipp32s srcstep = (Ipp32s)src.step; + if (src.isContinuous()) + { + roiSize.width = (Ipp32s)src.total(); + roiSize.height = 1; + srcstep = (Ipp32s)src.total() * CV_ELEM_SIZE(type); + } + + if (depth == CV_8U) + status = ippiCountInRange_8u_C1R((const Ipp8u *)src.data, srcstep, roiSize, &count, 0, 0); + else if (depth == CV_32F) + status = ippiCountInRange_32f_C1R((const Ipp32f *)src.data, srcstep, roiSize, &count, 0, 0); + + if (status >= 0) + { + res = ((Ipp32s)src.total() - count); + return true; + } +#else + CV_UNUSED(src); CV_UNUSED(res); +#endif + return false; +} +} +#endif + + int cv::countNonZero( InputArray _src ) { int type = _src.type(), cn = CV_MAT_CN(type); CV_Assert( cn == 1 ); -#ifdef HAVE_OPENCL +#if defined HAVE_OPENCL || defined HAVE_IPP int res = -1; +#endif + +#ifdef HAVE_OPENCL CV_OCL_RUN_(OCL_PERFORMANCE_CHECK(_src.isUMat()) && _src.dims() <= 2, ocl_countNonZero(_src, res), res) #endif Mat src = _src.getMat(); - -#if defined HAVE_IPP && !defined HAVE_IPP_ICV_ONLY && 0 - CV_IPP_CHECK() - { - if (src.dims <= 2 || src.isContinuous()) - { - IppiSize roiSize = { src.cols, src.rows }; - Ipp32s count = 0, srcstep = (Ipp32s)src.step; - IppStatus status = (IppStatus)-1; - - if (src.isContinuous()) - { - roiSize.width = (Ipp32s)src.total(); - roiSize.height = 1; - srcstep = (Ipp32s)src.total() * CV_ELEM_SIZE(type); - } - - int depth = CV_MAT_DEPTH(type); - if (depth == CV_8U) - status = ippiCountInRange_8u_C1R((const Ipp8u *)src.data, srcstep, roiSize, &count, 0, 0); - else if (depth == CV_32F) - status = ippiCountInRange_32f_C1R((const Ipp32f *)src.data, srcstep, roiSize, &count, 0, 0); - - if (status >= 0) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return (Ipp32s)src.total() - count; - } - setIppErrorStatus(); - } - } -#endif + CV_IPP_RUN(0 && (_src.dims() <= 2 || _src.isContinuous()), ipp_countNonZero(src, res), res); CountNonZeroFunc func = getCountNonZeroTab(src.depth()); CV_Assert( func != 0 ); @@ -1618,127 +1644,135 @@ static bool ocl_meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv #endif -void cv::meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv, InputArray _mask ) +#if defined (HAVE_IPP) +namespace cv { - CV_OCL_RUN(OCL_PERFORMANCE_CHECK(_src.isUMat()) && _src.dims() <= 2, - ocl_meanStdDev(_src, _mean, _sdv, _mask)) - - Mat src = _src.getMat(), mask = _mask.getMat(); - CV_Assert( mask.empty() || mask.type() == CV_8UC1 ); - - int k, cn = src.channels(), depth = src.depth(); - -#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CV_IPP_CHECK() - { - size_t total_size = src.total(); - int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0; - if( src.dims == 2 || (src.isContinuous() && mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) ) - { - Ipp64f mean_temp[3]; - Ipp64f stddev_temp[3]; - Ipp64f *pmean = &mean_temp[0]; - Ipp64f *pstddev = &stddev_temp[0]; - Mat mean, stddev; - int dcn_mean = -1; - if( _mean.needed() ) +static bool ipp_meanStdDev(Mat& src, OutputArray _mean, OutputArray _sdv, Mat& mask) +{ +#if (IPP_VERSION_MAJOR >= 7) + int cn = src.channels(); + size_t total_size = src.total(); + int rows = src.size[0], cols = rows ? (int)(total_size / rows) : 0; + + Ipp64f mean_temp[3]; + Ipp64f stddev_temp[3]; + Ipp64f *pmean = &mean_temp[0]; + Ipp64f *pstddev = &stddev_temp[0]; + Mat mean, stddev; + int dcn_mean = -1; + if (_mean.needed()) + { + if (!_mean.fixedSize()) + _mean.create(cn, 1, CV_64F, -1, true); + mean = _mean.getMat(); + dcn_mean = (int)mean.total(); + pmean = mean.ptr(); + } + int dcn_stddev = -1; + if (_sdv.needed()) + { + if (!_sdv.fixedSize()) + _sdv.create(cn, 1, CV_64F, -1, true); + stddev = _sdv.getMat(); + dcn_stddev = (int)stddev.total(); + pstddev = stddev.ptr(); + } + for (int c = cn; c < dcn_mean; c++) + pmean[c] = 0; + for (int c = cn; c < dcn_stddev; c++) + pstddev[c] = 0; + IppiSize sz = { cols, rows }; + int type = src.type(); + + if (!mask.empty()) + { + typedef IppStatus(CV_STDCALL* ippiMaskMeanStdDevFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *, Ipp64f *); + ippiMaskMeanStdDevFuncC1 ippFuncC1 = + type == CV_8UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_8u_C1MR : + type == CV_16UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_16u_C1MR : + type == CV_32FC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_32f_C1MR : + 0; + if (ippFuncC1) + { + if (ippFuncC1(src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, pmean, pstddev) >= 0) { - if( !_mean.fixedSize() ) - _mean.create(cn, 1, CV_64F, -1, true); - mean = _mean.getMat(); - dcn_mean = (int)mean.total(); - pmean = mean.ptr(); + return true; } - int dcn_stddev = -1; - if( _sdv.needed() ) + } + typedef IppStatus(CV_STDCALL* ippiMaskMeanStdDevFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *, Ipp64f *); + ippiMaskMeanStdDevFuncC3 ippFuncC3 = + type == CV_8UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CMR : + type == CV_16UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CMR : + type == CV_32FC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CMR : + 0; + if (ippFuncC3) + { + if (ippFuncC3(src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 1, &pmean[0], &pstddev[0]) >= 0 && + ippFuncC3(src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 2, &pmean[1], &pstddev[1]) >= 0 && + ippFuncC3(src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 3, &pmean[2], &pstddev[2]) >= 0) { - if( !_sdv.fixedSize() ) - _sdv.create(cn, 1, CV_64F, -1, true); - stddev = _sdv.getMat(); - dcn_stddev = (int)stddev.total(); - pstddev = stddev.ptr(); + return true; } - for( int c = cn; c < dcn_mean; c++ ) - pmean[c] = 0; - for( int c = cn; c < dcn_stddev; c++ ) - pstddev[c] = 0; - IppiSize sz = { cols, rows }; - int type = src.type(); - if( !mask.empty() ) + } + } + else + { + typedef IppStatus(CV_STDCALL* ippiMeanStdDevFuncC1)(const void *, int, IppiSize, Ipp64f *, Ipp64f *); + ippiMeanStdDevFuncC1 ippFuncC1 = + type == CV_8UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_8u_C1R : + type == CV_16UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_16u_C1R : +#if (IPP_VERSION_X100 >= 801) + type == CV_32FC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_32f_C1R ://Aug 2013: bug in IPP 7.1, 8.0 +#endif + 0; + if (ippFuncC1) + { + if (ippFuncC1(src.ptr(), (int)src.step[0], sz, pmean, pstddev) >= 0) { - typedef IppStatus (CV_STDCALL* ippiMaskMeanStdDevFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *, Ipp64f *); - ippiMaskMeanStdDevFuncC1 ippFuncC1 = - type == CV_8UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_8u_C1MR : - type == CV_16UC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_16u_C1MR : - type == CV_32FC1 ? (ippiMaskMeanStdDevFuncC1)ippiMean_StdDev_32f_C1MR : - 0; - if( ippFuncC1 ) - { - if( ippFuncC1(src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, pmean, pstddev) >= 0 ) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); - } - typedef IppStatus (CV_STDCALL* ippiMaskMeanStdDevFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *, Ipp64f *); - ippiMaskMeanStdDevFuncC3 ippFuncC3 = - type == CV_8UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CMR : - type == CV_16UC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CMR : - type == CV_32FC3 ? (ippiMaskMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CMR : - 0; - if( ippFuncC3 ) - { - if( ippFuncC3(src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 1, &pmean[0], &pstddev[0]) >= 0 && - ippFuncC3(src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 2, &pmean[1], &pstddev[1]) >= 0 && - ippFuncC3(src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, 3, &pmean[2], &pstddev[2]) >= 0 ) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); - } + return true; } - else + } + typedef IppStatus(CV_STDCALL* ippiMeanStdDevFuncC3)(const void *, int, IppiSize, int, Ipp64f *, Ipp64f *); + ippiMeanStdDevFuncC3 ippFuncC3 = + type == CV_8UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CR : + type == CV_16UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CR : + type == CV_32FC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CR : + 0; + if (ippFuncC3) + { + if (ippFuncC3(src.ptr(), (int)src.step[0], sz, 1, &pmean[0], &pstddev[0]) >= 0 && + ippFuncC3(src.ptr(), (int)src.step[0], sz, 2, &pmean[1], &pstddev[1]) >= 0 && + ippFuncC3(src.ptr(), (int)src.step[0], sz, 3, &pmean[2], &pstddev[2]) >= 0) { - typedef IppStatus (CV_STDCALL* ippiMeanStdDevFuncC1)(const void *, int, IppiSize, Ipp64f *, Ipp64f *); - ippiMeanStdDevFuncC1 ippFuncC1 = - type == CV_8UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_8u_C1R : - type == CV_16UC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_16u_C1R : -#if (IPP_VERSION_X100 >= 801) - type == CV_32FC1 ? (ippiMeanStdDevFuncC1)ippiMean_StdDev_32f_C1R ://Aug 2013: bug in IPP 7.1, 8.0 -#endif - 0; - if( ippFuncC1 ) - { - if( ippFuncC1(src.ptr(), (int)src.step[0], sz, pmean, pstddev) >= 0 ) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); - } - typedef IppStatus (CV_STDCALL* ippiMeanStdDevFuncC3)(const void *, int, IppiSize, int, Ipp64f *, Ipp64f *); - ippiMeanStdDevFuncC3 ippFuncC3 = - type == CV_8UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_8u_C3CR : - type == CV_16UC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_16u_C3CR : - type == CV_32FC3 ? (ippiMeanStdDevFuncC3)ippiMean_StdDev_32f_C3CR : - 0; - if( ippFuncC3 ) - { - if( ippFuncC3(src.ptr(), (int)src.step[0], sz, 1, &pmean[0], &pstddev[0]) >= 0 && - ippFuncC3(src.ptr(), (int)src.step[0], sz, 2, &pmean[1], &pstddev[1]) >= 0 && - ippFuncC3(src.ptr(), (int)src.step[0], sz, 3, &pmean[2], &pstddev[2]) >= 0 ) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); - } + return true; } } } #endif + return false; +} +} +#endif + +void cv::meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv, InputArray _mask ) +{ + CV_OCL_RUN(OCL_PERFORMANCE_CHECK(_src.isUMat()) && _src.dims() <= 2, + ocl_meanStdDev(_src, _mean, _sdv, _mask)) + + Mat src = _src.getMat(), mask = _mask.getMat(); + CV_Assert( mask.empty() || mask.type() == CV_8UC1 ); +#ifdef HAVE_IPP + Size sz = _src.dims() <= 2 ? _src.size() : Size(); + size_t total_size = _src.total(); + int rows = sz.height; + int cols = rows ? (int)(total_size / rows) : 0; +#endif + CV_IPP_RUN(IPP_VERSION_MAJOR >= 7 && (_src.dims() == 2 || (_src.isContinuous() && _mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size)), + ipp_meanStdDev(src, _mean, _sdv, mask)); + + + int k, cn = src.channels(), depth = src.depth(); + SumSqrFunc func = getSumSqrTab(depth); @@ -1830,6 +1864,7 @@ void cv::meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv, Input } } + /****************************************************************************************\ * minMaxLoc * \****************************************************************************************/ @@ -2181,115 +2216,120 @@ static bool ocl_minMaxIdx( InputArray _src, double* minVal, double* maxVal, int* #endif -} - -void cv::minMaxIdx(InputArray _src, double* minVal, - double* maxVal, int* minIdx, int* maxIdx, - InputArray _mask) +#if defined (HAVE_IPP) +static bool ipp_minMaxIdx( InputArray _src, double* minVal, double* maxVal, int* minIdx, int* maxIdx, InputArray _mask) { +#if (IPP_VERSION_MAJOR >= 7) int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); - CV_Assert( (cn == 1 && (_mask.empty() || _mask.type() == CV_8U)) || - (cn > 1 && _mask.empty() && !minIdx && !maxIdx) ); - - CV_OCL_RUN(OCL_PERFORMANCE_CHECK(_src.isUMat()) && _src.dims() <= 2 && (_mask.empty() || _src.size() == _mask.size()), - ocl_minMaxIdx(_src, minVal, maxVal, minIdx, maxIdx, _mask)) - Mat src = _src.getMat(), mask = _mask.getMat(); -#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CV_IPP_CHECK() - { - size_t total_size = src.total(); - int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0; - if( src.dims == 2 || (src.isContinuous() && mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) ) - { - IppiSize sz = { cols * cn, rows }; + size_t total_size = src.total(); + int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0; + IppiSize sz = { cols * cn, rows }; - if( !mask.empty() ) - { - typedef IppStatus (CV_STDCALL* ippiMaskMinMaxIndxFuncC1)(const void *, int, const void *, int, - IppiSize, Ipp32f *, Ipp32f *, IppiPoint *, IppiPoint *); + if( !mask.empty() ) + { + typedef IppStatus (CV_STDCALL* ippiMaskMinMaxIndxFuncC1)(const void *, int, const void *, int, + IppiSize, Ipp32f *, Ipp32f *, IppiPoint *, IppiPoint *); - CV_SUPPRESS_DEPRECATED_START - ippiMaskMinMaxIndxFuncC1 ippFuncC1 = - type == CV_8UC1 ? (ippiMaskMinMaxIndxFuncC1)ippiMinMaxIndx_8u_C1MR : - type == CV_8SC1 ? (ippiMaskMinMaxIndxFuncC1)ippiMinMaxIndx_8s_C1MR : - type == CV_16UC1 ? (ippiMaskMinMaxIndxFuncC1)ippiMinMaxIndx_16u_C1MR : - type == CV_32FC1 ? (ippiMaskMinMaxIndxFuncC1)ippiMinMaxIndx_32f_C1MR : 0; - CV_SUPPRESS_DEPRECATED_END + CV_SUPPRESS_DEPRECATED_START + ippiMaskMinMaxIndxFuncC1 ippFuncC1 = + type == CV_8UC1 ? (ippiMaskMinMaxIndxFuncC1)ippiMinMaxIndx_8u_C1MR : + type == CV_8SC1 ? (ippiMaskMinMaxIndxFuncC1)ippiMinMaxIndx_8s_C1MR : + type == CV_16UC1 ? (ippiMaskMinMaxIndxFuncC1)ippiMinMaxIndx_16u_C1MR : + type == CV_32FC1 ? (ippiMaskMinMaxIndxFuncC1)ippiMinMaxIndx_32f_C1MR : 0; + CV_SUPPRESS_DEPRECATED_END - if( ippFuncC1 ) + if( ippFuncC1 ) + { + Ipp32f min, max; + IppiPoint minp, maxp; + if( ippFuncC1(src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, &min, &max, &minp, &maxp) >= 0 ) + { + if( minVal ) + *minVal = (double)min; + if( maxVal ) + *maxVal = (double)max; + if( !minp.x && !minp.y && !maxp.x && !maxp.y && !mask.ptr()[0] ) + minp.x = maxp.x = -1; + if( minIdx ) { - Ipp32f min, max; - IppiPoint minp, maxp; - if( ippFuncC1(src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, &min, &max, &minp, &maxp) >= 0 ) - { - if( minVal ) - *minVal = (double)min; - if( maxVal ) - *maxVal = (double)max; - if( !minp.x && !minp.y && !maxp.x && !maxp.y && !mask.ptr()[0] ) - minp.x = maxp.x = -1; - if( minIdx ) - { - size_t minidx = minp.y * cols + minp.x + 1; - ofs2idx(src, minidx, minIdx); - } - if( maxIdx ) - { - size_t maxidx = maxp.y * cols + maxp.x + 1; - ofs2idx(src, maxidx, maxIdx); - } - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); + size_t minidx = minp.y * cols + minp.x + 1; + ofs2idx(src, minidx, minIdx); + } + if( maxIdx ) + { + size_t maxidx = maxp.y * cols + maxp.x + 1; + ofs2idx(src, maxidx, maxIdx); } + return true; } - else - { - typedef IppStatus (CV_STDCALL* ippiMinMaxIndxFuncC1)(const void *, int, IppiSize, Ipp32f *, Ipp32f *, IppiPoint *, IppiPoint *); - - CV_SUPPRESS_DEPRECATED_START - ippiMinMaxIndxFuncC1 ippFuncC1 = - depth == CV_8U ? (ippiMinMaxIndxFuncC1)ippiMinMaxIndx_8u_C1R : - depth == CV_8S ? (ippiMinMaxIndxFuncC1)ippiMinMaxIndx_8s_C1R : - depth == CV_16U ? (ippiMinMaxIndxFuncC1)ippiMinMaxIndx_16u_C1R : - #if !((defined _MSC_VER && defined _M_IX86) || defined __i386__) - depth == CV_32F ? (ippiMinMaxIndxFuncC1)ippiMinMaxIndx_32f_C1R : - #endif - 0; - CV_SUPPRESS_DEPRECATED_END + } + } + else + { + typedef IppStatus (CV_STDCALL* ippiMinMaxIndxFuncC1)(const void *, int, IppiSize, Ipp32f *, Ipp32f *, IppiPoint *, IppiPoint *); - if( ippFuncC1 ) + CV_SUPPRESS_DEPRECATED_START + ippiMinMaxIndxFuncC1 ippFuncC1 = + depth == CV_8U ? (ippiMinMaxIndxFuncC1)ippiMinMaxIndx_8u_C1R : + depth == CV_8S ? (ippiMinMaxIndxFuncC1)ippiMinMaxIndx_8s_C1R : + depth == CV_16U ? (ippiMinMaxIndxFuncC1)ippiMinMaxIndx_16u_C1R : + depth == CV_32F ? (ippiMinMaxIndxFuncC1)ippiMinMaxIndx_32f_C1R : 0; + CV_SUPPRESS_DEPRECATED_END + + if( ippFuncC1 ) + { + Ipp32f min, max; + IppiPoint minp, maxp; + if( ippFuncC1(src.ptr(), (int)src.step[0], sz, &min, &max, &minp, &maxp) >= 0 ) + { + if( minVal ) + *minVal = (double)min; + if( maxVal ) + *maxVal = (double)max; + if( minIdx ) { - Ipp32f min, max; - IppiPoint minp, maxp; - if( ippFuncC1(src.ptr(), (int)src.step[0], sz, &min, &max, &minp, &maxp) >= 0 ) - { - if( minVal ) - *minVal = (double)min; - if( maxVal ) - *maxVal = (double)max; - if( minIdx ) - { - size_t minidx = minp.y * cols + minp.x + 1; - ofs2idx(src, minidx, minIdx); - } - if( maxIdx ) - { - size_t maxidx = maxp.y * cols + maxp.x + 1; - ofs2idx(src, maxidx, maxIdx); - } - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); + size_t minidx = minp.y * cols + minp.x + 1; + ofs2idx(src, minidx, minIdx); } + if( maxIdx ) + { + size_t maxidx = maxp.y * cols + maxp.x + 1; + ofs2idx(src, maxidx, maxIdx); + } + return true; } } } #endif + return false; +} +#endif + +} + +void cv::minMaxIdx(InputArray _src, double* minVal, + double* maxVal, int* minIdx, int* maxIdx, + InputArray _mask) +{ + int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type); + CV_Assert( (cn == 1 && (_mask.empty() || _mask.type() == CV_8U)) || + (cn > 1 && _mask.empty() && !minIdx && !maxIdx) ); + + CV_OCL_RUN(OCL_PERFORMANCE_CHECK(_src.isUMat()) && _src.dims() <= 2 && (_mask.empty() || _src.size() == _mask.size()), + ocl_minMaxIdx(_src, minVal, maxVal, minIdx, maxIdx, _mask)) + + Mat src = _src.getMat(), mask = _mask.getMat(); +#ifdef HAVE_IPP + Size sz = _src.dims() <= 2 ? _src.size() : Size(); + size_t total_size = _src.total(); + int rows = sz.height; + int cols = rows ? (int)(total_size/rows) : 0; +#endif + CV_IPP_RUN(IPP_VERSION_MAJOR >= 7 && (_src.dims() == 2 || (_src.isContinuous() && _mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size)), + ipp_minMaxIdx(src, minVal, maxVal, minIdx, maxIdx, mask)) + MinMaxIdxFunc func = getMinmaxTab(depth); CV_Assert( func != 0 ); @@ -2332,6 +2372,7 @@ void cv::minMaxIdx(InputArray _src, double* minVal, ofs2idx(src, maxidx, maxIdx); } + void cv::minMaxLoc( InputArray _img, double* minVal, double* maxVal, Point* minLoc, Point* maxLoc, InputArray mask ) { @@ -2613,111 +2654,96 @@ static bool ocl_norm( InputArray _src, int normType, InputArray _mask, double & } -double cv::norm( InputArray _src, int normType, InputArray _mask ) -{ - normType &= NORM_TYPE_MASK; - CV_Assert( normType == NORM_INF || normType == NORM_L1 || - normType == NORM_L2 || normType == NORM_L2SQR || - ((normType == NORM_HAMMING || normType == NORM_HAMMING2) && _src.type() == CV_8U) ); - -#ifdef HAVE_OPENCL - double _result = 0; - CV_OCL_RUN_(OCL_PERFORMANCE_CHECK(_src.isUMat()) && _src.dims() <= 2, - ocl_norm(_src, normType, _mask, _result), - _result) -#endif - - Mat src = _src.getMat(), mask = _mask.getMat(); - int depth = src.depth(), cn = src.channels(); - #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CV_IPP_CHECK() - { - size_t total_size = src.total(); - int rows = src.size[0], cols = rows ? (int)(total_size/rows) : 0; - if( (src.dims == 2 || (src.isContinuous() && mask.isContinuous())) - && cols > 0 && (size_t)rows*cols == total_size - && (normType == NORM_INF || normType == NORM_L1 || - normType == NORM_L2 || normType == NORM_L2SQR) ) - { - IppiSize sz = { cols, rows }; - int type = src.type(); - if( !mask.empty() ) +namespace cv { +static bool ipp_norm(InputArray _src, int normType, InputArray _mask, double & result) +{ + Mat src = _src.getMat(), mask = _mask.getMat(); + int cn = src.channels(); + size_t total_size = src.total(); + int rows = src.size[0], cols = rows ? (int)(total_size / rows) : 0; + if ((src.dims == 2 || (src.isContinuous() && mask.isContinuous())) + && cols > 0 && (size_t)rows*cols == total_size + && (normType == NORM_INF || normType == NORM_L1 || + normType == NORM_L2 || normType == NORM_L2SQR)) + { + IppiSize sz = { cols, rows }; + int type = src.type(); + if (!mask.empty()) { - typedef IppStatus (CV_STDCALL* ippiMaskNormFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *); + typedef IppStatus(CV_STDCALL* ippiMaskNormFuncC1)(const void *, int, const void *, int, IppiSize, Ipp64f *); ippiMaskNormFuncC1 ippFuncC1 = normType == NORM_INF ? (type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_8u_C1MR : type == CV_8SC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_8s_C1MR : - // type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_16u_C1MR : + // type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_16u_C1MR : type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_Inf_32f_C1MR : 0) : - normType == NORM_L1 ? + normType == NORM_L1 ? (type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_8u_C1MR : type == CV_8SC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_8s_C1MR : type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_16u_C1MR : type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_L1_32f_C1MR : 0) : - normType == NORM_L2 || normType == NORM_L2SQR ? + normType == NORM_L2 || normType == NORM_L2SQR ? (type == CV_8UC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_8u_C1MR : type == CV_8SC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_8s_C1MR : type == CV_16UC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_16u_C1MR : type == CV_32FC1 ? (ippiMaskNormFuncC1)ippiNorm_L2_32f_C1MR : 0) : 0; - if( ippFuncC1 ) + if (ippFuncC1) { Ipp64f norm; - if( ippFuncC1(src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, &norm) >= 0 ) + if (ippFuncC1(src.ptr(), (int)src.step[0], mask.ptr(), (int)mask.step[0], sz, &norm) >= 0) { - CV_IMPL_ADD(CV_IMPL_IPP); - return normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm; + result = normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm; + return true; } - - setIppErrorStatus(); + return false; } /*typedef IppStatus (CV_STDCALL* ippiMaskNormFuncC3)(const void *, int, const void *, int, IppiSize, int, Ipp64f *); ippiMaskNormFuncC3 ippFuncC3 = - normType == NORM_INF ? - (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_8u_C3CMR : - type == CV_8SC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_8s_C3CMR : - type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_16u_C3CMR : - type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_32f_C3CMR : - 0) : + normType == NORM_INF ? + (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_8u_C3CMR : + type == CV_8SC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_8s_C3CMR : + type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_16u_C3CMR : + type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_Inf_32f_C3CMR : + 0) : normType == NORM_L1 ? - (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_8u_C3CMR : - type == CV_8SC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_8s_C3CMR : - type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_16u_C3CMR : - type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_32f_C3CMR : - 0) : + (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_8u_C3CMR : + type == CV_8SC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_8s_C3CMR : + type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_16u_C3CMR : + type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L1_32f_C3CMR : + 0) : normType == NORM_L2 || normType == NORM_L2SQR ? - (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_8u_C3CMR : - type == CV_8SC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_8s_C3CMR : - type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_16u_C3CMR : - type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_32f_C3CMR : - 0) : 0; + (type == CV_8UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_8u_C3CMR : + type == CV_8SC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_8s_C3CMR : + type == CV_16UC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_16u_C3CMR : + type == CV_32FC3 ? (ippiMaskNormFuncC3)ippiNorm_L2_32f_C3CMR : + 0) : 0; if( ippFuncC3 ) { - Ipp64f norm1, norm2, norm3; - if( ippFuncC3(src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 1, &norm1) >= 0 && - ippFuncC3(src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 2, &norm2) >= 0 && - ippFuncC3(src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 3, &norm3) >= 0) - { - Ipp64f norm = - normType == NORM_INF ? std::max(std::max(norm1, norm2), norm3) : - normType == NORM_L1 ? norm1 + norm2 + norm3 : - normType == NORM_L2 || normType == NORM_L2SQR ? std::sqrt(norm1 * norm1 + norm2 * norm2 + norm3 * norm3) : - 0; - CV_IMPL_ADD(CV_IMPL_IPP); - return normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm; - } - setIppErrorStatus(); + Ipp64f norm1, norm2, norm3; + if( ippFuncC3(src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 1, &norm1) >= 0 && + ippFuncC3(src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 2, &norm2) >= 0 && + ippFuncC3(src.data, (int)src.step[0], mask.data, (int)mask.step[0], sz, 3, &norm3) >= 0) + { + Ipp64f norm = + normType == NORM_INF ? std::max(std::max(norm1, norm2), norm3) : + normType == NORM_L1 ? norm1 + norm2 + norm3 : + normType == NORM_L2 || normType == NORM_L2SQR ? std::sqrt(norm1 * norm1 + norm2 * norm2 + norm3 * norm3) : + 0; + CV_IMPL_ADD(CV_IMPL_IPP); + return normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm; + } + setIppErrorStatus(); }*/ } else { - typedef IppStatus (CV_STDCALL* ippiNormFuncHint)(const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint); - typedef IppStatus (CV_STDCALL* ippiNormFuncNoHint)(const void *, int, IppiSize, Ipp64f *); + typedef IppStatus(CV_STDCALL* ippiNormFuncHint)(const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint); + typedef IppStatus(CV_STDCALL* ippiNormFuncNoHint)(const void *, int, IppiSize, Ipp64f *); ippiNormFuncHint ippFuncHint = normType == NORM_L1 ? (type == CV_32FC1 ? (ippiNormFuncHint)ippiNorm_L1_32f_C1R : @@ -2770,15 +2796,17 @@ double cv::norm( InputArray _src, int normType, InputArray _mask ) 0) : 0; // Make sure only zero or one version of the function pointer is valid CV_Assert(!ippFuncHint || !ippFuncNoHint); - if( ippFuncHint || ippFuncNoHint ) + if (ippFuncHint || ippFuncNoHint) { Ipp64f norm_array[4]; IppStatus ret = ippFuncHint ? ippFuncHint(src.ptr(), (int)src.step[0], sz, norm_array, ippAlgHintAccurate) : - ippFuncNoHint(src.ptr(), (int)src.step[0], sz, norm_array); - if( ret >= 0 ) + ippFuncNoHint(src.ptr(), (int)src.step[0], sz, norm_array); + if (ret >= 0) { Ipp64f norm = (normType == NORM_L2 || normType == NORM_L2SQR) ? norm_array[0] * norm_array[0] : norm_array[0]; - for( int i = 1; i < cn; i++ ) + CV_Assert(cn <= 4); + cn = min(cn, 4); + for (int i = 1; i < cn; i++) { norm = normType == NORM_INF ? std::max(norm, norm_array[i]) : @@ -2786,16 +2814,40 @@ double cv::norm( InputArray _src, int normType, InputArray _mask ) normType == NORM_L2 || normType == NORM_L2SQR ? norm + norm_array[i] * norm_array[i] : 0; } - CV_IMPL_ADD(CV_IMPL_IPP); - return normType == NORM_L2 ? (double)std::sqrt(norm) : (double)norm; + result = normType == NORM_L2 ? (double)std::sqrt(norm) : (double)norm; + return true; } - setIppErrorStatus(); + return false; } } } + return false; } +} +#endif + + +double cv::norm( InputArray _src, int normType, InputArray _mask ) +{ + normType &= NORM_TYPE_MASK; + CV_Assert( normType == NORM_INF || normType == NORM_L1 || + normType == NORM_L2 || normType == NORM_L2SQR || + ((normType == NORM_HAMMING || normType == NORM_HAMMING2) && _src.type() == CV_8U) ); + +#if defined HAVE_OPENCL || defined HAVE_IPP + double _result = 0; #endif +#ifdef HAVE_OPENCL + CV_OCL_RUN_(OCL_PERFORMANCE_CHECK(_src.isUMat()) && _src.dims() <= 2, + ocl_norm(_src, normType, _mask, _result), + _result) +#endif + + Mat src = _src.getMat(), mask = _mask.getMat(); + int depth = src.depth(), cn = src.channels(); + CV_IPP_RUN(true, ipp_norm(_src, normType, _mask, _result), _result); + if( src.isContinuous() && mask.empty() ) { size_t len = src.total()*cn; @@ -2992,151 +3044,129 @@ static bool ocl_norm( InputArray _src1, InputArray _src2, int normType, InputArr #endif -double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask ) +namespace cv { - CV_Assert( _src1.sameSize(_src2) && _src1.type() == _src2.type() ); - -#ifdef HAVE_OPENCL - double _result = 0; - CV_OCL_RUN_(OCL_PERFORMANCE_CHECK(_src1.isUMat()), - ocl_norm(_src1, _src2, normType, _mask, _result), - _result) -#endif - - if( normType & CV_RELATIVE ) - { #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CV_IPP_CHECK() - { - Mat src1 = _src1.getMat(), src2 = _src2.getMat(), mask = _mask.getMat(); - - normType &= NORM_TYPE_MASK; - CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR || - ((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src1.type() == CV_8U) ); - size_t total_size = src1.total(); - int rows = src1.size[0], cols = rows ? (int)(total_size/rows) : 0; - if( (src1.dims == 2 || (src1.isContinuous() && src2.isContinuous() && mask.isContinuous())) - && cols > 0 && (size_t)rows*cols == total_size - && (normType == NORM_INF || normType == NORM_L1 || - normType == NORM_L2 || normType == NORM_L2SQR) ) + static bool ipp_norm_rel(InputArray _src1, InputArray _src2, int normType, InputArray _mask, double & result) + { + Mat src1 = _src1.getMat(), src2 = _src2.getMat(), mask = _mask.getMat(); + + normType &= NORM_TYPE_MASK; + CV_Assert(normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 || normType == NORM_L2SQR || + ((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src1.type() == CV_8U)); + size_t total_size = src1.total(); + int rows = src1.size[0], cols = rows ? (int)(total_size / rows) : 0; + if ((src1.dims == 2 || (src1.isContinuous() && src2.isContinuous() && mask.isContinuous())) + && cols > 0 && (size_t)rows*cols == total_size + && (normType == NORM_INF || normType == NORM_L1 || + normType == NORM_L2 || normType == NORM_L2SQR)) + { + IppiSize sz = { cols, rows }; + int type = src1.type(); + if (!mask.empty()) { - IppiSize sz = { cols, rows }; - int type = src1.type(); - if( !mask.empty() ) - { - typedef IppStatus (CV_STDCALL* ippiMaskNormRelFuncC1)(const void *, int, const void *, int, const void *, int, IppiSize, Ipp64f *); - ippiMaskNormRelFuncC1 ippFuncC1 = - normType == NORM_INF ? - (type == CV_8UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_Inf_8u_C1MR : + typedef IppStatus(CV_STDCALL* ippiMaskNormRelFuncC1)(const void *, int, const void *, int, const void *, int, IppiSize, Ipp64f *); + ippiMaskNormRelFuncC1 ippFuncC1 = + normType == NORM_INF ? + (type == CV_8UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_Inf_8u_C1MR : #ifndef __APPLE__ - type == CV_8SC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_Inf_8s_C1MR : + type == CV_8SC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_Inf_8s_C1MR : #endif - type == CV_16UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_Inf_16u_C1MR : - type == CV_32FC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_Inf_32f_C1MR : - 0) : - normType == NORM_L1 ? - (type == CV_8UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L1_8u_C1MR : + type == CV_16UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_Inf_16u_C1MR : + type == CV_32FC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_Inf_32f_C1MR : + 0) : + normType == NORM_L1 ? + (type == CV_8UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L1_8u_C1MR : #ifndef __APPLE__ - type == CV_8SC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L1_8s_C1MR : + type == CV_8SC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L1_8s_C1MR : #endif - type == CV_16UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L1_16u_C1MR : - type == CV_32FC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L1_32f_C1MR : - 0) : - normType == NORM_L2 || normType == NORM_L2SQR ? - (type == CV_8UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L2_8u_C1MR : - type == CV_8SC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L2_8s_C1MR : - type == CV_16UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L2_16u_C1MR : - type == CV_32FC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L2_32f_C1MR : - 0) : 0; - if( ippFuncC1 ) + type == CV_16UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L1_16u_C1MR : + type == CV_32FC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L1_32f_C1MR : + 0) : + normType == NORM_L2 || normType == NORM_L2SQR ? + (type == CV_8UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L2_8u_C1MR : + type == CV_8SC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L2_8s_C1MR : + type == CV_16UC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L2_16u_C1MR : + type == CV_32FC1 ? (ippiMaskNormRelFuncC1)ippiNormRel_L2_32f_C1MR : + 0) : 0; + if (ippFuncC1) + { + Ipp64f norm; + if (ippFuncC1(src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], mask.ptr(), (int)mask.step[0], sz, &norm) >= 0) { - Ipp64f norm; - if( ippFuncC1(src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], mask.ptr(), (int)mask.step[0], sz, &norm) >= 0 ) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm; - } - setIppErrorStatus(); + result = normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm; + return true; } + return false; } - else + } + else + { + typedef IppStatus(CV_STDCALL* ippiNormRelFuncNoHint)(const void *, int, const void *, int, IppiSize, Ipp64f *); + typedef IppStatus(CV_STDCALL* ippiNormRelFuncHint)(const void *, int, const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint); + ippiNormRelFuncNoHint ippFuncNoHint = + normType == NORM_INF ? + (type == CV_8UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_8u_C1R : + type == CV_16UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_16u_C1R : + type == CV_16SC1 ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_16s_C1R : + type == CV_32FC1 ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_32f_C1R : + 0) : + normType == NORM_L1 ? + (type == CV_8UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L1_8u_C1R : + type == CV_16UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L1_16u_C1R : + type == CV_16SC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L1_16s_C1R : + 0) : + normType == NORM_L2 || normType == NORM_L2SQR ? + (type == CV_8UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L2_8u_C1R : + type == CV_16UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L2_16u_C1R : + type == CV_16SC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L2_16s_C1R : + 0) : 0; + ippiNormRelFuncHint ippFuncHint = + normType == NORM_L1 ? + (type == CV_32FC1 ? (ippiNormRelFuncHint)ippiNormRel_L1_32f_C1R : + 0) : + normType == NORM_L2 || normType == NORM_L2SQR ? + (type == CV_32FC1 ? (ippiNormRelFuncHint)ippiNormRel_L2_32f_C1R : + 0) : 0; + if (ippFuncNoHint) { - typedef IppStatus (CV_STDCALL* ippiNormRelFuncNoHint)(const void *, int, const void *, int, IppiSize, Ipp64f *); - typedef IppStatus (CV_STDCALL* ippiNormRelFuncHint)(const void *, int, const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint); - ippiNormRelFuncNoHint ippFuncNoHint = - normType == NORM_INF ? - (type == CV_8UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_8u_C1R : - type == CV_16UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_16u_C1R : - type == CV_16SC1 ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_16s_C1R : - type == CV_32FC1 ? (ippiNormRelFuncNoHint)ippiNormRel_Inf_32f_C1R : - 0) : - normType == NORM_L1 ? - (type == CV_8UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L1_8u_C1R : - type == CV_16UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L1_16u_C1R : - type == CV_16SC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L1_16s_C1R : - 0) : - normType == NORM_L2 || normType == NORM_L2SQR ? - (type == CV_8UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L2_8u_C1R : - type == CV_16UC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L2_16u_C1R : - type == CV_16SC1 ? (ippiNormRelFuncNoHint)ippiNormRel_L2_16s_C1R : - 0) : 0; - ippiNormRelFuncHint ippFuncHint = - normType == NORM_L1 ? - (type == CV_32FC1 ? (ippiNormRelFuncHint)ippiNormRel_L1_32f_C1R : - 0) : - normType == NORM_L2 || normType == NORM_L2SQR ? - (type == CV_32FC1 ? (ippiNormRelFuncHint)ippiNormRel_L2_32f_C1R : - 0) : 0; - if (ippFuncNoHint) + Ipp64f norm; + if (ippFuncNoHint(src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm) >= 0) { - Ipp64f norm; - if( ippFuncNoHint(src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm) >= 0 ) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return (double)norm; - } - setIppErrorStatus(); + result = (double)norm; + return true; } - if (ippFuncHint) + return false; + } + if (ippFuncHint) + { + Ipp64f norm; + if (ippFuncHint(src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm, ippAlgHintAccurate) >= 0) { - Ipp64f norm; - if( ippFuncHint(src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, &norm, ippAlgHintAccurate) >= 0 ) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return (double)norm; - } - setIppErrorStatus(); + result = (double)norm; + return true; } + return false; } } } -#endif - return norm(_src1, _src2, normType & ~CV_RELATIVE, _mask)/(norm(_src2, normType, _mask) + DBL_EPSILON); + return false; } - - Mat src1 = _src1.getMat(), src2 = _src2.getMat(), mask = _mask.getMat(); - int depth = src1.depth(), cn = src1.channels(); - - normType &= 7; - CV_Assert( normType == NORM_INF || normType == NORM_L1 || - normType == NORM_L2 || normType == NORM_L2SQR || - ((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src1.type() == CV_8U) ); - -#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CV_IPP_CHECK() + static bool ipp_norm_dif(InputArray _src1, InputArray _src2, int normType, InputArray _mask, double & result) { + Mat src1 = _src1.getMat(), src2 = _src2.getMat(), mask = _mask.getMat(); size_t total_size = src1.total(); - int rows = src1.size[0], cols = rows ? (int)(total_size/rows) : 0; - if( (src1.dims == 2 || (src1.isContinuous() && src2.isContinuous() && mask.isContinuous())) + int rows = src1.size[0], cols = rows ? (int)(total_size / rows) : 0; + if ((src1.dims == 2 || (src1.isContinuous() && src2.isContinuous() && mask.isContinuous())) && cols > 0 && (size_t)rows*cols == total_size && (normType == NORM_INF || normType == NORM_L1 || - normType == NORM_L2 || normType == NORM_L2SQR) ) + normType == NORM_L2 || normType == NORM_L2SQR)) { IppiSize sz = { cols, rows }; int type = src1.type(); - if( !mask.empty() ) + if (!mask.empty()) { - typedef IppStatus (CV_STDCALL* ippiMaskNormDiffFuncC1)(const void *, int, const void *, int, const void *, int, IppiSize, Ipp64f *); + typedef IppStatus(CV_STDCALL* ippiMaskNormDiffFuncC1)(const void *, int, const void *, int, const void *, int, IppiSize, Ipp64f *); ippiMaskNormDiffFuncC1 ippFuncC1 = normType == NORM_INF ? (type == CV_8UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_Inf_8u_C1MR : @@ -3158,18 +3188,18 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m type == CV_16UC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L2_16u_C1MR : type == CV_32FC1 ? (ippiMaskNormDiffFuncC1)ippiNormDiff_L2_32f_C1MR : 0) : 0; - if( ippFuncC1 ) + if (ippFuncC1) { Ipp64f norm; - if( ippFuncC1(src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], mask.ptr(), (int)mask.step[0], sz, &norm) >= 0 ) + if (ippFuncC1(src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], mask.ptr(), (int)mask.step[0], sz, &norm) >= 0) { - CV_IMPL_ADD(CV_IMPL_IPP); - return normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm; + result = normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm; + return true; } - setIppErrorStatus(); + return false; } #ifndef __APPLE__ - typedef IppStatus (CV_STDCALL* ippiMaskNormDiffFuncC3)(const void *, int, const void *, int, const void *, int, IppiSize, int, Ipp64f *); + typedef IppStatus(CV_STDCALL* ippiMaskNormDiffFuncC3)(const void *, int, const void *, int, const void *, int, IppiSize, int, Ipp64f *); ippiMaskNormDiffFuncC3 ippFuncC3 = normType == NORM_INF ? (type == CV_8UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_Inf_8u_C3CMR : @@ -3189,10 +3219,10 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_16u_C3CMR : type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_32f_C3CMR : 0) : 0; - if( ippFuncC3 ) + if (ippFuncC3) { Ipp64f norm1, norm2, norm3; - if( ippFuncC3(src1.data, (int)src1.step[0], src2.data, (int)src2.step[0], mask.data, (int)mask.step[0], sz, 1, &norm1) >= 0 && + if (ippFuncC3(src1.data, (int)src1.step[0], src2.data, (int)src2.step[0], mask.data, (int)mask.step[0], sz, 1, &norm1) >= 0 && ippFuncC3(src1.data, (int)src1.step[0], src2.data, (int)src2.step[0], mask.data, (int)mask.step[0], sz, 2, &norm2) >= 0 && ippFuncC3(src1.data, (int)src1.step[0], src2.data, (int)src2.step[0], mask.data, (int)mask.step[0], sz, 3, &norm3) >= 0) { @@ -3201,17 +3231,17 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m normType == NORM_L1 ? norm1 + norm2 + norm3 : normType == NORM_L2 || normType == NORM_L2SQR ? std::sqrt(norm1 * norm1 + norm2 * norm2 + norm3 * norm3) : 0; - CV_IMPL_ADD(CV_IMPL_IPP); - return normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm; + result = normType == NORM_L2SQR ? (double)(norm * norm) : (double)norm; + return true; } - setIppErrorStatus(); + return false; } #endif } else { - typedef IppStatus (CV_STDCALL* ippiNormDiffFuncHint)(const void *, int, const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint); - typedef IppStatus (CV_STDCALL* ippiNormDiffFuncNoHint)(const void *, int, const void *, int, IppiSize, Ipp64f *); + typedef IppStatus(CV_STDCALL* ippiNormDiffFuncHint)(const void *, int, const void *, int, IppiSize, Ipp64f *, IppHintAlgorithm hint); + typedef IppStatus(CV_STDCALL* ippiNormDiffFuncNoHint)(const void *, int, const void *, int, IppiSize, Ipp64f *); ippiNormDiffFuncHint ippFuncHint = normType == NORM_L1 ? (type == CV_32FC1 ? (ippiNormDiffFuncHint)ippiNormDiff_L1_32f_C1R : @@ -3266,15 +3296,17 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m 0) : 0; // Make sure only zero or one version of the function pointer is valid CV_Assert(!ippFuncHint || !ippFuncNoHint); - if( ippFuncHint || ippFuncNoHint ) + if (ippFuncHint || ippFuncNoHint) { Ipp64f norm_array[4]; IppStatus ret = ippFuncHint ? ippFuncHint(src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, norm_array, ippAlgHintAccurate) : - ippFuncNoHint(src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, norm_array); - if( ret >= 0 ) + ippFuncNoHint(src1.ptr(), (int)src1.step[0], src2.ptr(), (int)src2.step[0], sz, norm_array); + if (ret >= 0) { Ipp64f norm = (normType == NORM_L2 || normType == NORM_L2SQR) ? norm_array[0] * norm_array[0] : norm_array[0]; - for( int i = 1; i < src1.channels(); i++ ) + CV_Assert(src1.channels() <= 4); + int cn = min(src1.channels(), 4); + for (int i = 1; i < cn; i++) { norm = normType == NORM_INF ? std::max(norm, norm_array[i]) : @@ -3282,15 +3314,47 @@ double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _m normType == NORM_L2 || normType == NORM_L2SQR ? norm + norm_array[i] * norm_array[i] : 0; } - CV_IMPL_ADD(CV_IMPL_IPP); - return normType == NORM_L2 ? (double)std::sqrt(norm) : (double)norm; + result = normType == NORM_L2 ? (double)std::sqrt(norm) : (double)norm; + return true; } - setIppErrorStatus(); + return false; } } } + return false; } #endif +} + + +double cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask ) +{ + CV_Assert( _src1.sameSize(_src2) && _src1.type() == _src2.type() ); + +#if defined HAVE_OPENCL || defined HAVE_IPP + double _result = 0; +#endif + +#ifdef HAVE_OPENCL + CV_OCL_RUN_(OCL_PERFORMANCE_CHECK(_src1.isUMat()), + ocl_norm(_src1, _src2, normType, _mask, _result), + _result) +#endif + + if( normType & CV_RELATIVE ) + { + CV_IPP_RUN(true, ipp_norm_rel(_src1, _src2, normType, _mask, _result), _result); + return norm(_src1, _src2, normType & ~CV_RELATIVE, _mask)/(norm(_src2, normType, _mask) + DBL_EPSILON); + } + + Mat src1 = _src1.getMat(), src2 = _src2.getMat(), mask = _mask.getMat(); + int depth = src1.depth(), cn = src1.channels(); + + normType &= 7; + CV_Assert( normType == NORM_INF || normType == NORM_L1 || + normType == NORM_L2 || normType == NORM_L2SQR || + ((normType == NORM_HAMMING || normType == NORM_HAMMING2) && src1.type() == CV_8U) ); + CV_IPP_RUN(true, ipp_norm_dif(_src1, _src2, normType, _mask, _result), _result); if( src1.isContinuous() && src2.isContinuous() && mask.empty() ) { diff --git a/modules/imgproc/src/accum.cpp b/modules/imgproc/src/accum.cpp index 23dc457..8792e85 100644 --- a/modules/imgproc/src/accum.cpp +++ b/modules/imgproc/src/accum.cpp @@ -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(src.total() * src.elemSize()); - dststep = static_cast(dst.total() * dst.elemSize()); - maskstep = static_cast(mask.total() * mask.elemSize()); - size.width = static_cast(src.total()); - size.height = 1; - } - size.width *= scn; - - if (mask.empty()) - status = ippFunc(src.ptr(), srcstep, dst.ptr(), dststep, ippiSize(size.width, size.height)); - else - status = ippFuncMask(src.ptr(), srcstep, mask.ptr(), maskstep, - dst.ptr(), dststep, ippiSize(size.width, size.height)); - - if (status >= 0) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); + srcstep = static_cast(src.total() * src.elemSize()); + dststep = static_cast(dst.total() * dst.elemSize()); + maskstep = static_cast(mask.total() * mask.elemSize()); + size.width = static_cast(src.total()); + size.height = 1; } + size.width *= scn; + + if (ippFunc) + status = ippFunc(src.ptr(), srcstep, dst.ptr(), dststep, ippiSize(size.width, size.height)); + else if(ippFuncMask) + status = ippFuncMask(src.ptr(), srcstep, mask.ptr(), maskstep, + dst.ptr(), 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(src.total() * src.elemSize()); - dststep = static_cast(dst.total() * dst.elemSize()); - maskstep = static_cast(mask.total() * mask.elemSize()); - size.width = static_cast(src.total()); - size.height = 1; - } - size.width *= scn; - - if (mask.empty()) - status = ippFunc(src.ptr(), srcstep, dst.ptr(), dststep, ippiSize(size.width, size.height)); - else - status = ippFuncMask(src.ptr(), srcstep, mask.ptr(), maskstep, - dst.ptr(), dststep, ippiSize(size.width, size.height)); - - if (status >= 0) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); + srcstep = static_cast(src.total() * src.elemSize()); + dststep = static_cast(dst.total() * dst.elemSize()); + maskstep = static_cast(mask.total() * mask.elemSize()); + size.width = static_cast(src.total()); + size.height = 1; } + size.width *= scn; + + if (ippFunc) + status = ippFunc(src.ptr(), srcstep, dst.ptr(), dststep, ippiSize(size.width, size.height)); + else if(ippFuncMask) + status = ippFuncMask(src.ptr(), srcstep, mask.ptr(), maskstep, + dst.ptr(), 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(src1.total() * src1.elemSize()); + src2step = static_cast(src2.total() * src2.elemSize()); + dststep = static_cast(dst.total() * dst.elemSize()); + maskstep = static_cast(mask.total() * mask.elemSize()); + size.width = static_cast(src1.total()); + size.height = 1; + } + size.width *= scn; + + if (ippFunc) + status = ippFunc(src1.ptr(), src1step, src2.ptr(), src2step, dst.ptr(), + dststep, ippiSize(size.width, size.height)); + else if(ippFuncMask) + status = ippFuncMask(src1.ptr(), src1step, src2.ptr(), src2step, mask.ptr(), maskstep, + dst.ptr(), 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(src1.total() * src1.elemSize()); - src2step = static_cast(src2.total() * src2.elemSize()); - dststep = static_cast(dst.total() * dst.elemSize()); - maskstep = static_cast(mask.total() * mask.elemSize()); - size.width = static_cast(src1.total()); - size.height = 1; - } - size.width *= scn; - - if (mask.empty()) - status = ippFunc(src1.ptr(), src1step, src2.ptr(), src2step, dst.ptr(), - dststep, ippiSize(size.width, size.height)); - else - status = ippFuncMask(src1.ptr(), src1step, src2.ptr(), src2step, mask.ptr(), maskstep, - dst.ptr(), 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(src.total() * src.elemSize()); - dststep = static_cast(dst.total() * dst.elemSize()); - maskstep = static_cast(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(), dststep, ippiSize(size.width, size.height), (Ipp32f)alpha); - else - status = ippFuncMask(src.ptr(), srcstep, mask.ptr(), maskstep, - dst.ptr(), dststep, ippiSize(size.width, size.height), (Ipp32f)alpha); - - if (status >= 0) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); + srcstep = static_cast(src.total() * src.elemSize()); + dststep = static_cast(dst.total() * dst.elemSize()); + maskstep = static_cast(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(), dststep, ippiSize(size.width, size.height), (Ipp32f)alpha); + else if(ippFuncMask) + status = ippFuncMask(src.ptr(), srcstep, mask.ptr(), maskstep, + dst.ptr(), 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 ); diff --git a/modules/imgproc/src/color.cpp b/modules/imgproc/src/color.cpp index f8bc095..6f53a12 100644 --- a/modules/imgproc/src/color.cpp +++ b/modules/imgproc/src/color.cpp @@ -7325,103 +7325,635 @@ static bool ocl_cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) }//namespace cv -////////////////////////////////////////////////////////////////////////////////////////// -// The main function // -////////////////////////////////////////////////////////////////////////////////////////// - -void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) +#ifdef HAVE_IPP +namespace cv +{ +static bool ipp_cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) { int stype = _src.type(); - int scn = CV_MAT_CN(stype), depth = CV_MAT_DEPTH(stype), bidx; - - CV_OCL_RUN( _src.dims() <= 2 && _dst.isUMat() && !(depth == CV_8U && (code == CV_Luv2BGR || code == CV_Luv2RGB)), - ocl_cvtColor(_src, _dst, code, dcn) ) + int scn = CV_MAT_CN(stype), depth = CV_MAT_DEPTH(stype); Mat src = _src.getMat(), dst; Size sz = src.size(); - CV_Assert( depth == CV_8U || depth == CV_16U || depth == CV_32F ); - switch( code ) { +#if IPP_VERSION_MAJOR >= 7 case CV_BGR2BGRA: case CV_RGB2BGRA: case CV_BGRA2BGR: case CV_RGBA2BGR: case CV_RGB2BGR: case CV_BGRA2RGBA: CV_Assert( scn == 3 || scn == 4 ); dcn = code == CV_BGR2BGRA || code == CV_RGB2BGRA || code == CV_BGRA2RGBA ? 4 : 3; - bidx = code == CV_BGR2BGRA || code == CV_BGRA2BGR ? 0 : 2; - _dst.create( sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); -#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CV_IPP_CHECK() + if( code == CV_BGR2BGRA) + { + if ( CvtColorIPPLoop(src, dst, IPPReorderFunctor(ippiSwapChannelsC3C4RTab[depth], 0, 1, 2)) ) + return true; + } + else if( code == CV_BGRA2BGR ) + { + if ( CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiCopyAC4C3RTab[depth])) ) + return true; + } + else if( code == CV_BGR2RGBA ) + { + if( CvtColorIPPLoop(src, dst, IPPReorderFunctor(ippiSwapChannelsC3C4RTab[depth], 2, 1, 0)) ) + return true; + } + else if( code == CV_RGBA2BGR ) + { + if( CvtColorIPPLoop(src, dst, IPPReorderFunctor(ippiSwapChannelsC4C3RTab[depth], 2, 1, 0)) ) + return true; + } + else if( code == CV_RGB2BGR ) + { + if( CvtColorIPPLoopCopy(src, dst, IPPReorderFunctor(ippiSwapChannelsC3RTab[depth], 2, 1, 0)) ) + return true; + } +#if IPP_VERSION_X100 >= 801 + else if( code == CV_RGBA2BGRA ) + { + if( CvtColorIPPLoopCopy(src, dst, IPPReorderFunctor(ippiSwapChannelsC4RTab[depth], 2, 1, 0)) ) + return true; + } +#endif + return false; +#endif + +#if 0 // breaks OCL accuracy tests + case CV_BGR2BGR565: case CV_BGR2BGR555: case CV_RGB2BGR565: case CV_RGB2BGR555: + case CV_BGRA2BGR565: case CV_BGRA2BGR555: case CV_RGBA2BGR565: case CV_RGBA2BGR555: + CV_Assert( (scn == 3 || scn == 4) && depth == CV_8U ); + _dst.create(sz, CV_8UC2); + dst = _dst.getMat(); + + CV_SUPPRESS_DEPRECATED_START + + if (code == CV_BGR2BGR565 && scn == 3) + { + if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R))) + return true; + } + else if (code == CV_BGRA2BGR565 && scn == 4) + { + if (CvtColorIPPLoopCopy(src, dst, + IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + (ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 0, 1, 2, depth))) + return true; + } + else if (code == CV_RGB2BGR565 && scn == 3) + { + if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], + (ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 2, 1, 0, depth)) ) + return true; + } + else if (code == CV_RGBA2BGR565 && scn == 4) + { + if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + (ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 2, 1, 0, depth)) ) + return true; + } + CV_SUPPRESS_DEPRECATED_END + return false; +#endif + + case CV_BGR5652BGR: case CV_BGR5552BGR: case CV_BGR5652RGB: case CV_BGR5552RGB: + case CV_BGR5652BGRA: case CV_BGR5552BGRA: case CV_BGR5652RGBA: case CV_BGR5552RGBA: + if(dcn <= 0) dcn = (code==CV_BGR5652BGRA || code==CV_BGR5552BGRA || code==CV_BGR5652RGBA || code==CV_BGR5552RGBA) ? 4 : 3; + CV_Assert( (dcn == 3 || dcn == 4) && scn == 2 && depth == CV_8U ); + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + CV_SUPPRESS_DEPRECATED_START + if (code == CV_BGR5652BGR && dcn == 3) + { + if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R))) + return true; + } + else if (code == CV_BGR5652RGB && dcn == 3) + { + if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R, + ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth))) + return true; + } + else if (code == CV_BGR5652BGRA && dcn == 4) + { + if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R, + ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth))) + return true; + } + else if (code == CV_BGR5652RGBA && dcn == 4) + { + if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R, + ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth))) + return true; + } + CV_SUPPRESS_DEPRECATED_END + return false; + +#if IPP_VERSION_MAJOR >= 7 + case CV_BGR2GRAY: case CV_BGRA2GRAY: case CV_RGB2GRAY: case CV_RGBA2GRAY: + CV_Assert( scn == 3 || scn == 4 ); + _dst.create(sz, CV_MAKETYPE(depth, 1)); + dst = _dst.getMat(); + + if( code == CV_BGR2GRAY && depth == CV_32F ) + { + if( CvtColorIPPLoop(src, dst, IPPColor2GrayFunctor(ippiColor2GrayC3Tab[depth])) ) + return true; + } + else if( code == CV_RGB2GRAY && depth == CV_32F ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiRGB2GrayC3Tab[depth])) ) + return true; + } + else if( code == CV_BGRA2GRAY && depth == CV_32F ) + { + if( CvtColorIPPLoop(src, dst, IPPColor2GrayFunctor(ippiColor2GrayC4Tab[depth])) ) + return true; + } + else if( code == CV_RGBA2GRAY && depth == CV_32F ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiRGB2GrayC4Tab[depth])) ) + return true; + } + return false; + + case CV_GRAY2BGR: case CV_GRAY2BGRA: + if( dcn <= 0 ) dcn = (code==CV_GRAY2BGRA) ? 4 : 3; + CV_Assert( scn == 1 && (dcn == 3 || dcn == 4)); + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( code == CV_GRAY2BGR ) + { + if( CvtColorIPPLoop(src, dst, IPPGray2BGRFunctor(ippiCopyP3C3RTab[depth])) ) + return true; + } + else if( code == CV_GRAY2BGRA ) + { + if( CvtColorIPPLoop(src, dst, IPPGray2BGRAFunctor(ippiCopyP3C3RTab[depth], ippiSwapChannelsC3C4RTab[depth], depth)) ) + return true; + } + return false; +#endif + +#if 0 + case CV_BGR2YCrCb: case CV_RGB2YCrCb: + case CV_BGR2YUV: case CV_RGB2YUV: + { + CV_Assert( scn == 3 || scn == 4 ); + static const float yuv_f[] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f }; + static const int yuv_i[] = { B2Y, G2Y, R2Y, 8061, 14369 }; + const float* coeffs_f = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_f; + const int* coeffs_i = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_i; + + _dst.create(sz, CV_MAKETYPE(depth, 3)); + dst = _dst.getMat(); + + if (code == CV_RGB2YUV && scn == 3 && depth == CV_8U) + { + if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiRGBToYUV_8u_C3R))) + return true; + } + else if (code == CV_BGR2YUV && scn == 3 && depth == CV_8U) + { + if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], + (ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth))) + return true; + } + else if (code == CV_RGB2YUV && scn == 4 && depth == CV_8U) + { + if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + (ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 0, 1, 2, depth))) + return true; + } + else if (code == CV_BGR2YUV && scn == 4 && depth == CV_8U) + { + if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + (ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth))) + return true; + } + return false; + } +#endif + +#if 0 + case CV_YCrCb2BGR: case CV_YCrCb2RGB: + case CV_YUV2BGR: case CV_YUV2RGB: + { + if( dcn <= 0 ) dcn = 3; + CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) ); + static const float yuv_f[] = { 2.032f, -0.395f, -0.581f, 1.140f }; + static const int yuv_i[] = { 33292, -6472, -9519, 18678 }; + const float* coeffs_f = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_f; + const int* coeffs_i = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_i; + + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if (code == CV_YUV2RGB && dcn == 3 && depth == CV_8U) + { + if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R))) + return true; + } + else if (code == CV_YUV2BGR && dcn == 3 && depth == CV_8U) + { + if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R, + ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth))) + return true; + } + else if (code == CV_YUV2RGB && dcn == 4 && depth == CV_8U) + { + if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R, + ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth))) + return true; + } + else if (code == CV_YUV2BGR && dcn == 4 && depth == CV_8U) + { + if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R, + ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth))) + return true; + } + return false; + } +#endif + +#if IPP_VERSION_MAJOR >= 7 + case CV_BGR2XYZ: case CV_RGB2XYZ: + CV_Assert( scn == 3 || scn == 4 ); + _dst.create(sz, CV_MAKETYPE(depth, 3)); + dst = _dst.getMat(); + + if( code == CV_BGR2XYZ && scn == 3 && depth != CV_32F ) + { + if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2XYZTab[depth], 2, 1, 0, depth)) ) + return true; + } + else if( code == CV_BGR2XYZ && scn == 4 && depth != CV_32F ) + { + if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2XYZTab[depth], 2, 1, 0, depth)) ) + return true; + } + else if( code == CV_RGB2XYZ && scn == 3 && depth != CV_32F ) + { + if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiRGB2XYZTab[depth])) ) + return true; + } + else if( code == CV_RGB2XYZ && scn == 4 && depth != CV_32F ) { - if( code == CV_BGR2BGRA) + if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2XYZTab[depth], 0, 1, 2, depth)) ) + return true; + } + return false; +#endif + +#if IPP_VERSION_MAJOR >= 7 + case CV_XYZ2BGR: case CV_XYZ2RGB: + if( dcn <= 0 ) dcn = 3; + CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) ); + + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( code == CV_XYZ2BGR && dcn == 3 && depth != CV_32F ) + { + if( CvtColorIPPLoopCopy(src, dst, IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) + return true; + } + else if( code == CV_XYZ2BGR && dcn == 4 && depth != CV_32F ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) + return true; + } + if( code == CV_XYZ2RGB && dcn == 3 && depth != CV_32F ) + { + if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiXYZ2RGBTab[depth])) ) + return true; + } + else if( code == CV_XYZ2RGB && dcn == 4 && depth != CV_32F ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) + return true; + } + return false; +#endif + +#if IPP_VERSION_MAJOR >= 7 + case CV_BGR2HSV: case CV_RGB2HSV: case CV_BGR2HSV_FULL: case CV_RGB2HSV_FULL: + case CV_BGR2HLS: case CV_RGB2HLS: case CV_BGR2HLS_FULL: case CV_RGB2HLS_FULL: + { + CV_Assert( (scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F) ); + _dst.create(sz, CV_MAKETYPE(depth, 3)); + dst = _dst.getMat(); + + if( depth == CV_8U || depth == CV_16U ) + { +#if 0 // breaks OCL accuracy tests + if( code == CV_BGR2HSV_FULL && scn == 3 ) { - if ( CvtColorIPPLoop(src, dst, IPPReorderFunctor(ippiSwapChannelsC3C4RTab[depth], 0, 1, 2)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); + if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) ) + return true; } - else if( code == CV_BGRA2BGR ) + else if( code == CV_BGR2HSV_FULL && scn == 4 ) { - if ( CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiCopyAC4C3RTab[depth])) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); + if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) ) + return true; } - else if( code == CV_BGR2RGBA ) + else if( code == CV_RGB2HSV_FULL && scn == 4 ) { - if( CvtColorIPPLoop(src, dst, IPPReorderFunctor(ippiSwapChannelsC3C4RTab[depth], 2, 1, 0)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); + if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 0, 1, 2, depth)) ) + return true; + } else +#endif + if( code == CV_RGB2HSV_FULL && scn == 3 && depth == CV_16U ) + { + if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiRGB2HSVTab[depth])) ) + return true; } - else if( code == CV_RGBA2BGR ) + else if( code == CV_BGR2HLS_FULL && scn == 3 ) { - if( CvtColorIPPLoop(src, dst, IPPReorderFunctor(ippiSwapChannelsC4C3RTab[depth], 2, 1, 0)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); + if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) ) + return true; } - else if( code == CV_RGB2BGR ) + else if( code == CV_BGR2HLS_FULL && scn == 4 ) { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderFunctor(ippiSwapChannelsC3RTab[depth], 2, 1, 0)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); + if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) ) + return true; } -#if IPP_VERSION_X100 >= 801 - else if( code == CV_RGBA2BGRA ) + else if( code == CV_RGB2HLS_FULL && scn == 3 ) + { + if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiRGB2HLSTab[depth])) ) + return true; + } + else if( code == CV_RGB2HLS_FULL && scn == 4 ) { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderFunctor(ippiSwapChannelsC4RTab[depth], 2, 1, 0)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); + if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 0, 1, 2, depth)) ) + return true; } + } + return false; + } #endif + +#if IPP_VERSION_MAJOR >= 7 + case CV_HSV2BGR: case CV_HSV2RGB: case CV_HSV2BGR_FULL: case CV_HSV2RGB_FULL: + case CV_HLS2BGR: case CV_HLS2RGB: case CV_HLS2BGR_FULL: case CV_HLS2RGB_FULL: + { + if( dcn <= 0 ) dcn = 3; + CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F) ); + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( depth == CV_8U || depth == CV_16U ) + { + if( code == CV_HSV2BGR_FULL && dcn == 3 ) + { + if( CvtColorIPPLoopCopy(src, dst, IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) + return true; + } + else if( code == CV_HSV2BGR_FULL && dcn == 4 ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) + return true; + } + else if( code == CV_HSV2RGB_FULL && dcn == 3 ) + { + if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiHSV2RGBTab[depth])) ) + return true; + } + else if( code == CV_HSV2RGB_FULL && dcn == 4 ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) + return true; + } + else if( code == CV_HLS2BGR_FULL && dcn == 3 ) + { + if( CvtColorIPPLoopCopy(src, dst, IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) + return true; + } + else if( code == CV_HLS2BGR_FULL && dcn == 4 ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) + return true; + } + else if( code == CV_HLS2RGB_FULL && dcn == 3 ) + { + if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiHLS2RGBTab[depth])) ) + return true; + } + else if( code == CV_HLS2RGB_FULL && dcn == 4 ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) + return true; + } } + return false; + } #endif +#if 0 + case CV_BGR2Lab: case CV_RGB2Lab: case CV_LBGR2Lab: case CV_LRGB2Lab: + case CV_BGR2Luv: case CV_RGB2Luv: case CV_LBGR2Luv: case CV_LRGB2Luv: + { + CV_Assert( (scn == 3 || scn == 4) && (depth == CV_8U || depth == CV_32F) ); + bool srgb = code == CV_BGR2Lab || code == CV_RGB2Lab || + code == CV_BGR2Luv || code == CV_RGB2Luv; + + _dst.create(sz, CV_MAKETYPE(depth, 3)); + dst = _dst.getMat(); + + if (code == CV_LBGR2Lab && scn == 3 && depth == CV_8U) + { + if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiBGRToLab_8u_C3R))) + return true; + } + else if (code == CV_LBGR2Lab && scn == 4 && depth == CV_8U) + { + if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + (ippiGeneralFunc)ippiBGRToLab_8u_C3R, 0, 1, 2, depth))) + return true; + } + else + if (code == CV_LRGB2Lab && scn == 3 && depth == CV_8U) // slower than OpenCV + { + if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], + (ippiGeneralFunc)ippiBGRToLab_8u_C3R, 2, 1, 0, depth))) + return true; + } + else if (code == CV_LRGB2Lab && scn == 4 && depth == CV_8U) // slower than OpenCV + { + if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + (ippiGeneralFunc)ippiBGRToLab_8u_C3R, 2, 1, 0, depth))) + return true; + } + else if (code == CV_LRGB2Luv && scn == 3) + { + if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiRGBToLUVTab[depth]))) + return true; + } + else if (code == CV_LRGB2Luv && scn == 4) + { + if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + ippiRGBToLUVTab[depth], 0, 1, 2, depth))) + return true; + } + else if (code == CV_LBGR2Luv && scn == 3) + { + if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], + ippiRGBToLUVTab[depth], 2, 1, 0, depth))) + return true; + } + else if (code == CV_LBGR2Luv && scn == 4) + { + if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], + ippiRGBToLUVTab[depth], 2, 1, 0, depth))) + return true; + } + return false; + } +#endif + +#if 0 + case CV_Lab2BGR: case CV_Lab2RGB: case CV_Lab2LBGR: case CV_Lab2LRGB: + case CV_Luv2BGR: case CV_Luv2RGB: case CV_Luv2LBGR: case CV_Luv2LRGB: + { + if( dcn <= 0 ) dcn = 3; + CV_Assert( scn == 3 && (dcn == 3 || dcn == 4) && (depth == CV_8U || depth == CV_32F) ); + bool srgb = code == CV_Lab2BGR || code == CV_Lab2RGB || + code == CV_Luv2BGR || code == CV_Luv2RGB; + + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( code == CV_Lab2LBGR && dcn == 3 && depth == CV_8U) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R)) ) + return true; + } + else if( code == CV_Lab2LBGR && dcn == 4 && depth == CV_8U ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R, + ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) + return true; + } + if( code == CV_Lab2LRGB && dcn == 3 && depth == CV_8U ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R, + ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) + return true; + } + else if( code == CV_Lab2LRGB && dcn == 4 && depth == CV_8U ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R, + ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) + return true; + } + if( code == CV_Luv2LRGB && dcn == 3 ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiLUVToRGBTab[depth])) ) + return true; + } + else if( code == CV_Luv2LRGB && dcn == 4 ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth], + ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) + return true; + } + if( code == CV_Luv2LBGR && dcn == 3 ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth], + ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) + return true; + } + else if( code == CV_Luv2LBGR && dcn == 4 ) + { + if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth], + ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) + return true; + } + return false; + } +#endif + + case CV_YUV2GRAY_420: + { + if (dcn <= 0) dcn = 1; + + CV_Assert( dcn == 1 ); + CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0 && depth == CV_8U ); + + Size dstSz(sz.width, sz.height * 2 / 3); + _dst.create(dstSz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if (ippStsNoErr == ippiCopy_8u_C1R(src.data, (int)src.step, dst.data, (int)dst.step, + ippiSize(dstSz.width, dstSz.height))) + return true; + return false; + } + + case CV_RGBA2mRGBA: + { + if (dcn <= 0) dcn = 4; + CV_Assert( scn == 4 && dcn == 4 ); + + _dst.create(sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( depth == CV_8U ) + { + if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiAlphaPremul_8u_AC4R))) + return true; + return false; + } + + return false; + } + + default: + return false; + } +} +} +#endif + +////////////////////////////////////////////////////////////////////////////////////////// +// The main function // +////////////////////////////////////////////////////////////////////////////////////////// + +void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) +{ + int stype = _src.type(); + int scn = CV_MAT_CN(stype), depth = CV_MAT_DEPTH(stype), bidx; + + CV_OCL_RUN( _src.dims() <= 2 && _dst.isUMat() && !(depth == CV_8U && (code == CV_Luv2BGR || code == CV_Luv2RGB)), + ocl_cvtColor(_src, _dst, code, dcn) ) + + Mat src = _src.getMat(), dst; + Size sz = src.size(); + + CV_IPP_RUN(true, ipp_cvtColor(_src, _dst, code, dcn)); + + switch( code ) + { + case CV_BGR2BGRA: case CV_RGB2BGRA: case CV_BGRA2BGR: + case CV_RGBA2BGR: case CV_RGB2BGR: case CV_BGRA2RGBA: + CV_Assert( scn == 3 || scn == 4 ); + dcn = code == CV_BGR2BGRA || code == CV_RGB2BGRA || code == CV_BGRA2RGBA ? 4 : 3; + bidx = code == CV_BGR2BGRA || code == CV_BGRA2BGR ? 0 : 2; + + _dst.create( sz, CV_MAKETYPE(depth, dcn)); + dst = _dst.getMat(); + + if( depth == CV_8U ) { #ifdef HAVE_TEGRA_OPTIMIZATION - if(tegra::useTegra() && tegra::cvtBGR2RGB(src, dst, bidx)) - break; + if(!tegra::cvtBGR2RGB(src, dst, bidx)) #endif - CvtColorLoop(src, dst, RGB2RGB(scn, dcn, bidx)); + CvtColorLoop(src, dst, RGB2RGB(scn, dcn, bidx)); } else if( depth == CV_16U ) CvtColorLoop(src, dst, RGB2RGB(scn, dcn, bidx)); @@ -7435,58 +7967,10 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) _dst.create(sz, CV_8UC2); dst = _dst.getMat(); -#if defined(HAVE_IPP) && 0 // breaks OCL accuracy tests - CV_IPP_CHECK() - { - CV_SUPPRESS_DEPRECATED_START - - if (code == CV_BGR2BGR565 && scn == 3) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_BGRA2BGR565 && scn == 4) - { - if (CvtColorIPPLoopCopy(src, dst, - IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - (ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 0, 1, 2, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_RGB2BGR565 && scn == 3) - { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], - (ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_RGBA2BGR565 && scn == 4) - { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - (ippiGeneralFunc)ippiBGRToBGR565_8u16u_C3R, 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - CV_SUPPRESS_DEPRECATED_END - } -#endif #ifdef HAVE_TEGRA_OPTIMIZATION if(code == CV_BGR2BGR565 || code == CV_BGRA2BGR565 || code == CV_RGB2BGR565 || code == CV_RGBA2BGR565) - if(tegra::useTegra() && tegra::cvtRGB2RGB565(src, dst, code == CV_RGB2BGR565 || code == CV_RGBA2BGR565 ? 0 : 2)) + if(tegra::cvtRGB2RGB565(src, dst, code == CV_RGB2BGR565 || code == CV_RGBA2BGR565 ? 0 : 2)) break; #endif @@ -7505,53 +7989,6 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) _dst.create(sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); -#ifdef HAVE_IPP - CV_IPP_CHECK() - { - CV_SUPPRESS_DEPRECATED_START - if (code == CV_BGR5652BGR && dcn == 3) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_BGR5652RGB && dcn == 3) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R, - ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_BGR5652BGRA && dcn == 4) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R, - ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_BGR5652RGBA && dcn == 4) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiBGR565ToBGR_16u8u_C3R, - ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - CV_SUPPRESS_DEPRECATED_END - } -#endif - CvtColorLoop(src, dst, RGB5x52RGB(dcn, code == CV_BGR5652BGR || code == CV_BGR5552BGR || code == CV_BGR5652BGRA || code == CV_BGR5552BGRA ? 0 : 2, // blue idx @@ -7565,55 +8002,13 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) _dst.create(sz, CV_MAKETYPE(depth, 1)); dst = _dst.getMat(); -#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CV_IPP_CHECK() - { - if( code == CV_BGR2GRAY && depth == CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPColor2GrayFunctor(ippiColor2GrayC3Tab[depth])) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_RGB2GRAY && depth == CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiRGB2GrayC3Tab[depth])) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_BGRA2GRAY && depth == CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPColor2GrayFunctor(ippiColor2GrayC4Tab[depth])) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_RGBA2GRAY && depth == CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiRGB2GrayC4Tab[depth])) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - } -#endif bidx = code == CV_BGR2GRAY || code == CV_BGRA2GRAY ? 0 : 2; if( depth == CV_8U ) { #ifdef HAVE_TEGRA_OPTIMIZATION - if(tegra::useTegra() && tegra::cvtRGB2Gray(src, dst, bidx)) - break; + if(!tegra::cvtRGB2Gray(src, dst, bidx)) #endif CvtColorLoop(src, dst, RGB2Gray(scn, bidx, 0)); } @@ -7637,36 +8032,11 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) _dst.create(sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); -#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CV_IPP_CHECK() - { - if( code == CV_GRAY2BGR ) - { - if( CvtColorIPPLoop(src, dst, IPPGray2BGRFunctor(ippiCopyP3C3RTab[depth])) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_GRAY2BGRA ) - { - if( CvtColorIPPLoop(src, dst, IPPGray2BGRAFunctor(ippiCopyP3C3RTab[depth], ippiSwapChannelsC3C4RTab[depth], depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - } -#endif - if( depth == CV_8U ) { #ifdef HAVE_TEGRA_OPTIMIZATION - if(tegra::useTegra() && tegra::cvtGray2RGB(src, dst)) - break; + if(!tegra::cvtGray2RGB(src, dst)) #endif CvtColorLoop(src, dst, Gray2RGB(dcn)); } @@ -7697,55 +8067,10 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) _dst.create(sz, CV_MAKETYPE(depth, 3)); dst = _dst.getMat(); -#if defined HAVE_IPP && 0 - CV_IPP_CHECK() - { - if (code == CV_RGB2YUV && scn == 3 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiRGBToYUV_8u_C3R))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_BGR2YUV && scn == 3 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], - (ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_RGB2YUV && scn == 4 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - (ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 0, 1, 2, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_BGR2YUV && scn == 4 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - (ippiGeneralFunc)ippiRGBToYUV_8u_C3R, 2, 1, 0, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - } -#endif - if( depth == CV_8U ) { #ifdef HAVE_TEGRA_OPTIMIZATION - if((code == CV_RGB2YCrCb || code == CV_BGR2YCrCb) && tegra::useTegra() && tegra::cvtRGB2YCrCb(src, dst, bidx)) + if((code == CV_RGB2YCrCb || code == CV_BGR2YCrCb) && tegra::cvtRGB2YCrCb(src, dst, bidx)) break; #endif CvtColorLoop(src, dst, RGB2YCrCb_i(scn, bidx, coeffs_i)); @@ -7771,50 +8096,6 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) _dst.create(sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); -#if defined HAVE_IPP && 0 - CV_IPP_CHECK() - { - if (code == CV_YUV2RGB && dcn == 3 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_YUV2BGR && dcn == 3 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R, - ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_YUV2RGB && dcn == 4 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R, - ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_YUV2BGR && dcn == 4 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiYUVToRGB_8u_C3R, - ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - } -#endif if( depth == CV_8U ) CvtColorLoop(src, dst, YCrCb2RGB_i(dcn, bidx, coeffs_i)); @@ -7832,48 +8113,6 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) _dst.create(sz, CV_MAKETYPE(depth, 3)); dst = _dst.getMat(); -#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CV_IPP_CHECK() - { - if( code == CV_BGR2XYZ && scn == 3 && depth != CV_32F ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2XYZTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_BGR2XYZ && scn == 4 && depth != CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2XYZTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_RGB2XYZ && scn == 3 && depth != CV_32F ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiRGB2XYZTab[depth])) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_RGB2XYZ && scn == 4 && depth != CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2XYZTab[depth], 0, 1, 2, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - } -#endif - if( depth == CV_8U ) CvtColorLoop(src, dst, RGB2XYZ_i(scn, bidx, 0)); else if( depth == CV_16U ) @@ -7890,48 +8129,6 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) _dst.create(sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); -#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CV_IPP_CHECK() - { - if( code == CV_XYZ2BGR && dcn == 3 && depth != CV_32F ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_XYZ2BGR && dcn == 4 && depth != CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - if( code == CV_XYZ2RGB && dcn == 3 && depth != CV_32F ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiXYZ2RGBTab[depth])) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_XYZ2RGB && dcn == 4 && depth != CV_32F ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiXYZ2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - } -#endif - if( depth == CV_8U ) CvtColorLoop(src, dst, XYZ2RGB_i(dcn, bidx, 0)); else if( depth == CV_16U ) @@ -7952,94 +8149,12 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) _dst.create(sz, CV_MAKETYPE(depth, 3)); dst = _dst.getMat(); -#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CV_IPP_CHECK() - { - if( depth == CV_8U || depth == CV_16U ) - { -#if 0 // breaks OCL accuracy tests - if( code == CV_BGR2HSV_FULL && scn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_BGR2HSV_FULL && scn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_RGB2HSV_FULL && scn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 0, 1, 2, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } else -#endif - if( code == CV_RGB2HSV_FULL && scn == 3 && depth == CV_16U ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiRGB2HSVTab[depth])) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_BGR2HLS_FULL && scn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_BGR2HLS_FULL && scn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_RGB2HLS_FULL && scn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiRGB2HLSTab[depth])) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_RGB2HLS_FULL && scn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 0, 1, 2, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - } - } -#endif if( code == CV_BGR2HSV || code == CV_RGB2HSV || code == CV_BGR2HSV_FULL || code == CV_RGB2HSV_FULL ) { #ifdef HAVE_TEGRA_OPTIMIZATION - if(tegra::useTegra() && tegra::cvtRGB2HSV(src, dst, bidx, hrange)) + if(tegra::cvtRGB2HSV(src, dst, bidx, hrange)) break; #endif if( depth == CV_8U ) @@ -8070,86 +8185,6 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) _dst.create(sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); -#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) - CV_IPP_CHECK() - { - if( depth == CV_8U || depth == CV_16U ) - { - if( code == CV_HSV2BGR_FULL && dcn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_HSV2BGR_FULL && dcn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_HSV2RGB_FULL && dcn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiHSV2RGBTab[depth])) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_HSV2RGB_FULL && dcn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiHSV2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_HLS2BGR_FULL && dcn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_HLS2BGR_FULL && dcn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_HLS2RGB_FULL && dcn == 3 ) - { - if( CvtColorIPPLoopCopy(src, dst, IPPGeneralFunctor(ippiHLS2RGBTab[depth])) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_HLS2RGB_FULL && dcn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiHLS2RGBTab[depth], ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - } - } -#endif if( code == CV_HSV2BGR || code == CV_HSV2RGB || code == CV_HSV2BGR_FULL || code == CV_HSV2RGB_FULL ) @@ -8181,90 +8216,6 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) _dst.create(sz, CV_MAKETYPE(depth, 3)); dst = _dst.getMat(); -#if defined HAVE_IPP && 0 - CV_IPP_CHECK() - { - if (code == CV_LBGR2Lab && scn == 3 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiBGRToLab_8u_C3R))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_LBGR2Lab && scn == 4 && depth == CV_8U) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - (ippiGeneralFunc)ippiBGRToLab_8u_C3R, 0, 1, 2, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else - if (code == CV_LRGB2Lab && scn == 3 && depth == CV_8U) // slower than OpenCV - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], - (ippiGeneralFunc)ippiBGRToLab_8u_C3R, 2, 1, 0, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_LRGB2Lab && scn == 4 && depth == CV_8U) // slower than OpenCV - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - (ippiGeneralFunc)ippiBGRToLab_8u_C3R, 2, 1, 0, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_LRGB2Luv && scn == 3) - { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiRGBToLUVTab[depth]))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_LRGB2Luv && scn == 4) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - ippiRGBToLUVTab[depth], 0, 1, 2, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_LBGR2Luv && scn == 3) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC3RTab[depth], - ippiRGBToLUVTab[depth], 2, 1, 0, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if (code == CV_LBGR2Luv && scn == 4) - { - if (CvtColorIPPLoop(src, dst, IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], - ippiRGBToLUVTab[depth], 2, 1, 0, depth))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - } -#endif if( code == CV_BGR2Lab || code == CV_RGB2Lab || code == CV_LBGR2Lab || code == CV_LRGB2Lab ) @@ -8297,82 +8248,6 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) _dst.create(sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); -#if defined HAVE_IPP && 0 - CV_IPP_CHECK() - { - if( code == CV_Lab2LBGR && dcn == 3 && depth == CV_8U) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_Lab2LBGR && dcn == 4 && depth == CV_8U ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R, - ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - if( code == CV_Lab2LRGB && dcn == 3 && depth == CV_8U ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R, - ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - else if( code == CV_Lab2LRGB && dcn == 4 && depth == CV_8U ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor((ippiGeneralFunc)ippiLabToBGR_8u_C3R, - ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } - if( code == CV_Luv2LRGB && dcn == 3 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralFunctor(ippiLUVToRGBTab[depth])) ) - return; - } - else if( code == CV_Luv2LRGB && dcn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth], - ippiSwapChannelsC3C4RTab[depth], 0, 1, 2, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - } - if( code == CV_Luv2LBGR && dcn == 3 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth], - ippiSwapChannelsC3RTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - } - else if( code == CV_Luv2LBGR && dcn == 4 ) - { - if( CvtColorIPPLoop(src, dst, IPPGeneralReorderFunctor(ippiLUVToRGBTab[depth], - ippiSwapChannelsC3C4RTab[depth], 2, 1, 0, depth)) ) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - } - } -#endif if( code == CV_Lab2BGR || code == CV_Lab2RGB || code == CV_Lab2LBGR || code == CV_Lab2LRGB ) @@ -8481,18 +8356,6 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) Size dstSz(sz.width, sz.height * 2 / 3); _dst.create(dstSz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); -#if defined HAVE_IPP - CV_IPP_CHECK() - { - if (ippStsNoErr == ippiCopy_8u_C1R(src.data, (int)src.step, dst.data, (int)dst.step, - ippiSize(dstSz.width, dstSz.height))) - { - CV_IMPL_ADD(CV_IMPL_IPP); - return; - } - setIppErrorStatus(); - } -#endif src(Range(0, dstSz.height), Range::all()).copyTo(dst); } break; @@ -8582,17 +8445,6 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn ) if( depth == CV_8U ) { -#if defined(HAVE_IPP) - CV_IPP_CHECK() - { - if (CvtColorIPPLoop(src, dst, IPPGeneralFunctor((ippiGeneralFunc)ippiAlphaPremul_8u_AC4R))) - { - CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT); - return; - } - setIppErrorStatus(); - } -#endif CvtColorLoop(src, dst, RGBA2mRGBA()); } else diff --git a/modules/imgproc/src/corner.cpp b/modules/imgproc/src/corner.cpp index 38f9676..d9b3d94 100644 --- a/modules/imgproc/src/corner.cpp +++ b/modules/imgproc/src/corner.cpp @@ -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 ); } diff --git a/modules/imgproc/src/deriv.cpp b/modules/imgproc/src/deriv.cpp index d1e3a0b..482f4d3 100644 --- a/modules/imgproc/src/deriv.cpp +++ b/modules/imgproc/src/deriv.cpp @@ -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(scale), idelta = saturate_cast(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(scale), idelta = saturate_cast(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(), (int)dst.step, roisize, 0); - if (needDelta && status >= 0) - status = ippiAddC_16s_C1IRSfs((Ipp16s)idelta, dst.ptr(), (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(), (int)dst.step, roisize); - if (needDelta && status >= 0) - status = ippiAddC_32f_C1IR((Ipp32f)delta, dst.ptr(), (int)dst.step, roisize); - } - CV_SUPPRESS_DEPRECATED_END + if (needScale && status >= 0) + status = ippiMulC_16s_C1IRSfs((Ipp16s)iscale, dst.ptr(), (int)dst.step, roisize, 0); + if (needDelta && status >= 0) + status = ippiAddC_16s_C1IRSfs((Ipp16s)idelta, dst.ptr(), (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(), (int)dst.step, roisize); + if (needDelta && status >= 0) + status = ippiAddC_32f_C1IR((Ipp32f)delta, dst.ptr(), (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) { diff --git a/modules/imgproc/src/filter.cpp b/modules/imgproc/src/filter.cpp index f0b7ee7..10c8240 100644 --- a/modules/imgproc/src/filter.cpp +++ b/modules/imgproc/src/filter.cpp @@ -4555,6 +4555,96 @@ cv::Ptr 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) ) diff --git a/modules/imgproc/src/histogram.cpp b/modules/imgproc/src/histogram.cpp index ec8de4d..d9c5edf 100644 --- a/modules/imgproc/src/histogram.cpp +++ b/modules/imgproc/src/histogram.cpp @@ -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 diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index 760f3fb..a780438 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -3092,10 +3092,34 @@ 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, double inv_scale_x, double inv_scale_y, int interpolation ) { @@ -3219,6 +3243,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(scale_x); + int iscale_y = saturate_cast(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 +3266,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(scale_x); - int iscale_y = saturate_cast(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 +3290,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 @@ -3474,6 +3482,7 @@ void cv::resize( InputArray _src, OutputArray _dst, Size dsize, } + /****************************************************************************************\ * General warping (affine, perspective, remap) * \****************************************************************************************/ diff --git a/modules/imgproc/src/morph.cpp b/modules/imgproc/src/morph.cpp index f2d971b..f40ce1c 100644 --- a/modules/imgproc/src/morph.cpp +++ b/modules/imgproc/src/morph.cpp @@ -1711,16 +1711,9 @@ 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, IPPMorphOp(op, _src, _dst, kernel, anchor, iterations, borderType, borderValue)) + Mat src = _src.getMat(); _dst.create( src.size(), src.type() ); diff --git a/modules/imgproc/src/pyramids.cpp b/modules/imgproc/src/pyramids.cpp index 4018e08..1d8c943 100644 --- a/modules/imgproc/src/pyramids.cpp +++ b/modules/imgproc/src/pyramids.cpp @@ -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_, 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 ); } diff --git a/modules/imgproc/src/smooth.cpp b/modules/imgproc/src/smooth.cpp index dbe8a63..012b904 100644 --- a/modules/imgproc/src/smooth.cpp +++ b/modules/imgproc/src/smooth.cpp @@ -1303,17 +1303,24 @@ cv::Ptr 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 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::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(), (int)src.step, \ + dst.ptr(), (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(), (int)src.step, \ + dst.ptr(), (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(), (int)src.step, \ - dst.ptr(), (int)dst.step, roiSize, borderValues[0], pSpec, pBuffer) : \ - ippiFilterGaussianBorder_##ippfavor##_C3R(src.ptr(), (int)src.step, \ - dst.ptr(), (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(), (int)src.step, \ + dst.ptr(), (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(), (int)src.step, \ - dst.ptr(), (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)) diff --git a/modules/imgproc/src/sumpixels.cpp b/modules/imgproc/src/sumpixels.cpp index 16c7c7e..0330068 100755 --- a/modules/imgproc/src/sumpixels.cpp +++ b/modules/imgproc/src/sumpixels.cpp @@ -423,6 +423,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 ) { @@ -455,44 +518,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() ) { diff --git a/modules/imgproc/src/templmatch.cpp b/modules/imgproc/src/templmatch.cpp index c3d583b..e5f4986 100644 --- a/modules/imgproc/src/templmatch.cpp +++ b/modules/imgproc/src/templmatch.cpp @@ -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 ) { diff --git a/modules/imgproc/src/thresh.cpp b/modules/imgproc/src/thresh.cpp index 490bdff..1fafeeef 100644 --- a/modules/imgproc/src/thresh.cpp +++ b/modules/imgproc/src/thresh.cpp @@ -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) +{ + int ippStatus = -1; +#if IPP_VERSION_X100 >= 801 && !defined(HAVE_IPP_ICV_ONLY) + IppiSize srcSize = { size.width, size.height }; + CV_SUPPRESS_DEPRECATED_START + ippStatus = ippiComputeThreshold_Otsu_8u_C1R(_src, step, srcSize, &thresh); + CV_SUPPRESS_DEPRECATED_END +#else + CV_UNUSED(_src); CV_UNUSED(step); CV_UNUSED(size); CV_UNUSED(thresh); +#endif + if(ippStatus >= 0) + return true; + return false; +} +#endif + static double getThreshVal_Otsu_8u( const Mat& _src ) @@ -917,22 +935,11 @@ 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; #endif + CV_IPP_RUN(true, ipp_getThreshVal_Otsu_8u(_src.ptr(), step, size, thresh), thresh); + const int N = 256; int i, j, h[N] = {0}; -- 2.7.4