苦学Opencv的第十一天:图像的形态学操作

Python OpenCV从入门到精通学习日记:图像的形态学操作

前言

图像形态学是图像处理中的一个重要分支,主要关注图像中物体的形状和结构。通过形态学操作,我们可以对图像进行有效的分析和处理,例如图像的腐蚀与膨胀开运算与闭运算 等。腐蚀和膨胀是图像形态学中的两种核心操作,通过这两种操作可以清除或强化图像中的细节。合理使用腐蚀和膨胀,还可以实现图像开运算、闭运算、梯度运算、顶帽运算和黑帽运算等极具特点的操作。接下来开始学习吧!!!
图像形态学操作 腐蚀 膨胀 开运算 闭运算 其他形态学运算 梯度运算 顶帽运算 黑帽运算

因为内容较多,我列举了目录,如下:

图像的形态学操作

  • [Python OpenCV从入门到精通学习日记:图像的形态学操作](#Python OpenCV从入门到精通学习日记:图像的形态学操作)
  • 前言
  • [1 腐蚀](#1 腐蚀)
  • [2 膨胀](#2 膨胀)
  • [3 开运算](#3 开运算)
  • [4 闭运算](#4 闭运算)
  • [5 形态学运算](#5 形态学运算)
    • [5.1 梯度运算](#5.1 梯度运算)
    • [5.2 顶帽运算](#5.2 顶帽运算)
    • [5.3 黑帽运算](#5.3 黑帽运算)
  • 小结

1 腐蚀

腐蚀操作可以让图像沿着自己的边界向内收缩。OpenCV通过"核"来实现收缩计算。"核"的英文名为kernel,在形态学中可以理解为"由n个像素组成的像素块",像素块包含一个核心(核心通常在中央位置,也可以定义在其他位置)。像素块在图像的边缘移动,在移动过程中,核会将图像边缘那些与核重合但又没有越过核心的像素点都抹除,效果类似图12.1所示的过程,就像削土豆皮一样,将图像一层一层地"削薄"。(这里借用书上原图)

OpenCV将腐蚀操作封装成erode()方法。

复制代码
dst = cv2.erode(src, kernel, anchor, iterations,borderType, borderValue)

src: 输入图像。
kernel: 腐蚀使用的核,可以自定义或使用OpenCV提供的预设。
anchor:可选参数,核的锚点位置。
iterations: 腐蚀操作的迭代次数,默认为1。
borderType: 边界处理方式,默认为cv2.BORDER_CONSTANT。
borderValue: 边界值,默认为0。

图像经过腐蚀操作之后,可以抹除一些外部的细节,如图12.2所示是一个卡通小蜘蛛,如果用一个5×5的像素块作为核对小蜘蛛进行腐蚀操作,可以得到如图12.3所示的结果。小蜘蛛的腿被当成外部细节抹除了,同时小蜘蛛的眼睛变大了,因为核从内部也"削"了一圈。

在OpenCV做腐蚀或其他形态学操作时,通常使用numpy模块来创建核数组。

比如:

复制代码
 import numpy as np
 k = np.ones((5, 5), np.uint8)

这两行代码什么意思可以去看我前面的文章:链接: 苦学Opencv的第三天:像素的操作

这个数组作为erode()方法的核参数。除了5×5的结构,还可以使用3×3、9×9、11×11等结构,行列数越大,计算出的效果就越粗糙,行列数越小,计算出的效果就越精细。

代码示例:

python 复制代码
import cv2
import numpy as np

# 读取图像
img = cv2.imread('image.png', 0)

# 创建结构元素
kernel = np.ones((3,3), np.uint8)

# 腐蚀操作
eroded_img = cv2.erode(img, kernel)

# 显示结果
cv2.imshow('Eroded Image', eroded_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果如下:

🌟可以看出,仙人掌的刺并没有因此消失,但是刺明显变得模糊不清了。

2 膨胀

膨胀操作与腐蚀操作正好相反,它通过使用核来"扩展"图像的边界。

OpenCV将膨胀操作封装成dilate()方法。

复制代码
dst = cv2.dilate(src, kernel, anchor, iterations,borderType, borderValue)

参数说明:
 src:原始图像。
 kernel:膨胀使用的核。
 anchor:可选参数,核的锚点位置。
 iterations:可选参数,腐蚀操作的迭代次数,默认值为1。
 borderType:可选参数,边界样式,建议默认。
 borderValue:可选参数,边界值,建议默认。
返回值说明:
 dst:经过膨胀之后的图像。

膨胀的效果也正好是与腐蚀相反。这里不多加介绍了,直接放个图像,大家就知道什么意思了。

代码示例:

python 复制代码
# 膨胀操作
import cv2
import numpy as np

# 读取图像
img = cv2.imread('xianrenzhang.png')
cv2.imshow("img",img)
# 创建结构元素
kernel = np.ones((10,10), np.uint8)

# 腐蚀操作
dilated_img = cv2.dilate(img, kernel)

# 显示结果
cv2.imshow('Dilated Image', dilated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果如下:

🌟这里可以看出,过度膨胀后的图像就好像近视眼的世界,图像变得非常模糊。

3 开运算

开运算是先进行腐蚀操作,再进行膨胀操作,开运算可以用来抹除图像外部的细节(或者噪声)。

我们举个例子,这是一个二叉树:

我们先对齐进行腐蚀操作,那么连接的细线会因为腐蚀而消失

随后我们进行膨胀操作

🌟从结果中可以明显地看出:经过开运算之后,二叉树中的连接线消失了,只剩下光秃秃的节点。因为连接线被核当成"细节"抹除了,所以利用检测轮廓的方法可以统计二叉树节点数量,也就是说在某些情况下,开运算的结果还可以用来做数量统计。

4 闭运算

闭运算是先进行膨胀操作,再进行腐蚀操作,闭运算可以抹除图像内部的细节(或者噪声)。

闭运算正好与开运算相反。我们在这举个例子:假设有只身上有斑点的小蜘蛛

我们先对其膨胀

在进行腐蚀

🌟从结果中可以明显地看出:经过闭运算后,小蜘蛛身上的花纹都被抹除了,就连眼睛也被当成"细节"抹除了。闭运算除了会抹除图像内部的细节,还会让一些离得较近的区域合并成一块区域。

5 形态学运算

除了基本的腐蚀和膨胀操作,OpenCV还提供了梯度运算、顶帽运算和黑帽运算等高级形态学操作。OpenCV 提 供 了 一 个morphologyEx()形态学方法,包含所有常用的运算,其语法如下:

复制代码
dst = cv2.morphologyEx(src, op, kernel, anchor,iterations, borderType, borderValue)

参数说明:
 src:原始图像。
 op:操作类型,具体值如表所示。
 kernel:操作过程中使用的核。
 anchor:可选参数,核的锚点位置。
 iterations:可选参数,迭代次数,默认值为1。
 borderType:可选参数,边界样式,建议默认。
 borderValue:可选参数,边界值,建议默认。
返回值说明:
 dst:操作之后得到的图像。
参数值 含义
CV2.MORPH_ERODE 腐蚀操作
CV2.MORPHDILATE 膨胀操作
CV2.MORPH_OPEN 开运算,先腐蚀后膨胀
CV2.MORPHCLOSE 闭运算,先胀后腐蚀
CV2.MORPH_GRADIENT 梯度运算,膨胀图减腐蚀图
CV2.MORPHTOPHAT 顶幅运算,原始图减开运算图
CV2.MORPHBLACKHAT 黑幅运算,闭运算图减原始图

morphologyEx()方法实现的腐蚀、膨胀、开运算和闭运算效果与前文中介绍的效果完全一致,这里不再赘述,下面我们学习3个特点鲜明的操作:梯度运算、顶帽运算和黑帽运算。

5.1 梯度运算

这里的梯度是指图像梯度,可以简单地理解为像素的变化程度。如果几个连续的像素,其像素值跨度越大,则梯度值越大。

梯度运算是通过膨胀图像减去原始图像来突出显示图像的边缘。

通俗的讲,梯度运算的运算过程就是:让原图的膨胀图减去腐蚀图,因为膨胀图比原图大,腐蚀图比原图小,利用腐蚀图将膨胀图掏空,就得到了原图的轮廓图。当然,这只能等到一个大概的轮廓图,是不精准的。

具体的代码只是在前面的代码中修改函数为morphology(),在这里不再赘述。

5.2 顶帽运算

顶帽运算是原始图像减去开运算后的图像,用于提取图像的外部细节。

5.3 黑帽运算

黑帽运算是闭运算后的图像减去原始图像,用于提取图像的内部细节。

代码示例:

python 复制代码
# 梯度运算
gradient_img = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

# 顶帽运算
tophat_img = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

# 黑帽运算
blackhat_img = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

# 显示结果
cv2.imshow('Gradient Image', gradient_img)
cv2.imshow('Top Hat Image', tophat_img)
cv2.imshow('Black Hat Image', blackhat_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

小结

通过今天的学习,我们掌握了图像形态学的基本操作,这些操作对于图像分析和特征提取非常有用。明天继续学习图形检测!!!

大家在实践中遇到任何问题,欢迎在评论区讨论交流。明天见!

相关推荐
Mintopia2 小时前
OpenClaw 对软件行业产生的影响
人工智能
陈广亮2 小时前
构建具有长期记忆的 AI Agent:从设计模式到生产实践
人工智能
会写代码的柯基犬2 小时前
DeepSeek vs Kimi vs Qwen —— AI 生成俄罗斯方块代码效果横评
人工智能·llm
Mintopia3 小时前
OpenClaw 是什么?为什么节后热度如此之高?
人工智能
爱可生开源社区3 小时前
DBA 的未来?八位行业先锋的年度圆桌讨论
人工智能·dba
叁两6 小时前
用opencode打造全自动公众号写作流水线,AI 代笔太香了!
前端·人工智能·agent
前端付豪6 小时前
LangChain记忆:通过Memory记住上次的对话细节
人工智能·python·langchain
strayCat232556 小时前
Clawdbot 源码解读 7: 扩展机制
人工智能·开源
王鑫星6 小时前
SWE-bench 首次突破 80%:Claude Opus 4.5 发布,Anthropic 的野心不止于写代码
人工智能