Merge pull request #2654 from ElenaGvozdeva:ipp_DFT

pull/2653/merge
Alexander Alekhin 11 years ago committed by OpenCV Buildbot
commit 0e5b0677c9
  1. 17
      modules/core/perf/perf_dft.cpp
  2. 331
      modules/core/src/dxt.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> 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);
}
}

@ -1476,6 +1476,300 @@ 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
typedef IppStatus (CV_STDCALL* ippiDFT_C_Func)(const Ipp32fc*, int, Ipp32fc*, int, const IppiDFTSpec_C_32fc*, Ipp8u*);
typedef IppStatus (CV_STDCALL* ippiDFT_R_Func)(const Ipp32f* , int, Ipp32f* , int, const IppiDFTSpec_R_32f* , Ipp8u*);
template <typename Dft>
class Dft_C_IPPLoop_Invoker : public ParallelLoopBody
{
public:
Dft_C_IPPLoop_Invoker(const Mat& _src, Mat& _dst, const Dft& _ippidft, int _norm_flag, bool *_ok) :
ParallelLoopBody(), src(_src), dst(_dst), ippidft(_ippidft), norm_flag(_norm_flag), ok(_ok)
{
*ok = true;
}
virtual void operator()(const Range& range) const
{
IppStatus status;
Ipp8u* pBuffer = 0;
Ipp8u* pMemInit= 0;
int sizeBuffer=0;
int sizeSpec=0;
int sizeInit=0;
IppiSize srcRoiSize = {src.cols, 1};
status = ippiDFTGetSize_C_32fc(srcRoiSize, norm_flag, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuffer );
if ( status < 0 )
{
*ok = false;
return;
}
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 );
*ok = false;
return;
}
for( int i = range.start; i < range.end; ++i)
if(!ippidft((Ipp32fc*)(src.data+i*src.step), (int)src.step,(Ipp32fc*)(dst.data+i*dst.step), (int)dst.step, pDFTSpec, (Ipp8u*)pBuffer))
{
*ok = false;
}
if ( sizeBuffer > 0 )
ippFree( pBuffer );
ippFree( pDFTSpec );
}
private:
const Mat& src;
Mat& dst;
const Dft& ippidft;
int norm_flag;
bool *ok;
const Dft_C_IPPLoop_Invoker& operator= (const Dft_C_IPPLoop_Invoker&);
};
template <typename Dft>
class Dft_R_IPPLoop_Invoker : public ParallelLoopBody
{
public:
Dft_R_IPPLoop_Invoker(const Mat& _src, Mat& _dst, const Dft& _ippidft, int _norm_flag, bool *_ok) :
ParallelLoopBody(), src(_src), dst(_dst), ippidft(_ippidft), norm_flag(_norm_flag), ok(_ok)
{
*ok = true;
}
virtual void operator()(const Range& range) const
{
IppStatus status;
Ipp8u* pBuffer = 0;
Ipp8u* pMemInit= 0;
int sizeBuffer=0;
int sizeSpec=0;
int sizeInit=0;
IppiSize srcRoiSize = {src.cols, 1};
status = ippiDFTGetSize_R_32f(srcRoiSize, norm_flag, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuffer );
if ( status < 0 )
{
*ok = false;
return;
}
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 );
*ok = false;
return;
}
for( int i = range.start; i < range.end; ++i)
if(!ippidft(src.ptr<float>(i), (int)src.step,dst.ptr<float>(i), (int)dst.step, pDFTSpec, (Ipp8u*)pBuffer))
{
*ok = false;
}
if ( sizeBuffer > 0 )
ippFree( pBuffer );
ippFree( pDFTSpec );
}
private:
const Mat& src;
Mat& dst;
const Dft& ippidft;
int norm_flag;
bool *ok;
const Dft_R_IPPLoop_Invoker& operator= (const Dft_R_IPPLoop_Invoker&);
};
template <typename Dft>
bool Dft_C_IPPLoop(const Mat& src, Mat& dst, const Dft& ippidft, int norm_flag)
{
bool ok;
parallel_for_(Range(0, src.rows), Dft_C_IPPLoop_Invoker<Dft>(src, dst, ippidft, norm_flag, &ok), src.total()/(double)(1<<16) );
return ok;
}
template <typename Dft>
bool Dft_R_IPPLoop(const Mat& src, Mat& dst, const Dft& ippidft, int norm_flag)
{
bool ok;
parallel_for_(Range(0, src.rows), Dft_R_IPPLoop_Invoker<Dft>(src, dst, ippidft, norm_flag, &ok), src.total()/(double)(1<<16) );
return ok;
}
struct IPPDFT_C_Functor
{
IPPDFT_C_Functor(ippiDFT_C_Func _func) : func(_func){}
bool operator()(const Ipp32fc* src, int srcStep, Ipp32fc* dst, int dstStep, const IppiDFTSpec_C_32fc* pDFTSpec, Ipp8u* pBuffer) const
{
return func ? func(src, srcStep, dst, dstStep, pDFTSpec, pBuffer) >= 0 : false;
}
private:
ippiDFT_C_Func func;
};
struct IPPDFT_R_Functor
{
IPPDFT_R_Functor(ippiDFT_R_Func _func) : func(_func){}
bool operator()(const Ipp32f* src, int srcStep, Ipp32f* dst, int dstStep, const IppiDFTSpec_R_32f* pDFTSpec, Ipp8u* pBuffer) const
{
return func ? func(src, srcStep, dst, dstStep, pDFTSpec, pBuffer) >= 0 : false;
}
private:
ippiDFT_R_Func func;
};
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( src.ptr<float>(), (int)(src.step), dst.ptr<float>(), (int)dst.step, pDFTSpec, pBuffer );
else
status = ippiDFTInv_PackToR_32f_C1R( src.ptr<float>(), (int)src.step, dst.ptr<float>(), (int)dst.step, pDFTSpec, pBuffer );
if ( sizeBuffer > 0 )
ippFree( pBuffer );
ippFree( pDFTSpec );
return status >= 0;
}
#endif
}
#ifdef HAVE_CLAMDFFT
namespace cv {
@ -1769,6 +2063,43 @@ 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) && (src.total()>(int)(1<<6)))
if ((flags & DFT_ROWS) == 0)
{
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();
}
}
else
{
if (!real_transform)
{
ippiDFT_C_Func ippiFunc = inv ? (ippiDFT_C_Func)ippiDFTInv_CToC_32fc_C1R : (ippiDFT_C_Func)ippiDFTFwd_CToC_32fc_C1R;
if (Dft_C_IPPLoop(src,dst, IPPDFT_C_Functor(ippiFunc),ipp_norm_flag))
return;
setIppErrorStatus();
}
else if (inv || !(flags & DFT_COMPLEX_OUTPUT))
{
ippiDFT_R_Func ippiFunc = inv ? (ippiDFT_R_Func)ippiDFTInv_PackToR_32f_C1R : (ippiDFT_R_Func)ippiDFTFwd_RToPack_32f_C1R;
if (Dft_R_IPPLoop(src,dst, IPPDFT_R_Functor(ippiFunc),ipp_norm_flag))
return;
setIppErrorStatus();
}
}
#endif
if( !real_transform )
elem_size = complex_elem_size;

Loading…
Cancel
Save