|
|
|
@ -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<uchar>(i) != 1) |
|
|
|
|
rectKernel = false; |
|
|
|
|
{ |
|
|
|
|
Mat m = kernel.reshape(1, 1); |
|
|
|
|
for (int i = 0; i < m.size().area(); ++i) |
|
|
|
|
if (m.at<uchar>(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<ocl::Kernel> kernels; |
|
|
|
|
for(int i = 0; i<iterations; i++) |
|
|
|
|
for (int i = 0; i<iterations; i++) |
|
|
|
|
{ |
|
|
|
|
ocl::Kernel k( "morph", ocl::imgproc::morph_oclsrc, compile_option); |
|
|
|
|
ocl::Kernel k("morph", ocl::imgproc::morph_oclsrc, buildOptions); |
|
|
|
|
if (k.empty()) |
|
|
|
|
return false; |
|
|
|
|
kernels.push_back(k); |
|
|
|
@ -1346,7 +1355,7 @@ static bool ocl_morphology_op(InputArray _src, OutputArray _dst, InputArray _ker |
|
|
|
|
idxArg = kernels[0].set(idxArg, ofs.y); |
|
|
|
|
idxArg = kernels[0].set(idxArg, src.cols); |
|
|
|
|
idxArg = kernels[0].set(idxArg, src.rows); |
|
|
|
|
idxArg = kernels[0].set(idxArg, ocl::KernelArg::PtrReadOnly(kernel)); |
|
|
|
|
idxArg = kernels[0].set(idxArg, ocl::KernelArg::PtrReadOnly(kernel8U)); |
|
|
|
|
idxArg = kernels[0].set(idxArg, wholecols); |
|
|
|
|
idxArg = kernels[0].set(idxArg, wholerows); |
|
|
|
|
|
|
|
|
@ -1387,7 +1396,7 @@ static bool ocl_morphology_op(InputArray _src, OutputArray _dst, InputArray _ker |
|
|
|
|
idxArg = kernels[i].set(idxArg, ofs.y); |
|
|
|
|
idxArg = kernels[i].set(idxArg, source.cols); |
|
|
|
|
idxArg = kernels[i].set(idxArg, source.rows); |
|
|
|
|
idxArg = kernels[i].set(idxArg, ocl::KernelArg::PtrReadOnly(kernel)); |
|
|
|
|
idxArg = kernels[i].set(idxArg, ocl::KernelArg::PtrReadOnly(kernel8U)); |
|
|
|
|
idxArg = kernels[i].set(idxArg, wholecols); |
|
|
|
|
idxArg = kernels[i].set(idxArg, wholerows); |
|
|
|
|
|
|
|
|
@ -1413,8 +1422,6 @@ static void morphOp( int op, InputArray _src, OutputArray _dst, |
|
|
|
|
Size ksize = kernel.data ? kernel.size() : Size(3,3); |
|
|
|
|
anchor = normalizeAnchor(anchor, ksize); |
|
|
|
|
|
|
|
|
|
CV_Assert( anchor.inside(Rect(0, 0, ksize.width, ksize.height)) ); |
|
|
|
|
|
|
|
|
|
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 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), |
|
|
|
|