IPP: CV::dft
authorElena Gvozdeva <elena.gvozdeva@itseez.com>
Wed, 23 Apr 2014 07:32:12 +0000 (11:32 +0400)
committerElena Gvozdeva <elena.gvozdeva@itseez.com>
Wed, 23 Apr 2014 11:52:05 +0000 (15:52 +0400)
modules/core/perf/perf_dft.cpp
modules/core/src/dxt.cpp

index a33bcf5..a2d3d50 100644 (file)
@@ -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> Size_MatType_FlagsType_t;
+typedef perf::TestBaseWithParam<Size_MatType_FlagsType_t> 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
index c5a44e7..294a828 100644 (file)
@@ -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;