From 6880dbfd95a4796eae1b590f2080c4e696f0e3f9 Mon Sep 17 00:00:00 2001 From: Elena Gvozdeva Date: Wed, 16 Apr 2014 14:31:44 +0400 Subject: [PATCH] IPP: cv::dct --- modules/core/perf/perf_dft.cpp | 31 +++++++ modules/core/src/dxt.cpp | 155 ++++++++++++++++++++++++++++----- 2 files changed, 165 insertions(+), 21 deletions(-) diff --git a/modules/core/perf/perf_dft.cpp b/modules/core/perf/perf_dft.cpp index a2d3d503d1..f3e1d24e36 100644 --- a/modules/core/perf/perf_dft.cpp +++ b/modules/core/perf/perf_dft.cpp @@ -6,6 +6,8 @@ using namespace perf; using std::tr1::make_tuple; using std::tr1::get; +///////////////////////////////////////////////////////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) @@ -27,5 +29,34 @@ PERF_TEST_P(Size_MatType_FlagsType, dft, TEST_MATS_DFT) TEST_CYCLE() dft(src, dst, flags); + SANITY_CHECK(dst, 1e-5, ERROR_RELATIVE); + +///////////////////////////////////////////////////////dct////////////////////////////////////////////////////// + +CV_ENUM(FlagsType, 0, DCT_INVERSE , DCT_ROWS, DCT_INVERSE|DCT_ROWS) + +typedef std::tr1::tuple Size_MatType_Flag_t; +typedef perf::TestBaseWithParam Size_MatType_Flag; + +PERF_TEST_P(Size_MatType_Flag, dct, testing::Combine( + testing::Values(cv::Size(320, 240),cv::Size(800, 600), + cv::Size(1024, 768), cv::Size(1280, 1024), + sz1080p, sz2K), + testing::Values(CV_32FC1, CV_64FC1), FlagsType::all())) +{ + 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) + .out(dst) + .time(60); + + TEST_CYCLE() dct(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 0c12e1948a..f7ee8dc8c4 100644 --- a/modules/core/src/dxt.cpp +++ b/modules/core/src/dxt.cpp @@ -2880,6 +2880,132 @@ static void IDCT_64f(const double* src, int src_step, double* dft_src, double* d } +namespace cv +{ +#if defined HAVE_IPP && IPP_VERSION_MAJOR >= 7 + +typedef IppStatus (CV_STDCALL * ippiDCTFwdFunc)(const Ipp32f*, int, Ipp32f*, int, const IppiDCTFwdSpec_32f*, Ipp8u*); +typedef IppStatus (CV_STDCALL * ippiDCTInvFunc)(const Ipp32f*, int, Ipp32f*, int, const IppiDCTInvSpec_32f*, Ipp8u*); + +static bool ippi_DCT_Fwd(const Mat& src, Mat& dst, bool row) +{ + if (src.type() != CV_32F) + return false; + + IppStatus status; + IppiDCTFwdSpec_32f* pDCTSpec; + Ipp8u *pBuffer; + int bufSize=0; + + ippiDCTFwdFunc ippFunc = (ippiDCTFwdFunc)ippiDCTFwd_32f_C1R; + + if (ippFunc==0) + return false; + + IppiSize srcRoiSize = {src.cols, row ? 1 : src.rows}; + + CV_SUPPRESS_DEPRECATED_START + status = ippiDCTFwdInitAlloc_32f (&pDCTSpec, srcRoiSize, ippAlgHintNone); + + if ( status < 0 ) + { + ippiDCTFwdFree_32f(pDCTSpec); + return false; + } + + status = ippiDCTFwdGetBufSize_32f (pDCTSpec, &bufSize); + if ( status < 0 ) + { + ippiDCTFwdFree_32f(pDCTSpec); + return false; + } + + pBuffer = ippsMalloc_8u( bufSize ); + + if (row) + { + for (int i=0; i= 0; +} + +static bool ippi_DCT_Inv(const Mat& src, Mat& dst, bool row) +{ + if (src.type() != CV_32F) + return false; + + IppStatus status; + IppiDCTInvSpec_32f* pDCTSpec; + Ipp8u *pBuffer; + int bufSize=0; + + ippiDCTInvFunc ippFunc = (ippiDCTInvFunc)ippiDCTInv_32f_C1R; + + if (ippFunc==0) + return false; + + IppiSize srcRoiSize = {src.cols, row ? 1 : src.rows}; + + CV_SUPPRESS_DEPRECATED_START + status = ippiDCTInvInitAlloc_32f (&pDCTSpec, srcRoiSize, ippAlgHintNone); + + if ( status < 0 ) + { + ippiDCTInvFree_32f(pDCTSpec); + return false; + } + + status = ippiDCTInvGetBufSize_32f (pDCTSpec, &bufSize); + if ( status < 0 ) + { + ippiDCTInvFree_32f(pDCTSpec); + return false; + } + + pBuffer = ippsMalloc_8u( bufSize ); + + if (row) + { + for (int i=0; i= 0; +} + +#endif +} + void cv::dct( InputArray _src0, OutputArray _dst, int flags ) { static DCTFunc dct_tbl[4] = @@ -2910,6 +3036,14 @@ void cv::dct( InputArray _src0, OutputArray _dst, int flags ) _dst.create( src.rows, src.cols, type ); Mat dst = _dst.getMat(); +#if defined HAVE_IPP && IPP_VERSION_MAJOR >= 7 + bool row = (flags & DCT_ROWS) != 0; + if (inv && ippi_DCT_Inv(src,dst,row)) + return; + if(ippi_DCT_Fwd(src,dst,row)) + return; +#endif + DCTFunc dct_func = dct_tbl[(int)inv + (depth == CV_64F)*2]; if( (flags & DCT_ROWS) || src.rows == 1 || @@ -2962,27 +3096,6 @@ void cv::dct( InputArray _src0, OutputArray _dst, int flags ) spec = 0; inplace_transform = 1; - /*if( len*count >= 64 && DFTInitAlloc_R_32f_p ) - { - int ipp_sz = 0; - if( depth == CV_32F ) - { - if( spec_dft ) - IPPI_CALL( DFTFree_R_32f_p( spec_dft )); - IPPI_CALL( DFTInitAlloc_R_32f_p( &spec_dft, len, 8, cvAlgHintNone )); - IPPI_CALL( DFTGetBufSize_R_32f_p( spec_dft, &ipp_sz )); - } - else - { - if( spec_dft ) - IPPI_CALL( DFTFree_R_64f_p( spec_dft )); - IPPI_CALL( DFTInitAlloc_R_64f_p( &spec_dft, len, 8, cvAlgHintNone )); - IPPI_CALL( DFTGetBufSize_R_64f_p( spec_dft, &ipp_sz )); - } - spec = spec_dft; - sz += ipp_sz; - } - else*/ { sz += len*(complex_elem_size + sizeof(int)) + complex_elem_size;