diff --git a/modules/imgproc/src/morph.cpp b/modules/imgproc/src/morph.cpp index 4cf0d01031..ac958fc691 100644 --- a/modules/imgproc/src/morph.cpp +++ b/modules/imgproc/src/morph.cpp @@ -1286,21 +1286,30 @@ static bool IPPMorphOp(int op, InputArray _src, OutputArray _dst, #ifdef HAVE_OPENCL -static bool ocl_morphology_op(InputArray _src, OutputArray _dst, InputArray _kernel, Size &ksize, const Point anchor, int iterations, int op) +static bool ocl_morphology_op(InputArray _src, OutputArray _dst, Mat kernel, + const Size & ksize, const Point & anchor, int iterations, int op) { + CV_Assert(op == MORPH_ERODE || op == MORPH_DILATE); + bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0; if (_src.depth() == CV_64F && !doubleSupport) return false; UMat kernel8U; - _kernel.getUMat().convertTo(kernel8U, CV_8U); - UMat kernel = kernel8U.reshape(1, 1); + kernel.convertTo(kernel8U, CV_8U); + kernel8U = kernel8U.reshape(1, 1); bool rectKernel = true; - for(int i = 0; i < kernel.rows * kernel.cols; ++i) - if(kernel.getMat(ACCESS_READ).at(i) != 1) - rectKernel = false; + { + Mat m = kernel.reshape(1, 1); + for (int i = 0; i < m.size().area(); ++i) + if (m.at(i) != 1) + { + rectKernel = false; + break; + } + } UMat src = _src.getUMat(); @@ -1311,19 +1320,19 @@ static bool ocl_morphology_op(InputArray _src, OutputArray _dst, InputArray _ker #endif size_t globalThreads[3] = {(src.cols + localThreads[0] - 1) / localThreads[0] *localThreads[0], (src.rows + localThreads[1] - 1) / localThreads[1] *localThreads[1], 1}; - if(localThreads[0]*localThreads[1] * 2 < (localThreads[0] + ksize.width - 1) * (localThreads[1] + ksize.height - 1)) + if (localThreads[0]*localThreads[1] * 2 < (localThreads[0] + ksize.width - 1) * (localThreads[1] + ksize.height - 1)) 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() ); + static const char * const op2str[] = { "ERODE", "DILATE" }; + String buildOptions = format("-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() ); std::vector kernels; - for(int i = 0; i= 7) if( IPPMorphOp(op, _src, _dst, kernel, anchor, iterations, borderType, borderValue) ) return; @@ -1443,7 +1450,7 @@ static void morphOp( int op, InputArray _src, OutputArray _dst, } 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.dims() <= 2 && (src_cn == 1 || src_cn == 4) && (src_depth == CV_8U || src_depth == CV_32F || src_depth == CV_64F ) && borderType == cv::BORDER_CONSTANT && borderValue == morphologyDefaultBorderValue() && (op == MORPH_ERODE || op == MORPH_DILATE),