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 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 );
|
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
|
//! @} 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
|
#ifdef __cplusplus
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#else
|
#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 )
|
# pragma warning( pop )
|
||||||
#endif
|
#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"
|
#include "custom_hal.hpp"
|
||||||
|
|
||||||
#endif
|
#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
|
#endif
|
||||||
|
|
||||||
|
#include "opencv2/core/hal/hal.hpp"
|
||||||
|
|
||||||
void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
|
void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
|
||||||
Size corrsize, int ctype,
|
Size corrsize, int ctype,
|
||||||
Point anchor, double delta, int borderType )
|
Point anchor, double delta, int borderType )
|
||||||
@ -698,6 +700,9 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
|
|||||||
|
|
||||||
buf.resize(bufSize);
|
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
|
// compute DFT of each template plane
|
||||||
for( k = 0; k < tcn; k++ )
|
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));
|
Mat part(dst, Range(0, templ.rows), Range(templ.cols, dst.cols));
|
||||||
part = Scalar::all(0);
|
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 tileCountX = (corr.cols + blocksize.width - 1)/blocksize.width;
|
||||||
int tileCountY = (corr.rows + blocksize.height - 1)/blocksize.height;
|
int tileCountY = (corr.rows + blocksize.height - 1)/blocksize.height;
|
||||||
int tileCount = tileCountX * tileCountY;
|
int tileCount = tileCountX * tileCountY;
|
||||||
@ -740,6 +747,16 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
|
|||||||
}
|
}
|
||||||
borderType |= BORDER_ISOLATED;
|
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
|
// calculate correlation by blocks
|
||||||
for( i = 0; i < tileCount; i++ )
|
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),
|
copyMakeBorder(dst1, dst, y1-y0, dst.rows-dst1.rows-(y1-y0),
|
||||||
x1-x0, dst.cols-dst1.cols-(x1-x0), borderType);
|
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,
|
Mat dftTempl1(dftTempl, Rect(0, tcn > 1 ? k*dftsize.height : 0,
|
||||||
dftsize.width, dftsize.height));
|
dftsize.width, dftsize.height));
|
||||||
mulSpectrums(dftImg, dftTempl1, dftImg, 0, true);
|
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));
|
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 )
|
static void matchTemplateMask( InputArray _img, InputArray _templ, OutputArray _result, int method, InputArray _mask )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user