diff --git a/modules/core/include/opencv2/core/opencl/ocl_defs.hpp b/modules/core/include/opencv2/core/opencl/ocl_defs.hpp index 7a8aed4b88..1c5ca58c18 100644 --- a/modules/core/include/opencv2/core/opencl/ocl_defs.hpp +++ b/modules/core/include/opencv2/core/opencl/ocl_defs.hpp @@ -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) diff --git a/modules/imgproc/src/blend.cpp b/modules/imgproc/src/blend.cpp index 91b261dfa6..4fbdff9c3d 100644 --- a/modules/imgproc/src/blend.cpp +++ b/modules/imgproc/src/blend.cpp @@ -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(); diff --git a/modules/imgproc/src/canny.cpp b/modules/imgproc/src/canny.cpp index b52ca46de9..990074d496 100644 --- a/modules/imgproc/src/canny.cpp +++ b/modules/imgproc/src/canny.cpp @@ -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(); diff --git a/modules/imgproc/src/clahe.cpp b/modules/imgproc/src/clahe.cpp index 82474788d5..138bf83b55 100644 --- a/modules/imgproc/src/clahe.cpp +++ b/modules/imgproc/src/clahe.cpp @@ -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 } } diff --git a/modules/imgproc/src/color.cpp b/modules/imgproc/src/color.cpp index e698690abe..8d06c46c57 100644 --- a/modules/imgproc/src/color.cpp +++ b/modules/imgproc/src/color.cpp @@ -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(); diff --git a/modules/imgproc/src/corner.cpp b/modules/imgproc/src/corner.cpp index fe76481911..172a531a3b 100644 --- a/modules/imgproc/src/corner.cpp +++ b/modules/imgproc/src/corner.cpp @@ -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 ); diff --git a/modules/imgproc/src/featureselect.cpp b/modules/imgproc/src/featureselect.cpp index c8b65b1efa..ff923a3e93 100644 --- a/modules/imgproc/src/featureselect.cpp +++ b/modules/imgproc/src/featureselect.cpp @@ -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 ) diff --git a/modules/imgproc/src/filter.cpp b/modules/imgproc/src/filter.cpp index a94d99a3bf..8c11c62dba 100644 --- a/modules/imgproc/src/filter.cpp +++ b/modules/imgproc/src/filter.cpp @@ -3115,10 +3115,7 @@ template 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::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(); diff --git a/modules/imgproc/src/histogram.cpp b/modules/imgproc/src/histogram.cpp index 71127b6385..0533bbba2c 100644 --- a/modules/imgproc/src/histogram.cpp +++ b/modules/imgproc/src/histogram.cpp @@ -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 ch const std::vector& ranges, float scale, size_t histdims ) { - const std::vector & images = *(const std::vector *)_images.getObj(); + std::vector 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 ch } +#endif + void cv::calcBackProject( InputArrayOfArrays images, const std::vector& channels, InputArray hist, OutputArray dst, const std::vector& 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() ); diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index e9fd60d5d3..af961ee5b1 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -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() ); diff --git a/modules/imgproc/src/moments.cpp b/modules/imgproc/src/moments.cpp index f1954cfe33..98c542b208 100644 --- a/modules/imgproc/src/moments.cpp +++ b/modules/imgproc/src/moments.cpp @@ -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)) diff --git a/modules/imgproc/src/morph.cpp b/modules/imgproc/src/morph.cpp index 7ade970d95..4cf0d01031 100644 --- a/modules/imgproc/src/morph.cpp +++ b/modules/imgproc/src/morph.cpp @@ -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(); diff --git a/modules/imgproc/src/pyramids.cpp b/modules/imgproc/src/pyramids.cpp index 6802e9eebf..a50e10680c 100644 --- a/modules/imgproc/src/pyramids.cpp +++ b/modules/imgproc/src/pyramids.cpp @@ -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; diff --git a/modules/imgproc/src/smooth.cpp b/modules/imgproc/src/smooth.cpp index bc621be3b4..e5c0cde28e 100644 --- a/modules/imgproc/src/smooth.cpp +++ b/modules/imgproc/src/smooth.cpp @@ -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(); diff --git a/modules/imgproc/src/sumpixels.cpp b/modules/imgproc/src/sumpixels.cpp index c6ce0f2969..4e18f119fa 100644 --- a/modules/imgproc/src/sumpixels.cpp +++ b/modules/imgproc/src/sumpixels.cpp @@ -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, >2, <2, 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) ); diff --git a/modules/imgproc/src/templmatch.cpp b/modules/imgproc/src/templmatch.cpp index 9953c6851c..0242068eef 100644 --- a/modules/imgproc/src/templmatch.cpp +++ b/modules/imgproc/src/templmatch.cpp @@ -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; diff --git a/modules/imgproc/src/thresh.cpp b/modules/imgproc/src/thresh.cpp index ce853a783e..fc0f6f9e95 100644 --- a/modules/imgproc/src/thresh.cpp +++ b/modules/imgproc/src/thresh.cpp @@ -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;