提交 008abd28 编写于 作者: M Maksim Shabunin

Extracted HAL interfaces for DFT/DCT, added new test

上级 5877debb
......@@ -187,6 +187,25 @@ CV_EXPORTS void addWeighted32s( const int* src1, size_t step1, const int* src2,
CV_EXPORTS void addWeighted32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* scalars );
CV_EXPORTS void addWeighted64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* scalars );
struct DftContext
{
void * impl;
bool useReplacement;
DftContext() : impl(0), useReplacement(false) {}
};
CV_EXPORTS void dftInit2D(DftContext & c, int _width, int _height, int _depth, int _src_channels, int _dst_channels, int flags, int _nonzero_rows = 0);
CV_EXPORTS void dftRun2D(const DftContext & c, const void * src, int src_step, void * dst, int dst_step);
CV_EXPORTS void dftFree2D(DftContext & c);
CV_EXPORTS void dftInit(DftContext & c, int len, int count, int depth, int flags, bool * useBuffer = 0);
CV_EXPORTS void dftRun(const DftContext & c, const void * src, void * dst);
CV_EXPORTS void dftFree(DftContext & c);
CV_EXPORTS void dctInit(DftContext & c, int width, int height, int depth, int flags);
CV_EXPORTS void dctRun(const DftContext & c, const void * src, int src_step, void * dst, int dst_step);
CV_EXPORTS void dctFree(DftContext & c);
//! @} core_hal
//=============================================================================
......
......@@ -12,6 +12,16 @@
//! @}
#define CV_HAL_DFT_INVERSE 1
#define CV_HAL_DFT_SCALE 2
#define CV_HAL_DFT_ROWS 4
#define CV_HAL_DFT_COMPLEX_OUTPUT 16
#define CV_HAL_DFT_REAL_OUTPUT 32
#define CV_HAL_DFT_TWO_STAGE 64
#define CV_HAL_DFT_STAGE_COLS 128
#define CV_HAL_DFT_IS_CONTINUOUS 512
#define CV_HAL_DFT_IS_INPLACE 1024
#ifdef __cplusplus
#include <cstddef>
#else
......
此差异已折叠。
......@@ -384,6 +384,31 @@ inline int hal_ni_merge64s(const int64 **src_data, int64 *dst_data, int len, int
# pragma warning( pop )
#endif
inline int hal_ni_dftInit(void**, int, int, int, int, bool*) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
inline int hal_ni_dftRun(const void*, const void*, void*) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
inline int hal_ni_dftFree(void*) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
#define cv_hal_dftInit hal_ni_dftInit
#define cv_hal_dftRun hal_ni_dftRun
#define cv_hal_dftFree hal_ni_dftFree
inline int hal_ni_dftInit2D(void **, int, int, int, int, int, int, int) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
inline int hal_ni_dftRun2D(const void *, const void *, int, void *, int) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
inline int hal_ni_dftFree2D(void *) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
#define cv_hal_dftInit2D hal_ni_dftInit2D
#define cv_hal_dftRun2D hal_ni_dftRun2D
#define cv_hal_dftFree2D hal_ni_dftFree2D
inline int hal_ni_dctInit(void **, int, int, int, int) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
inline int hal_ni_dctRun(const void *, const void *, int, void *, int) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
inline int hal_ni_dctFree(void *) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
#define cv_hal_dctInit hal_ni_dctInit
#define cv_hal_dctRun hal_ni_dctRun
#define cv_hal_dctFree hal_ni_dctFree
#include "custom_hal.hpp"
#endif
......@@ -887,3 +887,79 @@ TEST(Core_DFT, complex_output2)
}
}
}
class Core_DXTReverseTest : public cvtest::BaseTest
{
public:
enum Mode
{
ModeDFT,
ModeDCT
};
Core_DXTReverseTest(Mode m) : mode(m) {}
private:
Mode mode;
protected:
void run(int)
{
for (int i = 0; i < 3; ++i)
{
if (mode == ModeDCT && i != 0)
continue;
int flags = 0;
int flags_inv = DFT_INVERSE | DFT_SCALE;
int cn_in = 0;
int cn_out = 0;
switch (i)
{
case 0: cn_in = 1; cn_out = 1; break;
case 1: cn_in = 1; cn_out = 2; flags |= DFT_COMPLEX_OUTPUT; flags_inv |= DFT_REAL_OUTPUT; break;
case 2: cn_in = 2; cn_out = 2; break;
};
for (int j = 0; j < 100; ++j)
{
RNG& rng = ts->get_rng();
int type = rng.uniform(0, 2) ? CV_64F : CV_32F;
int m = rng.uniform(1, 10);
int n = rng.uniform(1, 10);
if (mode == ModeDCT)
{
m *= 2;
n *= 2;
}
Mat one(m, n, CV_MAKETYPE(type, cn_in));
cvtest::randUni(rng, one, Scalar::all(-1.), Scalar::all(1.));
Mat out;
Mat two;
if (mode == ModeDFT)
{
cv::dft(one, out, flags);
cv::dft(out, two, flags_inv);
}
else if (mode == ModeDCT)
{
cv::dct(one, out, flags);
cv::dct(out, two, flags_inv);
}
if (out.channels() != cn_out || two.channels() != cn_in || cvtest::norm(one, two, NORM_INF) > 1e-5)
{
cout << "Test #" << j + 1 << " - "
<< "elements: " << m << " x " << n << ", "
<< "channels: "
<< one.channels() << " (" << cn_in << ")" << " -> "
<< out.channels() << " (" << cn_out << ")" << " -> "
<< two.channels() << " (" << cn_in << ")"
<< endl;
cout << "signal:\n" << one << endl << endl;
cout << "spectrum:\n" << out << endl << endl;
cout << "inverse:\n" << two << endl << endl;
ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_OUTPUT);
break;
}
}
}
}
};
TEST(Core_DFT, reverse) { Core_DXTReverseTest test(Core_DXTReverseTest::ModeDFT); test.safe_run(); }
TEST(Core_DCT, reverse) { Core_DXTReverseTest test(Core_DXTReverseTest::ModeDCT); test.safe_run(); }
......@@ -632,6 +632,8 @@ static bool ipp_sqrDistance(const Mat& src, const Mat& tpl, Mat& dst)
#endif
#include "opencv2/core/hal/hal.hpp"
void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
Size corrsize, int ctype,
Point anchor, double delta, int borderType )
......@@ -698,6 +700,9 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
buf.resize(bufSize);
hal::DftContext c;
hal::dftInit2D(c, dftsize.width, dftsize.height, dftTempl.depth(), 1, 1, CV_HAL_DFT_IS_INPLACE, templ.rows);
// compute DFT of each template plane
for( k = 0; k < tcn; k++ )
{
......@@ -721,9 +726,11 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
Mat part(dst, Range(0, templ.rows), Range(templ.cols, dst.cols));
part = Scalar::all(0);
}
dft(dst, dst, 0, templ.rows);
hal::dftRun2D(c, dst.data, (int)dst.step, dst.data, (int)dst.step);
}
hal::dftFree2D(c);
int tileCountX = (corr.cols + blocksize.width - 1)/blocksize.width;
int tileCountY = (corr.rows + blocksize.height - 1)/blocksize.height;
int tileCount = tileCountX * tileCountY;
......@@ -740,6 +747,16 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
}
borderType |= BORDER_ISOLATED;
bool useHalDft = tileCount > 1;
hal::DftContext cF, cR;
if (useHalDft)
{
int f = CV_HAL_DFT_IS_INPLACE;
int f_inv = f | CV_HAL_DFT_INVERSE | CV_HAL_DFT_SCALE;
hal::dftInit2D(cF, dftsize.width, dftsize.height, maxDepth, 1, 1, f, blocksize.height + templ.rows - 1);
hal::dftInit2D(cR, dftsize.width, dftsize.height, maxDepth, 1, 1, f_inv, blocksize.height);
}
// calculate correlation by blocks
for( i = 0; i < tileCount; i++ )
{
......@@ -777,11 +794,19 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
copyMakeBorder(dst1, dst, y1-y0, dst.rows-dst1.rows-(y1-y0),
x1-x0, dst.cols-dst1.cols-(x1-x0), borderType);
dft( dftImg, dftImg, 0, dsz.height );
if (useHalDft && bsz.height == blocksize.height)
hal::dftRun2D(cF, dftImg.data, (int)dftImg.step, dftImg.data, (int)dftImg.step);
else
dft( dftImg, dftImg, 0, dsz.height );
Mat dftTempl1(dftTempl, Rect(0, tcn > 1 ? k*dftsize.height : 0,
dftsize.width, dftsize.height));
mulSpectrums(dftImg, dftTempl1, dftImg, 0, true);
dft( dftImg, dftImg, DFT_INVERSE + DFT_SCALE, bsz.height );
if (useHalDft && bsz.height == blocksize.height)
hal::dftRun2D(cR, dftImg.data, (int)dftImg.step, dftImg.data, (int)dftImg.step);
else
dft( dftImg, dftImg, DFT_INVERSE + DFT_SCALE, bsz.height );
src = dftImg(Rect(0, 0, bsz.width, bsz.height));
......@@ -813,6 +838,11 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
}
}
}
if (useHalDft)
{
hal::dftFree2D(cF);
hal::dftFree2D(cR);
}
}
static void matchTemplateMask( InputArray _img, InputArray _templ, OutputArray _result, int method, InputArray _mask )
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册