Extracted HAL interfaces for DFT/DCT, added new test
This commit is contained in:
parent
5877debb6f
commit
008abd28fd
@ -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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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 )
|
||||
|
Loading…
x
Reference in New Issue
Block a user