refactored imgproc

This commit is contained in:
Ilya Lavrenov 2014-01-27 13:25:21 +04:00
parent 321782b9b7
commit 78c2b3ca2a
17 changed files with 479 additions and 432 deletions

View File

@ -29,7 +29,7 @@
#endif
#else
#define CV_OCL_RUN_(condition, func, retval)
#define CV_OCL_RUN_(condition, func, ...)
#endif
#define CV_OCL_RUN(condition, func) CV_OCL_RUN_(condition, func)

View File

@ -91,6 +91,8 @@ private:
Mat * dst;
};
#ifdef HAVE_OPENCL
static bool ocl_blendLinear( InputArray _src1, InputArray _src2, InputArray _weights1, InputArray _weights2, OutputArray _dst )
{
int type = _src1.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
@ -113,6 +115,8 @@ static bool ocl_blendLinear( InputArray _src1, InputArray _src2, InputArray _wei
return k.run(2, globalsize, NULL, false);
}
#endif
}
void cv::blendLinear( InputArray _src1, InputArray _src2, InputArray _weights1, InputArray _weights2, OutputArray _dst )
@ -126,8 +130,8 @@ void cv::blendLinear( InputArray _src1, InputArray _src2, InputArray _weights1,
_dst.create(size, type);
if (ocl::useOpenCL() && _dst.isUMat() && ocl_blendLinear(_src1, _src2, _weights1, _weights2, _dst))
return;
CV_OCL_RUN(_dst.isUMat(),
ocl_blendLinear(_src1, _src2, _weights1, _weights2, _dst))
Mat src1 = _src1.getMat(), src2 = _src2.getMat(), weights1 = _weights1.getMat(),
weights2 = _weights2.getMat(), dst = _dst.getMat();

View File

@ -88,6 +88,8 @@ static bool ippCanny(const Mat& _src, Mat& _dst, float low, float high)
}
#endif
#ifdef HAVE_OPENCL
static bool ocl_Canny(InputArray _src, OutputArray _dst, float low_thresh, float high_thresh,
int aperture_size, bool L2gradient, int cn, const Size & size)
{
@ -230,6 +232,8 @@ static bool ocl_Canny(InputArray _src, OutputArray _dst, float low_thresh, float
return getEdgesKernel.run(2, globalsize, NULL, false);
}
#endif
}
void cv::Canny( InputArray _src, OutputArray _dst,
@ -255,9 +259,8 @@ void cv::Canny( InputArray _src, OutputArray _dst,
if (low_thresh > high_thresh)
std::swap(low_thresh, high_thresh);
if (ocl::useOpenCL() && _dst.isUMat() && cn == 1 &&
ocl_Canny(_src, _dst, (float)low_thresh, (float)high_thresh, aperture_size, L2gradient, cn, size))
return;
CV_OCL_RUN(_dst.isUMat() && cn == 1,
ocl_Canny(_src, _dst, (float)low_thresh, (float)high_thresh, aperture_size, L2gradient, cn, size))
Mat src = _src.getMat(), dst = _dst.getMat();

View File

@ -45,6 +45,8 @@
// ----------------------------------------------------------------------
// CLAHE
#ifdef HAVE_OPENCL
namespace clahe
{
static bool calcLut(cv::InputArray _src, cv::OutputArray _dst,
@ -124,6 +126,8 @@ namespace clahe
}
}
#endif
namespace
{
class CLAHE_CalcLut_Body : public cv::ParallelLoopBody
@ -321,9 +325,12 @@ namespace
int tilesY_;
cv::Mat srcExt_;
cv::UMat usrcExt_;
cv::Mat lut_;
#ifdef HAVE_OPENCL
cv::UMat usrcExt_;
cv::UMat ulut_;
#endif
};
CLAHE_Impl::CLAHE_Impl(double clipLimit, int tilesX, int tilesY) :
@ -340,7 +347,9 @@ namespace
{
CV_Assert( _src.type() == CV_8UC1 );
#ifdef HAVE_OPENCL
bool useOpenCL = cv::ocl::useOpenCL() && _src.isUMat() && _src.dims()<=2;
#endif
const int histSize = 256;
@ -354,6 +363,7 @@ namespace
}
else
{
#ifdef HAVE_OPENCL
if(useOpenCL)
{
cv::copyMakeBorder(_src, usrcExt_, 0, tilesY_ - (_src.size().height % tilesY_), 0, tilesX_ - (_src.size().width % tilesX_), cv::BORDER_REFLECT_101);
@ -361,6 +371,7 @@ namespace
_srcForLut = usrcExt_;
}
else
#endif
{
cv::copyMakeBorder(_src, srcExt_, 0, tilesY_ - (_src.size().height % tilesY_), 0, tilesX_ - (_src.size().width % tilesX_), cv::BORDER_REFLECT_101);
tileSize = cv::Size(srcExt_.size().width / tilesX_, srcExt_.size().height / tilesY_);
@ -378,9 +389,11 @@ namespace
clipLimit = std::max(clipLimit, 1);
}
if(useOpenCL && clahe::calcLut(_srcForLut, ulut_, tilesX_, tilesY_, tileSize, clipLimit, lutScale) )
#ifdef HAVE_OPENCL
if (useOpenCL && clahe::calcLut(_srcForLut, ulut_, tilesX_, tilesY_, tileSize, clipLimit, lutScale) )
if( clahe::transform(_src, _dst, ulut_, tilesX_, tilesY_, tileSize) )
return;
#endif
cv::Mat src = _src.getMat();
_dst.create( src.size(), src.type() );
@ -420,8 +433,10 @@ namespace
{
srcExt_.release();
lut_.release();
#ifdef HAVE_OPENCL
usrcExt_.release();
ulut_.release();
#endif
}
}

View File

@ -2688,6 +2688,7 @@ struct mRGBA2RGBA
}
};
#ifdef HAVE_OPENCL
static bool ocl_cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
{
@ -3041,6 +3042,8 @@ static bool ocl_cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
return ok;
}
#endif
}//namespace cv
//////////////////////////////////////////////////////////////////////////////////////////
@ -3049,12 +3052,11 @@ static bool ocl_cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
{
bool use_opencl = ocl::useOpenCL() && _dst.kind() == _InputArray::UMAT;
int stype = _src.type();
int scn = CV_MAT_CN(stype), depth = CV_MAT_DEPTH(stype), bidx;
if( use_opencl && ocl_cvtColor(_src, _dst, code, dcn) )
return;
CV_OCL_RUN( _src.dims() <= 2 && _dst.isUMat(),
ocl_cvtColor(_src, _dst, code, dcn) )
Mat src = _src.getMat(), dst;
Size sz = src.size();

View File

@ -302,6 +302,8 @@ cornerEigenValsVecs( const Mat& src, Mat& eigenv, int block_size,
calcEigenValsVecs( cov, eigenv );
}
#ifdef HAVE_OPENCL
static bool ocl_cornerMinEigenValVecs(InputArray _src, OutputArray _dst, int block_size,
int aperture_size, double k, int borderType, int op_type)
{
@ -393,13 +395,14 @@ static bool ocl_preCornerDetect( InputArray _src, OutputArray _dst, int ksize, i
return k.run(2, globalsize, NULL, false);
}
#endif
}
void cv::cornerMinEigenVal( InputArray _src, OutputArray _dst, int blockSize, int ksize, int borderType )
{
if (ocl::useOpenCL() && _src.dims() <= 2 && _dst.isUMat() &&
ocl_cornerMinEigenValVecs(_src, _dst, blockSize, ksize, 0.0, borderType, MINEIGENVAL))
return;
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_cornerMinEigenValVecs(_src, _dst, blockSize, ksize, 0.0, borderType, MINEIGENVAL))
Mat src = _src.getMat();
_dst.create( src.size(), CV_32FC1 );
@ -410,9 +413,8 @@ void cv::cornerMinEigenVal( InputArray _src, OutputArray _dst, int blockSize, in
void cv::cornerHarris( InputArray _src, OutputArray _dst, int blockSize, int ksize, double k, int borderType )
{
if (ocl::useOpenCL() && _src.dims() <= 2 && _dst.isUMat() &&
ocl_cornerMinEigenValVecs(_src, _dst, blockSize, ksize, k, borderType, HARRIS))
return;
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_cornerMinEigenValVecs(_src, _dst, blockSize, ksize, k, borderType, HARRIS))
Mat src = _src.getMat();
_dst.create( src.size(), CV_32FC1 );
@ -439,9 +441,8 @@ void cv::preCornerDetect( InputArray _src, OutputArray _dst, int ksize, int bord
int type = _src.type();
CV_Assert( type == CV_8UC1 || type == CV_32FC1 );
if (ocl::useOpenCL() && _src.dims() <= 2 && _dst.isUMat() &&
ocl_preCornerDetect(_src, _dst, ksize, borderType, CV_MAT_DEPTH(type)))
return;
CV_OCL_RUN( _src.dims() <= 2 && _dst.isUMat(),
ocl_preCornerDetect(_src, _dst, ksize, borderType, CV_MAT_DEPTH(type)))
Mat Dx, Dy, D2x, D2y, Dxy, src = _src.getMat();
_dst.create( src.size(), CV_32FC1 );

View File

@ -66,6 +66,8 @@ struct Corner
{ return val > c.val; }
};
#ifdef HAVE_OPENCL
static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
int maxCorners, double qualityLevel, double minDistance,
InputArray _mask, int blockSize,
@ -211,6 +213,8 @@ static bool ocl_goodFeaturesToTrack( InputArray _image, OutputArray _corners,
return true;
}
#endif
}
void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
@ -221,10 +225,9 @@ void cv::goodFeaturesToTrack( InputArray _image, OutputArray _corners,
CV_Assert( qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0 );
CV_Assert( _mask.empty() || (_mask.type() == CV_8UC1 && _mask.sameSize(_image)) );
if (ocl::useOpenCL() && _image.dims() <= 2 && _image.isUMat() &&
ocl_goodFeaturesToTrack(_image, _corners, maxCorners, qualityLevel, minDistance,
CV_OCL_RUN(_image.dims() <= 2 && _image.isUMat(),
ocl_goodFeaturesToTrack(_image, _corners, maxCorners, qualityLevel, minDistance,
_mask, blockSize, useHarrisDetector, harrisK))
return;
Mat image = _image.getMat(), eig, tmp;
if( useHarrisDetector )

View File

@ -3115,10 +3115,7 @@ template<typename ST, class CastOp, class VecOp> struct Filter2D : public BaseFi
VecOp vecOp;
};
}
namespace cv
{
#ifdef HAVE_OPENCL
#define DIVUP(total, grain) (((total) + (grain) - 1) / (grain))
#define ROUNDUP(sz, n) ((sz) + (n) - 1 - (((sz) + (n) - 1) % (n)))
@ -3551,6 +3548,9 @@ static bool ocl_sepFilter2D( InputArray _src, OutputArray _dst, int ddepth,
UMat dst = _dst.getUMat();
return ocl_sepColFilter2D(buf, dst, kernelY, anchor.y, true);
}
#endif
}
cv::Ptr<cv::BaseFilter> cv::getLinearFilter(int srcType, int dstType,
@ -3668,9 +3668,8 @@ void cv::filter2D( InputArray _src, OutputArray _dst, int ddepth,
InputArray _kernel, Point anchor,
double delta, int borderType )
{
bool use_opencl = ocl::useOpenCL() && _dst.isUMat();
if( use_opencl && ocl_filter2D(_src, _dst, ddepth, _kernel, anchor, delta, borderType))
return;
CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2,
ocl_filter2D(_src, _dst, ddepth, _kernel, anchor, delta, borderType))
Mat src = _src.getMat(), kernel = _kernel.getMat();
@ -3718,9 +3717,8 @@ void cv::sepFilter2D( InputArray _src, OutputArray _dst, int ddepth,
InputArray _kernelX, InputArray _kernelY, Point anchor,
double delta, int borderType )
{
bool use_opencl = ocl::useOpenCL() && _dst.isUMat();
if (use_opencl && ocl_sepFilter2D(_src, _dst, ddepth, _kernelX, _kernelY, anchor, delta, borderType))
return;
CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2,
ocl_sepFilter2D(_src, _dst, ddepth, _kernelX, _kernelY, anchor, delta, borderType))
Mat src = _src.getMat(), kernelX = _kernelX.getMat(), kernelY = _kernelY.getMat();

View File

@ -1929,6 +1929,7 @@ void cv::calcBackProject( const Mat* images, int nimages, const int* channels,
CV_Error(CV_StsUnsupportedFormat, "");
}
#ifdef HAVE_OPENCL
namespace cv {
@ -1962,7 +1963,9 @@ static bool ocl_calcBackProject( InputArrayOfArrays _images, std::vector<int> ch
const std::vector<float>& ranges,
float scale, size_t histdims )
{
const std::vector<UMat> & images = *(const std::vector<UMat> *)_images.getObj();
std::vector<UMat> images;
_images.getUMatVector(images);
size_t nimages = images.size(), totalcn = images[0].channels();
CV_Assert(nimages > 0);
@ -2066,19 +2069,22 @@ static bool ocl_calcBackProject( InputArrayOfArrays _images, std::vector<int> ch
}
#endif
void cv::calcBackProject( InputArrayOfArrays images, const std::vector<int>& channels,
InputArray hist, OutputArray dst,
const std::vector<float>& ranges,
double scale )
{
Size histSize = hist.size();
#ifdef HAVE_OPENCL
bool _1D = histSize.height == 1 || histSize.width == 1;
size_t histdims = _1D ? 1 : hist.dims();
#endif
if (ocl::useOpenCL() && images.isUMatVector() && dst.isUMat() && hist.type() == CV_32FC1 &&
histdims <= 2 && ranges.size() == histdims * 2 && histdims == channels.size() &&
ocl_calcBackProject(images, channels, hist, dst, ranges, (float)scale, histdims))
return;
CV_OCL_RUN(dst.isUMat() && hist.type() == CV_32FC1 &&
histdims <= 2 && ranges.size() == histdims * 2 && histdims == channels.size(),
ocl_calcBackProject(images, channels, hist, dst, ranges, (float)scale, histdims))
Mat H0 = hist.getMat(), H;
int hcn = H0.channels();
@ -3280,6 +3286,8 @@ CV_IMPL void cvEqualizeHist( const CvArr* srcarr, CvArr* dstarr )
cv::equalizeHist(cv::cvarrToMat(srcarr), cv::cvarrToMat(dstarr));
}
#ifdef HAVE_OPENCL
namespace cv {
enum
@ -3340,6 +3348,8 @@ static bool ocl_equalizeHist(InputArray _src, OutputArray _dst)
}
#endif
void cv::equalizeHist( InputArray _src, OutputArray _dst )
{
CV_Assert( _src.type() == CV_8UC1 );
@ -3347,8 +3357,8 @@ void cv::equalizeHist( InputArray _src, OutputArray _dst )
if (_src.empty())
return;
if (ocl::useOpenCL() && _dst.isUMat() && ocl_equalizeHist(_src, _dst))
return;
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_equalizeHist(_src, _dst))
Mat src = _src.getMat();
_dst.create( src.size(), src.type() );

View File

@ -1900,6 +1900,8 @@ private:
};
#endif
#ifdef HAVE_OPENCL
static void ocl_computeResizeAreaTabs(int ssize, int dsize, double scale, int * const map_tab,
float * const alpha_tab, int * const ofs_tab)
{
@ -2069,6 +2071,8 @@ static bool ocl_resize( InputArray _src, OutputArray _dst, Size dsize,
return k.run(2, globalsize, 0, false);
}
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
@ -2196,9 +2200,8 @@ void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
inv_scale_y = (double)dsize.height/ssize.height;
}
if( ocl::useOpenCL() && _dst.kind() == _InputArray::UMAT &&
ocl_resize(_src, _dst, dsize, inv_scale_x, inv_scale_y, interpolation))
return;
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_resize(_src, _dst, dsize, inv_scale_x, inv_scale_y, interpolation))
Mat src = _src.getMat();
_dst.create(dsize, src.type());
@ -3390,6 +3393,8 @@ private:
const void *ctab;
};
#ifdef HAVE_OPENCL
static bool ocl_remap(InputArray _src, OutputArray _dst, InputArray _map1, InputArray _map2,
int interpolation, int borderType, const Scalar& borderValue)
{
@ -3462,6 +3467,8 @@ static bool ocl_remap(InputArray _src, OutputArray _dst, InputArray _map1, Input
return k.run(2, globalThreads, NULL, false);
}
#endif
}
void cv::remap( InputArray _src, OutputArray _dst,
@ -3504,8 +3511,8 @@ void cv::remap( InputArray _src, OutputArray _dst,
CV_Assert( _map1.size().area() > 0 );
CV_Assert( _map2.empty() || (_map2.size() == _map1.size()));
if (ocl::useOpenCL() && _dst.isUMat() && ocl_remap(_src, _dst, _map1, _map2, interpolation, borderType, borderValue))
return;
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_remap(_src, _dst, _map1, _map2, interpolation, borderType, borderValue))
Mat src = _src.getMat(), map1 = _map1.getMat(), map2 = _map2.getMat();
_dst.create( map1.size(), src.type() );
@ -3870,6 +3877,8 @@ private:
};
#endif
#ifdef HAVE_OPENCL
enum { OCL_OP_PERSPECTIVE = 1, OCL_OP_AFFINE = 0 };
static bool ocl_warpTransform(InputArray _src, OutputArray _dst, InputArray _M0,
@ -3953,6 +3962,8 @@ static bool ocl_warpTransform(InputArray _src, OutputArray _dst, InputArray _M0,
return k.run(2, globalThreads, NULL, false);
}
#endif
}
@ -3960,10 +3971,9 @@ void cv::warpAffine( InputArray _src, OutputArray _dst,
InputArray _M0, Size dsize,
int flags, int borderType, const Scalar& borderValue )
{
if (ocl::useOpenCL() && _dst.isUMat() &&
ocl_warpTransform(_src, _dst, _M0, dsize, flags, borderType,
borderValue, OCL_OP_AFFINE))
return;
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_warpTransform(_src, _dst, _M0, dsize, flags, borderType,
borderValue, OCL_OP_AFFINE))
Mat src = _src.getMat(), M0 = _M0.getMat();
_dst.create( dsize.area() == 0 ? src.size() : dsize, src.type() );
@ -4206,10 +4216,9 @@ void cv::warpPerspective( InputArray _src, OutputArray _dst, InputArray _M0,
{
CV_Assert( _src.total() > 0 );
if (ocl::useOpenCL() && _dst.isUMat() &&
ocl_warpTransform(_src, _dst, _M0, dsize, flags, borderType, borderValue,
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_warpTransform(_src, _dst, _M0, dsize, flags, borderType, borderValue,
OCL_OP_PERSPECTIVE))
return;
Mat src = _src.getMat(), M0 = _M0.getMat();
_dst.create( dsize.area() == 0 ? src.size() : dsize, src.type() );

View File

@ -363,6 +363,8 @@ Moments::Moments( double _m00, double _m10, double _m01, double _m20, double _m1
nu30 = mu30*s3; nu21 = mu21*s3; nu12 = mu12*s3; nu03 = mu03*s3;
}
#ifdef HAVE_OPENCL
static bool ocl_moments( InputArray _src, Moments& m)
{
const int TILE_SIZE = 32;
@ -427,6 +429,8 @@ static bool ocl_moments( InputArray _src, Moments& m)
return true;
}
#endif
}
@ -444,10 +448,12 @@ cv::Moments cv::moments( InputArray _src, bool binary )
if( size.width <= 0 || size.height <= 0 )
return m;
#ifdef HAVE_OPENCL
if( ocl::useOpenCL() && type == CV_8UC1 && !binary &&
_src.isUMat() && ocl_moments(_src, m) )
;
else
#endif
{
Mat mat = _src.getMat();
if( mat.checkVector(2) >= 0 && (depth == CV_32F || depth == CV_32S))

View File

@ -1284,7 +1284,7 @@ static bool IPPMorphOp(int op, InputArray _src, OutputArray _dst,
}
#endif
static const char* op2str[] = {"ERODE", "DILATE"};
#ifdef HAVE_OPENCL
static bool ocl_morphology_op(InputArray _src, OutputArray _dst, InputArray _kernel, Size &ksize, const Point anchor, int iterations, int op)
{
@ -1315,6 +1315,7 @@ static bool ocl_morphology_op(InputArray _src, OutputArray _dst, InputArray _ker
return false;
char compile_option[128];
static const char* op2str[] = {"ERODE", "DILATE"};
sprintf(compile_option, "-D RADIUSX=%d -D RADIUSY=%d -D LSIZE0=%d -D LSIZE1=%d -D %s %s %s -D GENTYPE=%s -D DEPTH_%d",
anchor.x, anchor.y, (int)localThreads[0], (int)localThreads[1], op2str[op], doubleSupport?"-D DOUBLE_SUPPORT" :"", rectKernel?"-D RECTKERNEL":"",
ocl::typeToStr(_src.type()), _src.depth() );
@ -1396,19 +1397,17 @@ static bool ocl_morphology_op(InputArray _src, OutputArray _dst, InputArray _ker
return true;
}
#endif
static void morphOp( int op, InputArray _src, OutputArray _dst,
InputArray _kernel,
Point anchor, int iterations,
int borderType, const Scalar& borderValue )
{
#ifdef HAVE_OPENCL
int src_type = _src.type(), dst_type = _dst.type(),
src_cn = CV_MAT_CN(src_type), src_depth = CV_MAT_DEPTH(src_type);
bool useOpenCL = cv::ocl::useOpenCL() && _dst.isUMat() && _src.size() == _dst.size() && src_type == dst_type &&
_src.dims() <= 2 && (src_cn == 1 || src_cn == 4) && anchor.x == -1 && anchor.y == -1 &&
(src_depth == CV_8U || src_depth == CV_32F || src_depth == CV_64F ) &&
borderType == cv::BORDER_CONSTANT && borderValue == morphologyDefaultBorderValue() &&
(op == MORPH_ERODE || op == MORPH_DILATE);
#endif
Mat kernel = _kernel.getMat();
Size ksize = kernel.data ? kernel.size() : Size(3,3);
@ -1443,8 +1442,12 @@ static void morphOp( int op, InputArray _src, OutputArray _dst,
iterations = 1;
}
if (useOpenCL && ocl_morphology_op(_src, _dst, kernel, ksize, anchor, iterations, op) )
return;
CV_OCL_RUN(_dst.isUMat() && _src.size() == _dst.size() && src_type == dst_type &&
_src.dims() <= 2 && (src_cn == 1 || src_cn == 4) && anchor.x == -1 && anchor.y == -1 &&
(src_depth == CV_8U || src_depth == CV_32F || src_depth == CV_64F ) &&
borderType == cv::BORDER_CONSTANT && borderValue == morphologyDefaultBorderValue() &&
(op == MORPH_ERODE || op == MORPH_DILATE),
ocl_morphology_op(_src, _dst, kernel, ksize, anchor, iterations, op) )
Mat src = _src.getMat();

View File

@ -401,6 +401,8 @@ pyrUp_( const Mat& _src, Mat& _dst, int)
typedef void (*PyrFunc)(const Mat&, Mat&, int);
#ifdef HAVE_OPENCL
static bool ocl_pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType)
{
int type = _src.type(), depth = CV_MAT_DEPTH(type), channels = CV_MAT_CN(type);
@ -484,13 +486,14 @@ static bool ocl_pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz, int
return k.run(2, globalThreads, localThreads, false);
}
#endif
}
void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )
{
if (ocl::useOpenCL() && _dst.isUMat() &&
ocl_pyrDown(_src, _dst, _dsz, borderType))
return;
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_pyrDown(_src, _dst, _dsz, borderType))
Mat src = _src.getMat();
Size dsz = _dsz.area() == 0 ? Size((src.cols + 1)/2, (src.rows + 1)/2) : _dsz;
@ -522,9 +525,8 @@ void cv::pyrDown( InputArray _src, OutputArray _dst, const Size& _dsz, int borde
void cv::pyrUp( InputArray _src, OutputArray _dst, const Size& _dsz, int borderType )
{
if (ocl::useOpenCL() && _dst.isUMat() &&
ocl_pyrUp(_src, _dst, _dsz, borderType))
return;
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_pyrUp(_src, _dst, _dsz, borderType))
Mat src = _src.getMat();
Size dsz = _dsz.area() == 0 ? Size(src.cols*2, src.rows*2) : _dsz;

View File

@ -1920,39 +1920,41 @@ medianBlur_SortNet( const Mat& _src, Mat& _dst, int m )
}
}
#ifdef HAVE_OPENCL
static bool ocl_medianFilter ( InputArray _src, OutputArray _dst, int m)
{
int type = _src.type();
int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
if (!((depth == CV_8U || depth == CV_16U || depth == CV_16S || depth == CV_32F) && (cn != 3 && cn <= 4)))
return false;
const char * kernelName;
if (m == 3)
kernelName = "medianFilter3";
else if (m == 5)
kernelName = "medianFilter5";
else
return false;
ocl::Kernel k(kernelName,ocl::imgproc::medianFilter_oclsrc,format("-D type=%s",ocl::typeToStr(type)));
if (k.empty())
return false;
UMat src = _src.getUMat();
_dst.create(_src.size(),type);
UMat dst = _dst.getUMat();
size_t globalsize[2] = {(src.cols + 18) / 16 * 16, (src.rows + 15) / 16 * 16};
size_t localsize[2] = {16, 16};
return k.args(ocl::KernelArg::ReadOnlyNoSize(src), ocl::KernelArg::WriteOnly(dst)).run(2,globalsize,localsize,false);
}
namespace cv
{
static bool ocl_medianFilter ( InputArray _src, OutputArray _dst, int m)
{
int type = _src.type();
int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
#endif
if (!((depth == CV_8U || depth == CV_16U || depth == CV_16S || depth == CV_32F) && (cn != 3 && cn <= 4)))
return false;
const char * kernelName;
if (m==3)
kernelName = "medianFilter3";
else if (m==5)
kernelName = "medianFilter5";
else
return false;
ocl::Kernel k(kernelName,ocl::imgproc::medianFilter_oclsrc,format("-D type=%s",ocl::typeToStr(type)));
if (k.empty())
return false;
_dst.create(_src.size(),type);
UMat src = _src.getUMat(), dst = _dst.getUMat();
size_t globalsize[2] = {(src.cols + 18) / 16 * 16, (src.rows + 15) / 16 * 16};
size_t localsize[2] = {16, 16};
return k.args(ocl::KernelArg::ReadOnlyNoSize(src), ocl::KernelArg::WriteOnly(dst)).run(2,globalsize,localsize,false);
}
}
void cv::medianBlur( InputArray _src0, OutputArray _dst, int ksize )
@ -1961,16 +1963,12 @@ void cv::medianBlur( InputArray _src0, OutputArray _dst, int ksize )
if( ksize <= 1 )
{
Mat src0 = _src0.getMat();
_dst.create( src0.size(), src0.type() );
Mat dst = _dst.getMat();
src0.copyTo(dst);
_src0.copyTo(_dst);
return;
}
bool use_opencl = ocl::useOpenCL() && _dst.isUMat();
if ( use_opencl && ocl_medianFilter(_src0,_dst, ksize))
return;
CV_OCL_RUN(_src0.dims() <= 2 && _dst.isUMat(),
ocl_medianFilter(_src0,_dst, ksize))
Mat src0 = _src0.getMat();
_dst.create( src0.size(), src0.type() );
@ -2226,6 +2224,8 @@ private:
};
#endif
#ifdef HAVE_OPENCL
static bool ocl_bilateralFilter_8u(InputArray _src, OutputArray _dst, int d,
double sigma_color, double sigma_space,
int borderType)
@ -2301,6 +2301,8 @@ static bool ocl_bilateralFilter_8u(InputArray _src, OutputArray _dst, int d,
return k.run(2, globalsize, NULL, false);
}
#endif
static void
bilateralFilter_8u( const Mat& src, Mat& dst, int d,
double sigma_color, double sigma_space,
@ -2651,9 +2653,8 @@ void cv::bilateralFilter( InputArray _src, OutputArray _dst, int d,
{
_dst.create( _src.size(), _src.type() );
if (ocl::useOpenCL() && _src.dims() <= 2 && _dst.isUMat() &&
ocl_bilateralFilter_8u(_src, _dst, d, sigmaColor, sigmaSpace, borderType))
return;
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),
ocl_bilateralFilter_8u(_src, _dst, d, sigmaColor, sigmaSpace, borderType))
Mat src = _src.getMat(), dst = _dst.getMat();

View File

@ -231,6 +231,8 @@ typedef void (*IntegralFunc)(const uchar* src, size_t srcstep, uchar* sum, size_
uchar* sqsum, size_t sqsumstep, uchar* tilted, size_t tstep,
Size size, int cn );
#ifdef HAVE_OPENCL
enum { vlen = 4 };
static bool ocl_integral( InputArray _src, OutputArray _sum, int sdepth )
@ -324,6 +326,8 @@ static bool ocl_integral( InputArray _src, OutputArray _sum, OutputArray _sqsum,
return k2.run(1, &gt2, &lt2, false);
}
#endif
}
@ -336,19 +340,17 @@ void cv::integral( InputArray _src, OutputArray _sum, OutputArray _sqsum, Output
sqdepth = CV_64F;
sdepth = CV_MAT_DEPTH(sdepth), sqdepth = CV_MAT_DEPTH(sqdepth);
#ifdef HAVE_OPENCL
if (ocl::useOpenCL() && _sum.isUMat() && !_tilted.needed())
{
if (!_sqsum.needed())
{
if (ocl_integral(_src, _sum, sdepth))
return;
CV_OCL_RUN(ocl::useOpenCL(), ocl_integral(_src, _sum, sdepth))
}
else if (_sqsum.isUMat())
{
if (ocl_integral(_src, _sum, _sqsum, sdepth, sqdepth))
return;
}
CV_OCL_RUN(ocl::useOpenCL(), ocl_integral(_src, _sum, _sqsum, sdepth, sqdepth))
}
#endif
Size ssize = _src.size(), isize(ssize.width + 1, ssize.height + 1);
_sum.create( isize, CV_MAKETYPE(sdepth, cn) );

View File

@ -42,338 +42,326 @@
#include "precomp.hpp"
#include "opencl_kernels.hpp"
//////////////////////////////////////////////////matchTemplate//////////////////////////////////////////////////////////
////////////////////////////////////////////////// matchTemplate //////////////////////////////////////////////////////////
namespace cv
{
static bool matchTemplate_CCORR(InputArray _image, InputArray _templ, OutputArray _result);
static bool matchTemplate_CCORR_NORMED(InputArray _image, InputArray _templ, OutputArray _result);
static bool matchTemplate_SQDIFF(InputArray _image, InputArray _templ, OutputArray _result);
static bool matchTemplate_SQDIFF_NORMED (InputArray _image, InputArray _templ, OutputArray _result);
#ifdef HAVE_OPENCL
static bool matchTemplate_CCOEFF(InputArray _image, InputArray _templ, OutputArray _result);
static bool matchTemplate_CCOEFF_NORMED(InputArray _image, InputArray _templ, OutputArray _result);
static bool matchTemplateNaive_CCORR (InputArray _image, InputArray _templ, OutputArray _result, int cn);
static bool matchTemplateNaive_SQDIFF(InputArray _image, InputArray _templ, OutputArray _result, int cn);
static bool useNaive(int method, int depth, Size size)
{
static bool useNaive(int method, int depth, Size size)
{
#ifdef HAVE_CLAMDFFT
if (method == TM_SQDIFF && depth == CV_32F)
return true;
else if(method == TM_CCORR || (method == TM_SQDIFF && depth == CV_8U))
return size.height < 18 && size.width < 18;
else
return false;
if (method == TM_SQDIFF && depth == CV_32F)
return true;
else if(method == TM_CCORR || (method == TM_SQDIFF && depth == CV_8U))
return size.height < 18 && size.width < 18;
else
return false;
#else
#define UNUSED(x) (void)(x);
UNUSED(method) UNUSED(depth) UNUSED(size)
UNUSED(method) UNUSED(depth) UNUSED(size)
#undef UNUSED
return true;
return true;
#endif
}
}
///////////////////////////////////////////////////CCORR//////////////////////////////////////////////////////////////
/////////////////////////////////////////////////// CCORR //////////////////////////////////////////////////////////////
static bool matchTemplate_CCORR(InputArray _image, InputArray _templ, OutputArray _result)
{
if (useNaive(TM_CCORR, _image.depth(), _templ.size()) )
return matchTemplateNaive_CCORR(_image, _templ, _result, _image.channels());
else
return false;
}
static bool matchTemplateNaive_CCORR (InputArray _image, InputArray _templ, OutputArray _result, int cn)
{
int type = _image.type();
int depth = CV_MAT_DEPTH(type);
static bool matchTemplateNaive_CCORR (InputArray _image, InputArray _templ, OutputArray _result, int cn)
const char * kernelName = "matchTemplate_Naive_CCORR";
ocl::Kernel k (kernelName, ocl::imgproc::match_template_oclsrc, format("-D type=%s -D elem_type=%s -D cn=%d",ocl::typeToStr(type), ocl::typeToStr(depth), cn));
if (k.empty())
return false;
UMat image = _image.getUMat();
UMat templ = _templ.getUMat(), result;
_result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32F);
result = _result.getUMat();
size_t globalsize[2] = {result.cols, result.rows};
return k.args(ocl::KernelArg::ReadOnlyNoSize(image), ocl::KernelArg::ReadOnly(templ), ocl::KernelArg::WriteOnly(result)).run(2,globalsize,NULL,false);
}
static bool matchTemplate_CCORR_NORMED(InputArray _image, InputArray _templ, OutputArray _result)
{
matchTemplate(_image, _templ, _result, CV_TM_CCORR);
int type = _image.type();
int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
const char * kernelName = "matchTemplate_CCORR_NORMED";
ocl::Kernel k(kernelName, ocl::imgproc::match_template_oclsrc, format("-D type=%s -D elem_type=%s -D cn=%d",ocl::typeToStr(type), ocl::typeToStr(depth), cn));
if (k.empty())
return false;
UMat image = _image.getUMat();
UMat templ = _templ.getUMat(), result;
_result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32F);
result = _result.getUMat();
UMat image_sums, image_sqsums;
integral(image.reshape(1), image_sums, image_sqsums, CV_32F, CV_32F);
UMat templ_resh, temp;
templ.reshape(1).convertTo(templ_resh, CV_32F);
multiply(templ_resh, templ_resh, temp);
unsigned long long templ_sqsum = (unsigned long long)sum(temp)[0];
size_t globalsize[2] = {result.cols, result.rows};
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sqsums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, templ_sqsum).run(2,globalsize,NULL,false);
}
static bool matchTemplate_CCORR(InputArray _image, InputArray _templ, OutputArray _result)
{
if (useNaive(TM_CCORR, _image.depth(), _templ.size()) )
return matchTemplateNaive_CCORR(_image, _templ, _result, _image.channels());
else
return false;
}
////////////////////////////////////// SQDIFF //////////////////////////////////////////////////////////////
static bool matchTemplateNaive_SQDIFF(InputArray _image, InputArray _templ, OutputArray _result, int cn)
{
int type = _image.type();
int depth = CV_MAT_DEPTH(type);
const char * kernelName = "matchTemplate_Naive_SQDIFF";
ocl::Kernel k (kernelName, ocl::imgproc::match_template_oclsrc, format("-D type=%s -D elem_type=%s -D cn=%d",ocl::typeToStr(type), ocl::typeToStr(depth), cn));
if (k.empty())
return false;
UMat image = _image.getUMat();
UMat templ = _templ.getUMat(), result;
_result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32F);
result = _result.getUMat();
size_t globalsize[2] = {result.cols, result.rows};
return k.args(ocl::KernelArg::ReadOnlyNoSize(image), ocl::KernelArg::ReadOnly(templ), ocl::KernelArg::WriteOnly(result)).run(2,globalsize,NULL,false);
}
static bool matchTemplate_SQDIFF_NORMED (InputArray _image, InputArray _templ, OutputArray _result)
{
matchTemplate(_image, _templ, _result, CV_TM_CCORR);
int type = _image.type();
int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
const char * kernelName = "matchTemplate_SQDIFF_NORMED";
ocl::Kernel k(kernelName, ocl::imgproc::match_template_oclsrc, format("-D type=%s -D elem_type=%s -D cn=%d",ocl::typeToStr(type), ocl::typeToStr(depth), cn));
if (k.empty())
return false;
UMat image = _image.getUMat();
UMat templ = _templ.getUMat(), result;
_result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32F);
result = _result.getUMat();
UMat image_sums, image_sqsums;
integral(image.reshape(1), image_sums, image_sqsums, CV_32F, CV_32F);
UMat temp, templ_resh;
templ.reshape(1).convertTo(templ_resh, CV_32F);
multiply(templ_resh, templ_resh, temp);
unsigned long long templ_sqsum = (unsigned long long)sum(temp)[0];
size_t globalsize[2] = {result.cols, result.rows};
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sqsums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, templ_sqsum).run(2,globalsize,NULL,false);
}
static bool matchTemplate_SQDIFF(InputArray _image, InputArray _templ, OutputArray _result)
{
if (useNaive(TM_SQDIFF, _image.depth(), _templ.size()))
return matchTemplateNaive_SQDIFF(_image, _templ, _result, _image.channels());
else
return false;
}
///////////////////////////////////// CCOEFF /////////////////////////////////////////////////////////////////
static bool matchTemplate_CCOEFF(InputArray _image, InputArray _templ, OutputArray _result)
{
matchTemplate(_image, _templ, _result, CV_TM_CCORR);
UMat image_sums;
integral(_image, image_sums);
int type = image_sums.type();
int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
const char * kernelName;
if (cn==1)
kernelName = "matchTemplate_Prepared_CCOEFF_C1";
else if (cn==2)
kernelName = "matchTemplate_Prepared_CCOEFF_C2";
else
kernelName = "matchTemplate_Prepared_CCOEFF_C4";
ocl::Kernel k(kernelName, ocl::imgproc::match_template_oclsrc, format("-D type=%s -D elem_type=%s -D cn=%d",ocl::typeToStr(type), ocl::typeToStr(depth), cn));
if (k.empty())
return false;
UMat templ = _templ.getUMat(), result;
Size size = _image.size();
_result.create(size.height - templ.rows + 1, size.width - templ.cols + 1, CV_32F);
result = _result.getUMat();
size_t globalsize[2] = {result.cols, result.rows};
if (cn==1)
{
int type = _image.type();
int depth = CV_MAT_DEPTH(type);
const char * kernelName = "matchTemplate_Naive_CCORR";
ocl::Kernel k (kernelName, ocl::imgproc::match_template_oclsrc, format("-D type=%s -D elem_type=%s -D cn=%d",ocl::typeToStr(type), ocl::typeToStr(depth), cn));
if (k.empty())
return false;
UMat image = _image.getUMat();
UMat templ = _templ.getUMat(), result;
_result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32F);
result = _result.getUMat();
size_t globalsize[2] = {result.cols, result.rows};
return k.args(ocl::KernelArg::ReadOnlyNoSize(image), ocl::KernelArg::ReadOnly(templ), ocl::KernelArg::WriteOnly(result)).run(2,globalsize,NULL,false);
float templ_sum = (float)sum(_templ)[0]/ _templ.size().area();
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, templ_sum).run(2,globalsize,NULL,false);
}
static bool matchTemplate_CCORR_NORMED(InputArray _image, InputArray _templ, OutputArray _result)
else
{
matchTemplate(_image, _templ, _result, CV_TM_CCORR);
int type = _image.type();
int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
const char * kernelName = "matchTemplate_CCORR_NORMED";
ocl::Kernel k(kernelName, ocl::imgproc::match_template_oclsrc, format("-D type=%s -D elem_type=%s -D cn=%d",ocl::typeToStr(type), ocl::typeToStr(depth), cn));
if (k.empty())
return false;
UMat image = _image.getUMat();
UMat templ = _templ.getUMat(), result;
_result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32F);
result = _result.getUMat();
UMat image_sums, image_sqsums;
integral(image.reshape(1), image_sums, image_sqsums, CV_32F, CV_32F);
UMat templ_resh, temp;
templ.reshape(1).convertTo(templ_resh, CV_32F);
multiply(templ_resh, templ_resh, temp);
unsigned long long templ_sqsum = (unsigned long long)sum(temp)[0];
size_t globalsize[2] = {result.cols, result.rows};
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sqsums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, templ_sqsum).run(2,globalsize,NULL,false);
}
//////////////////////////////////////SQDIFF//////////////////////////////////////////////////////////////
static bool matchTemplate_SQDIFF(InputArray _image, InputArray _templ, OutputArray _result)
{
if (useNaive(TM_SQDIFF, _image.depth(), _templ.size()))
{
return matchTemplateNaive_SQDIFF(_image, _templ, _result, _image.channels());;
}
else
return false;
}
static bool matchTemplateNaive_SQDIFF(InputArray _image, InputArray _templ, OutputArray _result, int cn)
{
int type = _image.type();
int depth = CV_MAT_DEPTH(type);
const char * kernelName = "matchTemplate_Naive_SQDIFF";
ocl::Kernel k (kernelName, ocl::imgproc::match_template_oclsrc, format("-D type=%s -D elem_type=%s -D cn=%d",ocl::typeToStr(type), ocl::typeToStr(depth), cn));
if (k.empty())
return false;
UMat image = _image.getUMat();
UMat templ = _templ.getUMat(), result;
_result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32F);
result = _result.getUMat();
size_t globalsize[2] = {result.cols, result.rows};
return k.args(ocl::KernelArg::ReadOnlyNoSize(image), ocl::KernelArg::ReadOnly(templ), ocl::KernelArg::WriteOnly(result)).run(2,globalsize,NULL,false);
}
static bool matchTemplate_SQDIFF_NORMED (InputArray _image, InputArray _templ, OutputArray _result)
{
matchTemplate(_image, _templ, _result, CV_TM_CCORR);
int type = _image.type();
int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
const char * kernelName = "matchTemplate_SQDIFF_NORMED";
ocl::Kernel k(kernelName, ocl::imgproc::match_template_oclsrc, format("-D type=%s -D elem_type=%s -D cn=%d",ocl::typeToStr(type), ocl::typeToStr(depth), cn));
if (k.empty())
return false;
UMat image = _image.getUMat();
UMat templ = _templ.getUMat(), result;
_result.create(image.rows - templ.rows + 1, image.cols - templ.cols + 1, CV_32F);
result = _result.getUMat();
UMat image_sums, image_sqsums;
integral(image.reshape(1), image_sums, image_sqsums, CV_32F, CV_32F);
UMat temp, templ_resh;
templ.reshape(1).convertTo(templ_resh, CV_32F);
multiply(templ_resh, templ_resh, temp);
unsigned long long templ_sqsum = (unsigned long long)sum(temp)[0];
size_t globalsize[2] = {result.cols, result.rows};
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sqsums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, templ_sqsum).run(2,globalsize,NULL,false);
}
/////////////////////////////////////CCOEFF/////////////////////////////////////////////////////////////////
static bool matchTemplate_CCOEFF(InputArray _image, InputArray _templ, OutputArray _result)
{
matchTemplate(_image, _templ, _result, CV_TM_CCORR);
UMat image_sums;
integral(_image, image_sums);
int type = image_sums.type();
int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
const char * kernelName;
if (cn==1)
kernelName = "matchTemplate_Prepared_CCOEFF_C1";
else if (cn==2)
kernelName = "matchTemplate_Prepared_CCOEFF_C2";
else
kernelName = "matchTemplate_Prepared_CCOEFF_C4";
ocl::Kernel k(kernelName, ocl::imgproc::match_template_oclsrc, format("-D type=%s -D elem_type=%s -D cn=%d",ocl::typeToStr(type), ocl::typeToStr(depth), cn));
if (k.empty())
return false;
UMat templ = _templ.getUMat(), result;
Size size = _image.size();
_result.create(size.height - templ.rows + 1, size.width - templ.cols + 1, CV_32F);
result = _result.getUMat();
size_t globalsize[2] = {result.cols, result.rows};
if (cn==1)
{
float templ_sum = (float)sum(_templ)[0]/ _templ.size().area();
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, templ_sum).run(2,globalsize,NULL,false);
}
else
{
Vec4f templ_sum = Vec4f::all(0);
templ_sum = sum(templ)/ templ.size().area();
if (cn==2)
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols,
templ_sum[0],templ_sum[1]).run(2,globalsize,NULL,false);
Vec4f templ_sum = Vec4f::all(0);
templ_sum = sum(templ)/ templ.size().area();
if (cn==2)
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols,
templ_sum[0],templ_sum[1],templ_sum[2],templ_sum[3]).run(2,globalsize,NULL,false);
}
}
templ_sum[0],templ_sum[1]).run(2,globalsize,NULL,false);
static bool matchTemplate_CCOEFF_NORMED(InputArray _image, InputArray _templ, OutputArray _result)
{
UMat imagef, templf;
_image.getUMat().convertTo(imagef, CV_32F);
_templ.getUMat().convertTo(templf, CV_32F);
matchTemplate(imagef, templf, _result, CV_TM_CCORR);
const char * kernelName;
UMat temp, image_sums, image_sqsums;
integral(_image,image_sums, image_sqsums, CV_32F, CV_32F);
int type = image_sums.type();
int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
if (cn== 1)
kernelName = "matchTemplate_CCOEFF_NORMED_C1";
else if (cn==2)
kernelName = "matchTemplate_CCOEFF_NORMED_C2";
else
kernelName = "matchTemplate_CCOEFF_NORMED_C4";
ocl::Kernel k(kernelName, ocl::imgproc::match_template_oclsrc,
format("-D type=%s -D elem_type=%s -D cn=%d", ocl::typeToStr(type), ocl::typeToStr(depth), cn));
if (k.empty())
return false;
UMat image = _image.getUMat();
UMat templ = _templ.getUMat(), result;
int image_rows = _image.size().height, image_cols = _image.size().width;
_result.create(image_rows - templ.rows + 1, image_cols - templ.cols + 1, CV_32F);
result = _result.getUMat();
size_t globalsize[2] = {result.cols, result.rows};
float scale = 1.f / templ.size().area();
if (cn==1)
{
float templ_sum = (float)sum(templ)[0];
multiply(templf, templf, temp);
float templ_sqsum = (float)sum(temp)[0];
templ_sqsum -= scale * templ_sum * templ_sum;
templ_sum *= scale;
if (templ_sqsum < DBL_EPSILON)
{
result = Scalar::all(1);
return true;
}
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums),ocl::KernelArg::ReadOnlyNoSize(image_sqsums),
ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, scale, templ_sum, templ_sqsum)
.run(2,globalsize,NULL,false);
}
else
{
Vec4f templ_sum = Vec4f::all(0);
Vec4f templ_sqsum = Vec4f::all(0);
templ_sum = sum(templ);
multiply(templf, templf, temp);
templ_sqsum = sum(temp);
float templ_sqsum_sum = 0;
for(int i = 0; i < cn; i ++)
{
templ_sqsum_sum += templ_sqsum[i] - scale * templ_sum[i] * templ_sum[i];
}
templ_sum *= scale;
if (templ_sqsum_sum < DBL_EPSILON)
{
result = Scalar::all(1);
return true;
}
if (cn==2)
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::ReadOnlyNoSize(image_sqsums),
ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, scale,
templ_sum[0],templ_sum[1], templ_sqsum_sum)
.run(2,globalsize,NULL,false);
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::ReadOnlyNoSize(image_sqsums),
ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, scale,
templ_sum[0],templ_sum[1],templ_sum[2],templ_sum[3], templ_sqsum_sum)
.run(2,globalsize,NULL,false);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
static bool ocl_matchTemplate( InputArray _img, InputArray _templ, OutputArray _result, int method)
{
int cn = CV_MAT_CN(_img.type());
if (cn == 3 || cn > 4)
return false;
typedef bool (*Caller)(InputArray _img, InputArray _templ, OutputArray _result);
const Caller callers[] =
{
matchTemplate_SQDIFF, matchTemplate_SQDIFF_NORMED, matchTemplate_CCORR,
matchTemplate_CCORR_NORMED, matchTemplate_CCOEFF, matchTemplate_CCOEFF_NORMED
};
Caller caller = callers[method];
return caller(_img, _templ, _result);
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols,
templ_sum[0],templ_sum[1],templ_sum[2],templ_sum[3]).run(2,globalsize,NULL,false);
}
}
namespace cv
static bool matchTemplate_CCOEFF_NORMED(InputArray _image, InputArray _templ, OutputArray _result)
{
UMat imagef, templf;
_image.getUMat().convertTo(imagef, CV_32F);
_templ.getUMat().convertTo(templf, CV_32F);
matchTemplate(imagef, templf, _result, CV_TM_CCORR);
const char * kernelName;
UMat temp, image_sums, image_sqsums;
integral(_image,image_sums, image_sqsums, CV_32F, CV_32F);
int type = image_sums.type();
int depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
if (cn== 1)
kernelName = "matchTemplate_CCOEFF_NORMED_C1";
else if (cn==2)
kernelName = "matchTemplate_CCOEFF_NORMED_C2";
else
kernelName = "matchTemplate_CCOEFF_NORMED_C4";
ocl::Kernel k(kernelName, ocl::imgproc::match_template_oclsrc,
format("-D type=%s -D elem_type=%s -D cn=%d", ocl::typeToStr(type), ocl::typeToStr(depth), cn));
if (k.empty())
return false;
UMat image = _image.getUMat();
UMat templ = _templ.getUMat(), result;
int image_rows = _image.size().height, image_cols = _image.size().width;
_result.create(image_rows - templ.rows + 1, image_cols - templ.cols + 1, CV_32F);
result = _result.getUMat();
size_t globalsize[2] = {result.cols, result.rows};
float scale = 1.f / templ.size().area();
if (cn==1)
{
float templ_sum = (float)sum(templ)[0];
multiply(templf, templf, temp);
float templ_sqsum = (float)sum(temp)[0];
templ_sqsum -= scale * templ_sum * templ_sum;
templ_sum *= scale;
if (templ_sqsum < DBL_EPSILON)
{
result = Scalar::all(1);
return true;
}
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums),ocl::KernelArg::ReadOnlyNoSize(image_sqsums),
ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, scale, templ_sum, templ_sqsum)
.run(2,globalsize,NULL,false);
}
else
{
Vec4f templ_sum = Vec4f::all(0);
Vec4f templ_sqsum = Vec4f::all(0);
templ_sum = sum(templ);
multiply(templf, templf, temp);
templ_sqsum = sum(temp);
float templ_sqsum_sum = 0;
for(int i = 0; i < cn; i ++)
{
templ_sqsum_sum += templ_sqsum[i] - scale * templ_sum[i] * templ_sum[i];
}
templ_sum *= scale;
if (templ_sqsum_sum < DBL_EPSILON)
{
result = Scalar::all(1);
return true;
}
if (cn==2)
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::ReadOnlyNoSize(image_sqsums),
ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, scale,
templ_sum[0],templ_sum[1], templ_sqsum_sum)
.run(2,globalsize,NULL,false);
return k.args(ocl::KernelArg::ReadOnlyNoSize(image_sums), ocl::KernelArg::ReadOnlyNoSize(image_sqsums),
ocl::KernelArg::WriteOnly(result), templ.rows, templ.cols, scale,
templ_sum[0],templ_sum[1],templ_sum[2],templ_sum[3], templ_sqsum_sum)
.run(2,globalsize,NULL,false);
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
static bool ocl_matchTemplate( InputArray _img, InputArray _templ, OutputArray _result, int method)
{
int cn = CV_MAT_CN(_img.type());
if (cn == 3 || cn > 4)
return false;
typedef bool (*Caller)(InputArray _img, InputArray _templ, OutputArray _result);
const Caller callers[] =
{
matchTemplate_SQDIFF, matchTemplate_SQDIFF_NORMED, matchTemplate_CCORR,
matchTemplate_CCORR_NORMED, matchTemplate_CCOEFF, matchTemplate_CCOEFF_NORMED
};
Caller caller = callers[method];
return caller(_img, _templ, _result);
}
#endif
void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
Size corrsize, int ctype,
@ -564,9 +552,7 @@ void crossCorr( const Mat& img, const Mat& _templ, Mat& corr,
void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result, int method )
{
CV_Assert( CV_TM_SQDIFF <= method && method <= CV_TM_CCOEFF_NORMED );
CV_Assert( (_img.depth() == CV_8U || _img.depth() == CV_32F) && _img.type() == _templ.type() );
CV_Assert(_img.dims() <= 2);
bool swapNotNeed = (_img.size().height >= _templ.size().height && _img.size().width >= _templ.size().width);
@ -575,9 +561,8 @@ void cv::matchTemplate( InputArray _img, InputArray _templ, OutputArray _result,
CV_Assert(_img.size().height <= _templ.size().height && _img.size().width <= _templ.size().width);
}
bool use_opencl = ocl::useOpenCL() && _result.isUMat();
if ( use_opencl && (swapNotNeed ? ocl_matchTemplate(_img,_templ,_result,method) : ocl_matchTemplate(_templ,_img,_result,method)))
return;
CV_OCL_RUN(_img.dims() <= 2 && _result.isUMat(),
(swapNotNeed ? ocl_matchTemplate(_img,_templ,_result,method) : ocl_matchTemplate(_templ,_img,_result,method)))
int numType = method == CV_TM_CCORR || method == CV_TM_CCORR_NORMED ? 0 :
method == CV_TM_CCOEFF || method == CV_TM_CCOEFF_NORMED ? 1 : 2;

View File

@ -706,6 +706,8 @@ private:
int thresholdType;
};
#ifdef HAVE_OPENCL
static bool ocl_threshold( InputArray _src, OutputArray _dst, double & thresh, double maxval, int thresh_type )
{
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type), ktype = CV_MAKE_TYPE(depth, 1);
@ -739,13 +741,14 @@ static bool ocl_threshold( InputArray _src, OutputArray _dst, double & thresh, d
return k.run(2, globalsize, NULL, false);
}
#endif
}
double cv::threshold( InputArray _src, OutputArray _dst, double thresh, double maxval, int type )
{
if (ocl::useOpenCL() && _src.dims() <= 2 && _dst.isUMat() &&
ocl_threshold(_src, _dst, thresh, maxval, type))
return thresh;
CV_OCL_RUN_(_src.dims() <= 2 && _dst.isUMat(),
ocl_threshold(_src, _dst, thresh, maxval, type), thresh)
Mat src = _src.getMat();
bool use_otsu = (type & THRESH_OTSU) != 0;