From 4dfd40bec04e783e4d2420945636ca3265d5530d Mon Sep 17 00:00:00 2001 From: kdrobnyh Date: Thu, 25 Jul 2013 21:27:35 +0400 Subject: [PATCH 1/2] Add IPP mean and sum functions --- modules/core/perf/perf_stat.cpp | 4 +- modules/core/src/stat.cpp | 124 ++++++++++++++++++++++++++++++ modules/core/test/test_arithm.cpp | 2 +- 3 files changed, 127 insertions(+), 3 deletions(-) diff --git a/modules/core/perf/perf_stat.cpp b/modules/core/perf/perf_stat.cpp index b7fc43d120..9698076ad5 100644 --- a/modules/core/perf/perf_stat.cpp +++ b/modules/core/perf/perf_stat.cpp @@ -33,7 +33,7 @@ PERF_TEST_P(Size_MatType, mean, TYPICAL_MATS) TEST_CYCLE() s = mean(src); - SANITY_CHECK(s, 1e-6); + SANITY_CHECK(s, 1e-5); } PERF_TEST_P(Size_MatType, mean_mask, TYPICAL_MATS) @@ -49,7 +49,7 @@ PERF_TEST_P(Size_MatType, mean_mask, TYPICAL_MATS) TEST_CYCLE() s = mean(src, mask); - SANITY_CHECK(s, 1e-6); + SANITY_CHECK(s, 5e-5); } PERF_TEST_P(Size_MatType, meanStdDev, TYPICAL_MATS) diff --git a/modules/core/src/stat.cpp b/modules/core/src/stat.cpp index e069e52985..832e95eb68 100644 --- a/modules/core/src/stat.cpp +++ b/modules/core/src/stat.cpp @@ -439,6 +439,50 @@ cv::Scalar cv::sum( InputArray _src ) { Mat src = _src.getMat(); int k, cn = src.channels(), depth = src.depth(); + +#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) + size_t total_size = src.total(); + int rows = src.size[0], cols = (int)(total_size/rows); + 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* ippiSumFunc)(const void*, int, IppiSize, double *, int); + ippiSumFunc ippFunc = + type == CV_8UC1 ? (ippiSumFunc)ippiSum_8u_C1R : + type == CV_8UC3 ? (ippiSumFunc)ippiSum_8u_C3R : + type == CV_8UC4 ? (ippiSumFunc)ippiSum_8u_C4R : + type == CV_16UC1 ? (ippiSumFunc)ippiSum_16u_C1R : + type == CV_16UC3 ? (ippiSumFunc)ippiSum_16u_C3R : + type == CV_16UC4 ? (ippiSumFunc)ippiSum_16u_C4R : + type == CV_16SC1 ? (ippiSumFunc)ippiSum_16s_C1R : + type == CV_16SC3 ? (ippiSumFunc)ippiSum_16s_C3R : + type == CV_16SC4 ? (ippiSumFunc)ippiSum_16s_C4R : + type == CV_32FC1 ? (ippiSumFunc)ippiSum_32f_C1R : + type == CV_32FC3 ? (ippiSumFunc)ippiSum_32f_C3R : + type == CV_32FC4 ? (ippiSumFunc)ippiSum_32f_C4R : + 0; + if( ippFunc ) + { + Ipp64f *res = new Ipp64f[cn]; + if( ippFunc(src.data, src.step[0], sz, res, ippAlgHintAccurate) == ippStsNoErr ) + { + Scalar sc; + for( int i = 0; i < cn; i++ ) + { + sc[i] = res[i]; + } + delete []res; + return sc; + } + else + { + delete []res; + } + } + } +#endif + SumFunc func = sumTab[depth]; CV_Assert( cn <= 4 && func != 0 ); @@ -512,6 +556,86 @@ cv::Scalar cv::mean( InputArray _src, InputArray _mask ) CV_Assert( mask.empty() || mask.type() == CV_8U ); int k, cn = src.channels(), depth = src.depth(); + +#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) + size_t total_size = src.total(); + int rows = src.size[0], cols = (int)(total_size/rows); + if( src.dims == 2 || (src.isContinuous() && mask.isContinuous() && cols > 0 && (size_t)rows*cols == total_size) ) + { + IppiSize sz = { cols, rows }; + int type = src.type(); + if( !mask.empty() ) + { + typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC1)(const void *, int, void *, int, IppiSize, Ipp64f *); + ippiMaskMeanFuncC1 ippFuncC1 = + type == CV_8UC1 ? (ippiMaskMeanFuncC1)ippiMean_8u_C1MR : + type == CV_16UC1 ? (ippiMaskMeanFuncC1)ippiMean_16u_C1MR : + type == CV_32FC1 ? (ippiMaskMeanFuncC1)ippiMean_32f_C1MR : + 0; + if( ippFuncC1 ) + { + Ipp64f res; + if( ippFuncC1(src.data, src.step[0], mask.data, mask.step[0], sz, &res) == ippStsNoErr ) + { + return Scalar(res); + } + } + typedef IppStatus (CV_STDCALL* ippiMaskMeanFuncC3)(const void *, int, void *, int, IppiSize, int, Ipp64f *); + ippiMaskMeanFuncC3 ippFuncC3 = + type == CV_8UC3 ? (ippiMaskMeanFuncC3)ippiMean_8u_C3CMR : + type == CV_16UC3 ? (ippiMaskMeanFuncC3)ippiMean_16u_C3CMR : + type == CV_32FC3 ? (ippiMaskMeanFuncC3)ippiMean_32f_C3CMR : + 0; + if( ippFuncC3 ) + { + Ipp64f res1, res2, res3; + if( ippFuncC3(src.data, src.step[0], mask.data, mask.step[0], sz, 1, &res1) == ippStsNoErr && + ippFuncC3(src.data, src.step[0], mask.data, mask.step[0], sz, 2, &res2) == ippStsNoErr && + ippFuncC3(src.data, src.step[0], mask.data, mask.step[0], sz, 3, &res3) == ippStsNoErr ) + { + return Scalar(res1, res2, res3); + } + } + } + else + { + typedef IppStatus (CV_STDCALL* ippiMeanFunc)(const void*, int, IppiSize, double *, int); + ippiMeanFunc ippFunc = + type == CV_8UC1 ? (ippiMeanFunc)ippiMean_8u_C1R : + type == CV_8UC3 ? (ippiMeanFunc)ippiMean_8u_C3R : + type == CV_8UC4 ? (ippiMeanFunc)ippiMean_8u_C4R : + type == CV_16UC1 ? (ippiMeanFunc)ippiMean_16u_C1R : + type == CV_16UC3 ? (ippiMeanFunc)ippiMean_16u_C3R : + type == CV_16UC4 ? (ippiMeanFunc)ippiMean_16u_C4R : + type == CV_16SC1 ? (ippiMeanFunc)ippiMean_16s_C1R : + type == CV_16SC3 ? (ippiMeanFunc)ippiMean_16s_C3R : + type == CV_16SC4 ? (ippiMeanFunc)ippiMean_16s_C4R : + type == CV_32FC1 ? (ippiMeanFunc)ippiMean_32f_C1R : + type == CV_32FC3 ? (ippiMeanFunc)ippiMean_32f_C3R : + type == CV_32FC4 ? (ippiMeanFunc)ippiMean_32f_C4R : + 0; + if( ippFunc ) + { + Ipp64f *res = new Ipp64f[cn]; + if( ippFunc(src.data, src.step[0], sz, res, ippAlgHintAccurate) == ippStsNoErr ) + { + Scalar sc; + for( int i = 0; i < cn; i++ ) + { + sc[i] = res[i]; + } + delete []res; + return sc; + } + else + { + delete []res; + } + } + } + } +#endif + SumFunc func = sumTab[depth]; CV_Assert( cn <= 4 && func != 0 ); diff --git a/modules/core/test/test_arithm.cpp b/modules/core/test/test_arithm.cpp index a3e61f22a3..0bb185d2d2 100644 --- a/modules/core/test/test_arithm.cpp +++ b/modules/core/test/test_arithm.cpp @@ -1123,7 +1123,7 @@ struct MeanOp : public BaseElemWiseOp } double getMaxErr(int) { - return 1e-6; + return 1e-5; } }; From 6af10a29375a0d032950ff98e17bb564b136dfb2 Mon Sep 17 00:00:00 2001 From: kdrobnyh Date: Tue, 30 Jul 2013 00:54:27 +0400 Subject: [PATCH 2/2] Some changes in sum and mean functions --- modules/core/src/stat.cpp | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/modules/core/src/stat.cpp b/modules/core/src/stat.cpp index 832e95eb68..d8f28e204f 100644 --- a/modules/core/src/stat.cpp +++ b/modules/core/src/stat.cpp @@ -464,21 +464,16 @@ cv::Scalar cv::sum( InputArray _src ) 0; if( ippFunc ) { - Ipp64f *res = new Ipp64f[cn]; - if( ippFunc(src.data, src.step[0], sz, res, ippAlgHintAccurate) == ippStsNoErr ) + Ipp64f res[4]; + if( ippFunc(src.data, src.step[0], sz, res, ippAlgHintAccurate) >= 0 ) { Scalar sc; for( int i = 0; i < cn; i++ ) { sc[i] = res[i]; } - delete []res; return sc; } - else - { - delete []res; - } } } #endif @@ -575,7 +570,7 @@ cv::Scalar cv::mean( InputArray _src, InputArray _mask ) if( ippFuncC1 ) { Ipp64f res; - if( ippFuncC1(src.data, src.step[0], mask.data, mask.step[0], sz, &res) == ippStsNoErr ) + if( ippFuncC1(src.data, src.step[0], mask.data, mask.step[0], sz, &res) >= 0 ) { return Scalar(res); } @@ -589,9 +584,9 @@ cv::Scalar cv::mean( InputArray _src, InputArray _mask ) if( ippFuncC3 ) { Ipp64f res1, res2, res3; - if( ippFuncC3(src.data, src.step[0], mask.data, mask.step[0], sz, 1, &res1) == ippStsNoErr && - ippFuncC3(src.data, src.step[0], mask.data, mask.step[0], sz, 2, &res2) == ippStsNoErr && - ippFuncC3(src.data, src.step[0], mask.data, mask.step[0], sz, 3, &res3) == ippStsNoErr ) + if( ippFuncC3(src.data, src.step[0], mask.data, mask.step[0], sz, 1, &res1) >= 0 && + ippFuncC3(src.data, src.step[0], mask.data, mask.step[0], sz, 2, &res2) >= 0 && + ippFuncC3(src.data, src.step[0], mask.data, mask.step[0], sz, 3, &res3) >= 0 ) { return Scalar(res1, res2, res3); } @@ -616,21 +611,16 @@ cv::Scalar cv::mean( InputArray _src, InputArray _mask ) 0; if( ippFunc ) { - Ipp64f *res = new Ipp64f[cn]; - if( ippFunc(src.data, src.step[0], sz, res, ippAlgHintAccurate) == ippStsNoErr ) + Ipp64f res[4]; + if( ippFunc(src.data, src.step[0], sz, res, ippAlgHintAccurate) >= 0 ) { Scalar sc; for( int i = 0; i < cn; i++ ) { sc[i] = res[i]; } - delete []res; return sc; } - else - { - delete []res; - } } } }