Opencv4 c++ 自用笔记 05 形态学操作

图像形态学主要获取物体的形状与位置信息。利用具有一定形态的结构元素度量和提取图像中的对应形状,达到对图像分析和识别的目的。操作主要包括腐蚀、膨胀、开运算和闭运算。

像素距离与连通域

图像形态学中,将不与其他区域链接的独立区域称为集合或者连通域,这个集合中的元素就是连通域中的每一个像素,像素之间的距离可以表示两个连通域之间的关系。

图像像素距离

两个像素之间的距离有多种定义。常见的有欧式距离、街区距离和棋盘距离。

欧式距离

指两个像素之间的直线距离,与坐标系中两点间的距离求取方式一致。
d=(x1−x2)2+(y1−y2)2 d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2} d=(x1x2)2+(y1y2)2

街区距离

指两个像素X差与Y差的和。欧式距离表示的是两点间最近距离,但有时我们并不能沿着直线行走,而是沿着一定的路径行走,如同城市街区一般。
d=∣x1−x2∣+∣y1−y2∣ d=|x_1-x_2|+|y_1-y_2| d=x1x2+y1y2

棋盘距离

又称切比雪夫距离(Chebyshev Distance),指两像素点在横坐标和纵坐标上差的绝对值中的较大者。这相当于棋盘上王从一个格子到另一个格子所需的最少步数。
d=max(∣x1−x2∣,∣y1−y2∣) d=max(|x_1-x_2|,|y_1-y_2|) d=max(x1x2,y1y2)
opencv中有计算不同距离的函数。

distanceTransform(src, dst, labels, distanceType, maskSize, labelType);

labels为二维标签数组,与输入图像有相同的尺寸,数据类型为CV_32S的单通道数据
distanceType为方法标志,-1 为自定义距离,1 为街区距离,2 为欧式距离,3 为棋盘距离
maskSize为距离变换掩码尺寸,可选 DIST_MASK_3(3×33\times33×3) 和 DIST_MASK_5(5×55\times55×5)
labelType为标签数组类型,0 表示同一连通区域的零像素及其最近的非零像素点赋予相同的标签,1 表示每个零像素及其最近的非零像素点都有其独特的标签

distanceTransform(src, dst, distanceType, maskSize, dstType);

这个原型不生成labels数组,占用资源小。
dstType决定了输出图像的类型,CV_8UCV_32F

图像连通域分析

图像的连通域指图像中具有相同像素值且位置相邻的像素组成的区域。为了避免像素值波动的影响,连通域分析处理的一般是二值化后的图像。

像素的邻域定义了其“相邻”关系,常见的有4-邻域(仅考虑上、下、左、右四个方向的像素)和8-邻域(额外包含对角线方向的四个像素)。

邻域分析主要有两遍扫描法和种子填充法。

函数如下:

connectedComponents(image, labels, connectivity, ltype, ccltype);

image为待标记图像,必须为CV_8U单通道二值图像
labels 输出的标记图像,其中每个连通域被赋予一个唯一的整数标签。
connectivity邻域种类,可选4(4-邻域)或8(8-邻域)
ltype为输出图像数据类型,可为CV_32SCV_16U
ccltype连通域标记算法类型,例如 cv::CCL_DEFAULTcv::CCL_WUcv::CCL_GRANA

简化原型:

connectedComponents(image, labels, connectivity=8, ltype=CV_32S);
connectedComponentsWithStats(image, labels, stats, centroids, connectivity, ltype, ccltype);
connectedComponentsWithStats(image, labels, stats, centroids, connectivity=8, ltype=CV_32S);

stats输出的统计信息矩阵。每一行对应一个连通域的统计数据(背景为第0行),列代表不同的统计属性
centroids为每个连通域质心的坐标,CV_64F
stats中包含的信息如下:

cv::CC_STAT_LEFT     // 0 连通域外包矩形最左侧像素的x坐标
cv::CC_STAT_TOP      // 1 连通域外包矩形最上方像素的y坐标
cv::CC_STAT_WIDTH    // 2 连通域外包矩形的水平长度
cv::CC_STAT_HEIGHT   // 3 连通域外包矩形的垂直长度
cv::CC_STAT_AREA     // 4 连通域的面积(以像素为单位)
// cv::CC_STAT_MAX      // 5 统计信息类型的总数,本身不代表具体统计值

腐蚀与膨胀

腐蚀与膨胀是形态学的基础操作,可用于去除图像噪声、分割独立的图像区域、连接邻近的区域等。

腐蚀

腐蚀与卷积相似,需要模板矩阵——结构元素。对于二值图像(通常前景为1或255,背景为0),腐蚀操作会检查结构元素是否能完全被图像中的前景像素区域所覆盖。若能,则结构元素中心(锚点)对应的像素在新图像中保持为前景;否则置为背景。其效果是“收缩”或“细化”图像中的前景区域,去除小的噪点和物体边界的一些像素。

getStructuringElement(shape, ksize, anchor = Point(-1, -1));

shape为生成的结构元素种类
ksize为结构元素大小
anchor为中心点的位置

这个函数可以生成矩形、十字、椭圆结构元素。只有十字结构元素的中心点位置会影响图像腐蚀后的轮廓形状,其他的只影响操作结果的平移量。

cv::MORPH_RECT     // 0 矩形结构元素
cv::MORPH_CROSS    // 1 十字结构元素
cv::MORPH_ELLIPSE  // 2 椭圆结构元素

图像腐蚀函数:

erode(src, dst, kernel, anchor=Point(-1, -1), iterations=1, borderType, borderValue);

kernel为结构元素
iterations为腐蚀次数,次数越多效果越明显
borderValue为使用边界不变外推法时的边界值

