From 2d71c094b32ee948fa1f54658e7645ca7d2b07a7 Mon Sep 17 00:00:00 2001 From: Elena Gvozdeva Date: Wed, 23 Apr 2014 11:32:12 +0400 Subject: [PATCH] IPP: CV::dft --- modules/core/perf/perf_dft.cpp | 17 ++++-- modules/core/src/dxt.cpp | 122 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 6 deletions(-) diff --git a/modules/core/perf/perf_dft.cpp b/modules/core/perf/perf_dft.cpp index a33bcf5..a2d3d50 100644 --- a/modules/core/perf/perf_dft.cpp +++ b/modules/core/perf/perf_dft.cpp @@ -6,21 +6,26 @@ using namespace perf; using std::tr1::make_tuple; using std::tr1::get; -#define MAT_TYPES_DFT CV_32FC1, CV_64FC1 -#define MAT_SIZES_DFT sz1080p, sz2K -#define TEST_MATS_DFT testing::Combine(testing::Values(MAT_SIZES_DFT), testing::Values(MAT_TYPES_DFT)) +#define MAT_TYPES_DFT CV_32FC1, CV_32FC2, CV_64FC1 +#define MAT_SIZES_DFT cv::Size(320, 480), cv::Size(800, 600), cv::Size(1280, 1024), sz1080p, sz2K +CV_ENUM(FlagsType, 0, DFT_INVERSE, DFT_SCALE, DFT_COMPLEX_OUTPUT, DFT_ROWS, DFT_INVERSE|DFT_COMPLEX_OUTPUT) +#define TEST_MATS_DFT testing::Combine(testing::Values(MAT_SIZES_DFT), testing::Values(MAT_TYPES_DFT), FlagsType::all()) -PERF_TEST_P(Size_MatType, dft, TEST_MATS_DFT) +typedef std::tr1::tuple Size_MatType_FlagsType_t; +typedef perf::TestBaseWithParam Size_MatType_FlagsType; + +PERF_TEST_P(Size_MatType_FlagsType, dft, TEST_MATS_DFT) { Size sz = get<0>(GetParam()); int type = get<1>(GetParam()); + int flags = get<2>(GetParam()); Mat src(sz, type); Mat dst(sz, type); declare.in(src, WARMUP_RNG).time(60); - TEST_CYCLE() dft(src, dst); + TEST_CYCLE() dft(src, dst, flags); SANITY_CHECK(dst, 1e-5, ERROR_RELATIVE); -} +} \ No newline at end of file diff --git a/modules/core/src/dxt.cpp b/modules/core/src/dxt.cpp index c5a44e7..294a828 100644 --- a/modules/core/src/dxt.cpp +++ b/modules/core/src/dxt.cpp @@ -1476,6 +1476,111 @@ typedef IppStatus (CV_STDCALL* IppDFTGetSizeFunc)(int, int, IppHintAlgorithm, in typedef IppStatus (CV_STDCALL* IppDFTInitFunc)(int, int, IppHintAlgorithm, void*, uchar*); #endif +namespace cv +{ +#if defined USE_IPP_DFT && !defined HAVE_IPP_ICV_ONLY + +static bool ippi_DFT_C_32F(const Mat& src, Mat& dst, bool inv, int norm_flag) +{ + IppStatus status; + Ipp8u* pBuffer = 0; + Ipp8u* pMemInit= 0; + int sizeBuffer=0; + int sizeSpec=0; + int sizeInit=0; + + IppiSize srcRoiSize = {src.cols, src.rows}; + + status = ippiDFTGetSize_C_32fc(srcRoiSize, norm_flag, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuffer ); + if ( status < 0 ) + return false; + + IppiDFTSpec_C_32fc* pDFTSpec = (IppiDFTSpec_C_32fc*)ippMalloc( sizeSpec ); + + if ( sizeInit > 0 ) + pMemInit = (Ipp8u*)ippMalloc( sizeInit ); + + if ( sizeBuffer > 0 ) + pBuffer = (Ipp8u*)ippMalloc( sizeBuffer ); + + status = ippiDFTInit_C_32fc( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit ); + + if ( sizeInit > 0 ) + ippFree( pMemInit ); + + if ( status < 0 ) + { + ippFree( pDFTSpec ); + if ( sizeBuffer > 0 ) + ippFree( pBuffer ); + return false; + } + + if (!inv) + status = ippiDFTFwd_CToC_32fc_C1R( (Ipp32fc*)src.data, (int)src.step, (Ipp32fc*)dst.data, (int)dst.step, pDFTSpec, pBuffer ); + else + status = ippiDFTInv_CToC_32fc_C1R( (Ipp32fc*)src.data, (int)src.step, (Ipp32fc*)dst.data, (int)dst.step, pDFTSpec, pBuffer ); + + if ( sizeBuffer > 0 ) + ippFree( pBuffer ); + + ippFree( pDFTSpec ); + + return status >= 0; + } + +static bool ippi_DFT_R_32F(const Mat& src, Mat& dst, bool inv, int norm_flag) +{ + IppStatus status; + Ipp8u* pBuffer = 0; + Ipp8u* pMemInit= 0; + int sizeBuffer=0; + int sizeSpec=0; + int sizeInit=0; + + IppiSize srcRoiSize = {src.cols, src.rows}; + + status = ippiDFTGetSize_R_32f(srcRoiSize, norm_flag, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuffer ); + if ( status < 0 ) + return false; + + IppiDFTSpec_R_32f* pDFTSpec = (IppiDFTSpec_R_32f*)ippMalloc( sizeSpec ); + + if ( sizeInit > 0 ) + pMemInit = (Ipp8u*)ippMalloc( sizeInit ); + + if ( sizeBuffer > 0 ) + pBuffer = (Ipp8u*)ippMalloc( sizeBuffer ); + + status = ippiDFTInit_R_32f( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit ); + + if ( sizeInit > 0 ) + ippFree( pMemInit ); + + if ( status < 0 ) + { + ippFree( pDFTSpec ); + if ( sizeBuffer > 0 ) + ippFree( pBuffer ); + return false; + } + + if (!inv) + status = ippiDFTFwd_RToPack_32f_C1R( (float*)src.data, (int)(src.step), (float*)(dst.data), (int)dst.step, pDFTSpec, pBuffer ); + else + status = ippiDFTInv_PackToR_32f_C1R( (float*)src.data, (int)src.step, (float*)dst.data, (int)dst.step, pDFTSpec, pBuffer ); + + if ( sizeBuffer > 0 ) + ippFree( pBuffer ); + + ippFree( pDFTSpec ); + + return status >= 0; + } + +#endif +} + #ifdef HAVE_CLAMDFFT namespace cv { @@ -1769,6 +1874,23 @@ void cv::dft( InputArray _src0, OutputArray _dst, int flags, int nonzero_rows ) Mat dst = _dst.getMat(); +#if defined USE_IPP_DFT && !defined HAVE_IPP_ICV_ONLY + + if ((src.depth() == CV_32F) && (flags & DFT_ROWS) == 0 && (src.total()>(int)(1<<6))) + if (!real_transform) + { + if (ippi_DFT_C_32F(src,dst, inv, ipp_norm_flag)) + return; + setIppErrorStatus(); + } + else if (inv || !(flags & DFT_COMPLEX_OUTPUT)) + { + if (ippi_DFT_R_32F(src,dst, inv, ipp_norm_flag)) + return; + setIppErrorStatus(); + } +#endif + if( !real_transform ) elem_size = complex_elem_size; -- 2.7.4