执行高级形态变换。函数 cv::morphologyEx 可以使用腐蚀和膨胀作为基本操作来执行高级形态变换。任何操作都可以就地完成。 在多通道图像的情况下,每个通道都是独立处理的。
支持的操作如下表
| Enumerator | |
|---|---|
| MORPH_ERODE Python: cv.MORPH_ERODE | ERODE 腐蚀 |
| MORPH_DILATE Python: cv.MORPH_DILATE | DILATE 膨胀 |
| MORPH_OPEN Python: cv.MORPH_OPEN | an opening operation 开运算 dst=open(src,element)=dilate(erode(src,element)) |
| MORPH_CLOSE Python: cv.MORPH_CLOSE | a closing operation 闭运算 dst=close(src,element)=erode(dilate(src,element)) |
| MORPH_GRADIENT Python: cv.MORPH_GRADIENT | a morphological gradient 形态学梯度 dst=morph_grad(src,element)=dilate(src,element)−erode(src,element) |
| MORPH_TOPHAT Python: cv.MORPH_TOPHAT | "top hat" 顶帽 dst=tophat(src,element)=src−open(src,element) |
| MORPH_BLACKHAT Python: cv.MORPH_BLACKHAT | "black hat" 黑帽 dst=blackhat(src,element)=close(src,element)−src |
| MORPH_HITMISS Python: cv.MORPH_HITMISS | "hit or miss" .- Only supported for CV_8UC1 binary images. A tutorial can be found in the documentation 击中击不中 |
cv::morphologyEx (InputArray src, OutputArray dst, int op, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar &borderValue=morphologyDefaultBorderValue())2、参数详解
| src | 源图像。 通道的数量可以是任意的。 深度应该是 CV_8U、CV_16U、CV_16S、CV_32F 或 CV_64F 之一。 |
| dst | 与源图像具有相同大小和类型的目标图像。 |
| op | 形态学操作的类型,请参阅 MorphTypes |
| kernel | 结构元素。 它可以使用 getStructuringElement 创建。 |
| anchor | 与内核的锚定位置。 负值表示锚点位于内核中心。 |
| iterations | 应用腐蚀和膨胀的次数。 |
| borderType | 像素外推法,请参阅 BorderTypes。 不支持 BORDER_WRAP。 |
| borderValue | 边界不变的情况下的边界值。 默认值具有特殊含义。 |
opencvmodulesimgprocsrcmorph.dispatch.cpp2、源码代码
void morphologyEx( InputArray _src, OutputArray _dst, int op,
InputArray _kernel, Point anchor, int iterations,
int borderType, const Scalar& borderValue )
{
CV_INSTRUMENT_REGION();
CV_Assert(!_src.empty());
Mat kernel = _kernel.getMat();
if (kernel.empty())
{
kernel = getStructuringElement(MORPH_RECT, Size(3,3), Point(1,1));
}
#ifdef HAVE_OPENCL
Size ksize = kernel.size();
anchor = normalizeAnchor(anchor, ksize);
CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2 && _src.channels() <= 4 &&
anchor.x == ksize.width >> 1 && anchor.y == ksize.height >> 1 &&
borderType == cv::BORDER_CONSTANT && borderValue == morphologyDefaultBorderValue(),
ocl_morphologyEx(_src, _dst, op, kernel, anchor, iterations, borderType, borderValue))
#endif
Mat src = _src.getMat(), temp;
_dst.create(src.size(), src.type());
Mat dst = _dst.getMat();
#if !IPP_DISABLE_MORPH_ADV
//CV_IPP_RUN_FAST(ipp_morphologyEx(op, src, dst, kernel, anchor, iterations, borderType, borderValue));
#endif
switch( op )
{
case MORPH_ERODE:
erode( src, dst, kernel, anchor, iterations, borderType, borderValue );
break;
case MORPH_DILATE:
dilate( src, dst, kernel, anchor, iterations, borderType, borderValue );
break;
case MORPH_OPEN:
erode( src, dst, kernel, anchor, iterations, borderType, borderValue );
dilate( dst, dst, kernel, anchor, iterations, borderType, borderValue );
break;
case MORPH_CLOSE:
dilate( src, dst, kernel, anchor, iterations, borderType, borderValue );
erode( dst, dst, kernel, anchor, iterations, borderType, borderValue );
break;
case MORPH_GRADIENT:
erode( src, temp, kernel, anchor, iterations, borderType, borderValue );
dilate( src, dst, kernel, anchor, iterations, borderType, borderValue );
dst -= temp;
break;
case MORPH_TOPHAT:
if( src.data != dst.data )
temp = dst;
erode( src, temp, kernel, anchor, iterations, borderType, borderValue );
dilate( temp, temp, kernel, anchor, iterations, borderType, borderValue );
dst = src - temp;
break;
case MORPH_BLACKHAT:
if( src.data != dst.data )
temp = dst;
dilate( src, temp, kernel, anchor, iterations, borderType, borderValue );
erode( temp, temp, kernel, anchor, iterations, borderType, borderValue );
dst = temp - src;
break;
case MORPH_HITMISS:
CV_Assert(src.type() == CV_8UC1);
if(countNonZero(kernel) <=0)
{
src.copyTo(dst);
break;
}
{
Mat k1, k2, e1, e2;
k1 = (kernel == 1);
k2 = (kernel == -1);
if (countNonZero(k1) <= 0)
e1 = Mat(src.size(), src.type(), Scalar(255));
else
erode(src, e1, k1, anchor, iterations, borderType, borderValue);
if (countNonZero(k2) <= 0)
e2 = Mat(src.size(), src.type(), Scalar(255));
else
{
Mat src_complement;
bitwise_not(src, src_complement);
erode(src_complement, e2, k2, anchor, iterations, borderType, borderValue);
}
dst = e1 & e2;
}
break;
default:
CV_Error( CV_StsBadArg, "unknown morphological operation" );
}
}
四、效果图像示例
数字图像处理 图像形态学处理_坐望云起的博客-CSDN博客_数字图像处理凸壳形态学一词通常表示生物学的一个分支,涉及动物和植物的形式和结构。 在这里在数学形态学的上下文中使用相同的词作为提取图像组件的工具,这些组件在区域形状的表示和描述中很有用,例如边界、骨架和凸包。 我们还对用于预处理或后处理的形态技术感兴趣,例如形态过滤、细化和修剪。形态学技术用称为结构元素的小形状或模板探测图像。https://blog.csdn.net/bashendixie5/article/details/108333356Opencv学习笔记 形态学重建(python)_坐望云起的博客-CSDN博客_形态学开重建在形态学梯度图像的基础上,利用形态学的开闭重建运算对梯度图像进行重建,在保留重要区域伦敦的同时去除细节和噪声。import numpy as npimport cv2 as cvfrom matplotlib import pyplot as pltimg = cv.imread("C:/Users/xiaomao/Desktop/test.jpg")# 二值化imgray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)imgray[imgray