此函数执行图像腐蚀。对于多通道图像,每个通道将独立进行腐蚀。在二值图像中,腐蚀会使前景物体“收缩”或“变细”。

膨胀

图像膨胀通常被认为是腐蚀的对偶运算。对于二值图像,如果结构元素的锚点对应于输入图像的某个位置,且结构元素覆盖的区域内至少有一个前景像素与输入图像的前景像素重叠,则输出图像中该锚点对应的像素被置为前景。其效果是“扩张”或“加粗”图像中的前景区域,填充小的空洞或连接断裂部分。

dilate(src, dst, kernel, anchor, iterations, borderType, borderValue);

对于多通道图像,各通道独立膨胀。在二值图像中,膨胀会使前景物体“扩张”或“变粗”。

膨胀只针对非0像素。

运算组合

针对不同的图像处理需求,OpenCV 提供了腐蚀与膨胀运算的不同组合形式,封装在 morphologyEx 函数中。

morphologyEx(src, dst, op, kernel, anshor, iterations, bord

op为形态学操作类型标志。

cv::MORPH_ERODE      // 0 腐蚀
cv::MORPH_DILATE     // 1 膨胀
cv::MORPH_OPEN       // 2 开运算
cv::MORPH_CLOSE      // 3 闭运算
cv::MORPH_GRADIENT   // 4 形态学梯度
cv::MORPH_TOPHAT     // 5 顶帽运算
cv::MORPH_BLACKHAT   // 6 黑帽运算
cv::MORPH_HITMISS    // 7 击中击不中变换
开运算

开运算可以去除图像噪声,消除较小连通域,保留较大连通域,同时在两个物体纤细连接处分离,且能在不明显改变较大连通域面积的同时平滑连通域的边界。

开运算先对图像进行腐蚀,随后膨胀,使用相同的结构元素。

Opening(A,B)=(A⊖B)⊕B Opening(A,B)=(A\ominus B)\oplus B Opening(A,B)=(AB)B
其中AAA是图像,BBB是结构元素,⊖\ominus代表腐蚀,⊕\oplus代表膨胀。

闭运算

闭运算常用于填充前景对象内部的小空洞,连接邻近的对象,以及平滑对象的轮廓(特别是填充轮廓的凹陷部分)。

闭运算先进行膨胀,再进行腐蚀。
Closing(A,B)=(A⊕B)⊖B Closing(A,B)=(A\oplus B)\ominus B Closing(A,B)=(AB)B
其中AAA是图像,BBB是结构元素,⊖\ominus代表腐蚀,⊕\oplus代表膨胀。

形态学梯度

形态学梯度(cv::MORPH_GRADIENT)用于突出对象的边缘。标准的形态学梯度是图像膨胀的结果与图像腐蚀的结果之差。梯度分为基本梯度、内部梯度、外部梯度。

基本梯度指图像膨胀后和腐蚀后的差值图像
Gradient(A,B)=(A⊕B)−(A⊖B) Gradient(A,B)=(A\oplus B)-(A\ominus B) Gradient(A,B)=(AB)(AB)

内部梯度指原图像与腐蚀后图像间的差值
Gradient(A,B)=A−(A⊖B) Gradient(A,B)=A-(A\ominus B) Gradient(A,B)=A(AB)

外部梯度指膨胀后图像与原图像间的差值。
Gradient(A,B)=(A⊕B)−A Gradient(A,B)=(A\oplus B)-A Gradient(A,B)=(AB)A

内部梯度与外部梯度需自己实现。

顶帽运算

顶帽运算(cv::MORPH_TOPHAT)是原图像与其开运算结果之间的差值。它常用于提取图像中相对于其周围环境更亮的细小区域或斑点,这些区域通常在开运算中被移除。
TopHat(A,B)=A−Opening(A,B) TopHat(A,B)=A−Opening(A,B) TopHat(A,B)=AOpening(A,B)

黑帽运算

黑帽运算(cv::MORPH_BLACKHAT)是图像的闭运算结果与原图像之间的差值。它用于提取图像中相对于其周围环境更暗的细小区域或斑点。
BlackHat(A,B)=Closing(A,B)−A BlackHat(A,B)=Closing(A,B)−A BlackHat(A,B)=Closing(A,B)A

击中击不中变换

击中击不中变换(cv::MORPH_HITMISS)是一种用于查找特定像素模式的运算。

它使用一个特殊的结构元素,该结构元素不仅定义了需要匹配的前景(“击中”部分,通常标记为1),也定义了必须为背景的区域(“击不中”部分,通常标记为-1),其他部分为“不关心”(标记为0)。

只有当图像中的某个区域与结构元素的前景部分完全匹配,并且与背景部分也完全匹配时,输出图像中对应锚点位置的像素才会被标记。这是一种比简单腐蚀更精确的模式匹配方法,常用于查找角点、孤立点等特定配置。

在使用矩形结构元素时,结果与腐蚀相同。

图像细化

细化指从多像素宽度减少到单位像素宽度的过程,又称“骨架化”或“中轴变换”。图像细化常用于文字识别。图像细化一般要求保证细化后骨架的连通性、对原图像的细节特征有较好保留、线条的端点保留完好、线条交叉点不能发生畸变。主要应用于由线条形状构成的物体。

细化算法分为迭代细化和非迭代细化。迭代细化中,又可分为串行细化和并行细化。

opencv中提供了如下函数:

thinning(src, dst, thinningType=THINNING_ZHANGSUEN);

src必须为CV_8UC1
thinningType为细化算法选择标志

0	THINNING_ZHANGSUEN	
1	THINNING_GUOHALL	复杂场景效果更好

需确保已链接 opencv_ximgproc 模块,并通过 cv::ximgproc:: 命名空间调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值