From 55bbca2d0936f40e6d64f36c1bf890d9f0a4c9ba Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Mon, 28 Apr 2014 13:50:28 +0400 Subject: [PATCH] added more types to cv::GaussianBlur --- modules/core/include/opencv2/core/private.hpp | 11 ++++ modules/imgproc/src/smooth.cpp | 62 ++++++++++++++----- modules/imgproc/test/ocl/test_filters.cpp | 4 +- 3 files changed, 60 insertions(+), 17 deletions(-) diff --git a/modules/core/include/opencv2/core/private.hpp b/modules/core/include/opencv2/core/private.hpp index a9210a18ba..1c4c951128 100644 --- a/modules/core/include/opencv2/core/private.hpp +++ b/modules/core/include/opencv2/core/private.hpp @@ -241,6 +241,17 @@ static inline IppiBorderType ippiGetBorderType(int borderTypeNI) borderTypeNI == cv::BORDER_REFLECT ? ippBorderMirrorR : (IppiBorderType)-1; } +static inline IppDataType ippiGetDataType(int depth) +{ + return depth == CV_8U ? ipp8u : + depth == CV_8S ? ipp8s : + depth == CV_16U ? ipp16u : + depth == CV_16S ? ipp16s : + depth == CV_32S ? ipp32s : + depth == CV_32F ? ipp32f : + depth == CV_64F ? ipp64f : (IppDataType)-1; +} + #else # define IPP_VERSION_X100 0 #endif diff --git a/modules/imgproc/src/smooth.cpp b/modules/imgproc/src/smooth.cpp index 50d1250322..e0320fac3a 100644 --- a/modules/imgproc/src/smooth.cpp +++ b/modules/imgproc/src/smooth.cpp @@ -1175,27 +1175,59 @@ void cv::GaussianBlur( InputArray _src, OutputArray _dst, Size ksize, #endif #if IPP_VERSION_X100 >= 801 - if( type == CV_32FC1 && sigma1 == sigma2 && ksize.width == ksize.height && sigma1 != 0.0 ) + 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)) + if (ippBorderConst == ippBorder || ippBorderRepl == ippBorder) { Mat src = _src.getMat(), dst = _dst.getMat(); - IppiSize roi = { src.cols, src.rows }; - int specSize = 0, bufferSize = 0; - if (0 <= ippiFilterGaussianGetBufferSize(roi, (Ipp32u)ksize.width, ipp32f, 1, &specSize, &bufferSize)) + 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 (0 <= ippiFilterGaussianInit(roi, (Ipp32u)ksize.width, (Ipp32f)sigma1, ippBorder, ipp32f, 1, pSpec, pBuffer)) + IppFilterGaussianSpec * pSpec = (IppFilterGaussianSpec *)ippMalloc(specSize); + Ipp8u * pBuffer = (Ipp8u*)ippMalloc(bufferSize); + + if (ippiFilterGaussianInit(roiSize, (Ipp32u)ksize.width, (Ipp32f)sigma1, ippBorder, dataType, 1, pSpec, pBuffer) >= 0) { - IppStatus sts = ippiFilterGaussianBorder_32f_C1R( (const Ipp32f *)src.data, (int)src.step, - (Ipp32f *)dst.data, (int)dst.step, - roi, 0.0, pSpec, pBuffer); - ippFree(pBuffer); - ippFree(pSpec); - if (0 <= sts) - return; +#define IPP_FILTER_GAUSS(ippfavor, ippcn) \ + do \ + { \ + typedef Ipp##ippfavor ippType; \ + ippType borderValues[] = { 0, 0, 0 }; \ + IppStatus status = ippcn == 1 ? \ + ippiFilterGaussianBorder_##ippfavor##_C1R((const ippType *)src.data, (int)src.step, \ + (ippType *)dst.data, (int)dst.step, roiSize, borderValues[0], pSpec, pBuffer) : \ + ippiFilterGaussianBorder_##ippfavor##_C3R((const ippType *)src.data, (int)src.step, \ + (ippType *)dst.data, (int)dst.step, roiSize, borderValues, pSpec, pBuffer); \ + ippFree(pBuffer); \ + ippFree(pSpec); \ + if (status >= 0) \ + 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(); diff --git a/modules/imgproc/test/ocl/test_filters.cpp b/modules/imgproc/test/ocl/test_filters.cpp index d142ce558c..46d77285d7 100644 --- a/modules/imgproc/test/ocl/test_filters.cpp +++ b/modules/imgproc/test/ocl/test_filters.cpp @@ -215,12 +215,12 @@ typedef FilterTestBase GaussianBlurTest; OCL_TEST_P(GaussianBlurTest, Mat) { - for (int j = 0; j < test_loop_times; j++) + for (int j = 0; j < test_loop_times + 1; j++) { random_roi(); double sigma1 = rng.uniform(0.1, 1.0); - double sigma2 = rng.uniform(0.1, 1.0); + double sigma2 = j % 2 == 0 ? sigma1 : rng.uniform(0.1, 1.0); OCL_OFF(cv::GaussianBlur(src_roi, dst_roi, Size(ksize, ksize), sigma1, sigma2, borderType)); OCL_ON(cv::GaussianBlur(usrc_roi, udst_roi, Size(ksize, ksize), sigma1, sigma2, borderType));