Commit 233612ef authored by Maksim Shabunin's avatar Maksim Shabunin

Reworked HAL dft/dct interface, added replacement documentation

parent f40d7014
...@@ -187,24 +187,28 @@ CV_EXPORTS void addWeighted32s( const int* src1, size_t step1, const int* src2, ...@@ -187,24 +187,28 @@ 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 struct CV_EXPORTS DFT1D
{ {
void * impl; static Ptr<DFT1D> create(int len, int count, int depth, int flags, bool * useBuffer = 0);
bool useReplacement; virtual void apply(const uchar *src, uchar *dst) = 0;
DftContext() : impl(0), useReplacement(false) {} virtual ~DFT1D() {}
}; };
CV_EXPORTS void dftInit2D(DftContext & c, int _width, int _height, int _depth, int _src_channels, int _dst_channels, int flags, int _nonzero_rows = 0); struct CV_EXPORTS DFT2D
CV_EXPORTS void dft2D(const DftContext & c, const void * src, int src_step, void * dst, int dst_step); {
CV_EXPORTS void dftFree2D(DftContext & c); static Ptr<DFT2D> create(int width, int height, int depth,
int src_channels, int dst_channels,
CV_EXPORTS void dftInit1D(DftContext & c, int len, int count, int depth, int flags, bool * useBuffer = 0); int flags, int nonzero_rows = 0);
CV_EXPORTS void dft1D(const DftContext & c, const void * src, void * dst); virtual void apply(const uchar *src_data, size_t src_step, uchar *dst_data, size_t dst_step) = 0;
CV_EXPORTS void dftFree1D(DftContext & c); virtual ~DFT2D() {}
};
CV_EXPORTS void dctInit2D(DftContext & c, int width, int height, int depth, int flags); struct CV_EXPORTS DCT2D
CV_EXPORTS void dct2D(const DftContext & c, const void * src, int src_step, void * dst, int dst_step); {
CV_EXPORTS void dctFree2D(DftContext & c); static Ptr<DCT2D> create(int width, int height, int depth, int flags);
virtual void apply(const uchar *src_data, size_t src_step, uchar *dst_data, size_t dst_step) = 0;
virtual ~DCT2D() {}
};
//! @} core_hal //! @} core_hal
......
...@@ -11,21 +11,11 @@ ...@@ -11,21 +11,11 @@
#define CV_HAL_ERROR_UNKNOWN -1 #define CV_HAL_ERROR_UNKNOWN -1
//! @} //! @}
#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
#include <stddef.h> #include <stddef.h>
#include <stdbool.h>
#endif #endif
//! @name Data types //! @name Data types
...@@ -155,6 +145,19 @@ typedef signed char schar; ...@@ -155,6 +145,19 @@ typedef signed char schar;
#define CV_HAL_BORDER_ISOLATED 16 #define CV_HAL_BORDER_ISOLATED 16
//! @} //! @}
//! @name DFT flags
//! @{
#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
//! @}
//! @} //! @}
#endif #endif
This diff is collapsed.
...@@ -376,38 +376,109 @@ inline int hal_ni_merge64s(const int64 **src_data, int64 *dst_data, int len, int ...@@ -376,38 +376,109 @@ inline int hal_ni_merge64s(const int64 **src_data, int64 *dst_data, int len, int
#define cv_hal_merge64s hal_ni_merge64s #define cv_hal_merge64s hal_ni_merge64s
//! @endcond //! @endcond
//! @} /**
@brief Dummy structure storing DFT/DCT context
#if defined __GNUC__
# pragma GCC diagnostic pop Users can convert this pointer to any type they want. Initialisation and destruction should be made in Init and Free function implementations correspondingly.
#elif defined _MSC_VER Example:
# pragma warning( pop ) @code{.cpp}
#endif int my_hal_dftInit2D(cvhalDFT **context, ...) {
*context = static_cast<cvhalDFT*>(new MyFilterData());
//... init
}
int my_hal_dftFree2D(cvhalDFT *context) {
MyFilterData *c = static_cast<MyFilterData*>(context);
delete c;
}
@endcode
*/
struct cvhalDFT {};
inline int hal_ni_dftInit1D(void**, int, int, int, int, bool*) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } /**
inline int hal_ni_dft1D(const void*, const void*, void*) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } @param context double pointer to context storing all necessary data
inline int hal_ni_dftFree1D(void*) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } @param len transformed array length
@param count estimated transformation count
@param depth array type (CV_32F or CV_64F)
@param flags algorithm options (combination of CV_HAL_DFT_INVERSE, CV_HAL_DFT_SCALE, ...)
@param needBuffer pointer to boolean variable, if valid pointer provided, then variable value should be set to true to signal that additional memory buffer is needed for operations
*/
inline int hal_ni_dftInit1D(cvhalDFT **context, int len, int count, int depth, int flags, bool *needBuffer) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
/**
@param context pointer to context storing all necessary data
@param src source data
@param dst destination data
*/
inline int hal_ni_dft1D(cvhalDFT *context, const uchar *src, uchar *dst) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
/**
@param context pointer to context storing all necessary data
*/
inline int hal_ni_dftFree1D(cvhalDFT *context) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
//! @cond IGNORED
#define cv_hal_dftInit1D hal_ni_dftInit1D #define cv_hal_dftInit1D hal_ni_dftInit1D
#define cv_hal_dft1D hal_ni_dft1D #define cv_hal_dft1D hal_ni_dft1D
#define cv_hal_dftFree1D hal_ni_dftFree1D #define cv_hal_dftFree1D hal_ni_dftFree1D
//! @endcond
inline int hal_ni_dftInit2D(void **, int, int, int, int, int, int, int) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } /**
inline int hal_ni_dft2D(const void *, const void *, int, void *, int) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } @param context double pointer to context storing all necessary data
inline int hal_ni_dftFree2D(void *) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } @param width,height image dimensions
@param depth image type (CV_32F or CV64F)
@param src_channels number of channels in input image
@param dst_channels number of channels in output image
@param flags algorithm options (combination of CV_HAL_DFT_INVERSE, ...)
@param nonzero_rows number of nonzero rows in image, can be used for optimization
*/
inline int hal_ni_dftInit2D(cvhalDFT **context, int width, int height, int depth, int src_channels, int dst_channels, int flags, int nonzero_rows) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
/**
@param context pointer to context storing all necessary data
@param src_data,src_step source image data and step
@param dst_data,dst_step destination image data and step
*/
inline int hal_ni_dft2D(cvhalDFT *context, const uchar *src_data, size_t src_step, uchar *dst_data, size_t dst_step) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
/**
@param context pointer to context storing all necessary data
*/
inline int hal_ni_dftFree2D(cvhalDFT *context) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
//! @cond IGNORED
#define cv_hal_dftInit2D hal_ni_dftInit2D #define cv_hal_dftInit2D hal_ni_dftInit2D
#define cv_hal_dft2D hal_ni_dft2D #define cv_hal_dft2D hal_ni_dft2D
#define cv_hal_dftFree2D hal_ni_dftFree2D #define cv_hal_dftFree2D hal_ni_dftFree2D
//! @endcond
/**
@param context double pointer to context storing all necessary data
@param width,height image dimensions
@param depth image type (CV_32F or CV64F)
@param flags algorithm options (combination of CV_HAL_DFT_INVERSE, ...)
*/
inline int hal_ni_dctInit2D(cvhalDFT **context, int width, int height, int depth, int flags) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
/**
@param context pointer to context storing all necessary data
@param src_data,src_step source image data and step
@param dst_data,dst_step destination image data and step
*/
inline int hal_ni_dct2D(cvhalDFT *context, const uchar *src_data, size_t src_step, uchar *dst_data, size_t dst_step) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
/**
@param context pointer to context storing all necessary data
*/
inline int hal_ni_dctFree2D(cvhalDFT *context) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
inline int hal_ni_dctInit2D(void **, int, int, int, int) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } //! @cond IGNORED
inline int hal_ni_dct2D(const void *, const void *, int, void *, int) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
inline int hal_ni_dctFree2D(void *) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
#define cv_hal_dctInit2D hal_ni_dctInit2D #define cv_hal_dctInit2D hal_ni_dctInit2D
#define cv_hal_dct2D hal_ni_dct2D #define cv_hal_dct2D hal_ni_dct2D
#define cv_hal_dctFree2D hal_ni_dctFree2D #define cv_hal_dctFree2D hal_ni_dctFree2D
//! @endcond
//! @}
#if defined __GNUC__
# pragma GCC diagnostic pop
#elif defined _MSC_VER
# pragma warning( pop )
#endif
#include "custom_hal.hpp" #include "custom_hal.hpp"
......
...@@ -700,8 +700,7 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr, ...@@ -700,8 +700,7 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
buf.resize(bufSize); buf.resize(bufSize);
hal::DftContext c; Ptr<hal::DFT2D> c = hal::DFT2D::create(dftsize.width, dftsize.height, dftTempl.depth(), 1, 1, CV_HAL_DFT_IS_INPLACE, templ.rows);
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++ )
...@@ -726,11 +725,9 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr, ...@@ -726,11 +725,9 @@ 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);
} }
hal::dft2D(c, dst.data, (int)dst.step, dst.data, (int)dst.step); c->apply(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;
...@@ -747,11 +744,11 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr, ...@@ -747,11 +744,11 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
} }
borderType |= BORDER_ISOLATED; borderType |= BORDER_ISOLATED;
hal::DftContext cF, cR; Ptr<hal::DFT2D> cF, cR;
int f = CV_HAL_DFT_IS_INPLACE; int f = CV_HAL_DFT_IS_INPLACE;
int f_inv = f | CV_HAL_DFT_INVERSE | CV_HAL_DFT_SCALE; 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); cF = hal::DFT2D::create(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); cR = hal::DFT2D::create(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++ )
...@@ -791,7 +788,7 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr, ...@@ -791,7 +788,7 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
x1-x0, dst.cols-dst1.cols-(x1-x0), borderType); x1-x0, dst.cols-dst1.cols-(x1-x0), borderType);
if (bsz.height == blocksize.height) if (bsz.height == blocksize.height)
hal::dft2D(cF, dftImg.data, (int)dftImg.step, dftImg.data, (int)dftImg.step); cF->apply(dftImg.data, (int)dftImg.step, dftImg.data, (int)dftImg.step);
else else
dft( dftImg, dftImg, 0, dsz.height ); dft( dftImg, dftImg, 0, dsz.height );
...@@ -800,7 +797,7 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr, ...@@ -800,7 +797,7 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
mulSpectrums(dftImg, dftTempl1, dftImg, 0, true); mulSpectrums(dftImg, dftTempl1, dftImg, 0, true);
if (bsz.height == blocksize.height) if (bsz.height == blocksize.height)
hal::dft2D(cR, dftImg.data, (int)dftImg.step, dftImg.data, (int)dftImg.step); cR->apply(dftImg.data, (int)dftImg.step, dftImg.data, (int)dftImg.step);
else else
dft( dftImg, dftImg, DFT_INVERSE + DFT_SCALE, bsz.height ); dft( dftImg, dftImg, DFT_INVERSE + DFT_SCALE, bsz.height );
...@@ -834,8 +831,6 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr, ...@@ -834,8 +831,6 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
} }
} }
} }
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 )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment