目录
在开始本章学习前,可以复习以下上一章内容哦~
OpenCV未配置的小伙伴可以跳转下方博客。
零基础入门PyTorch手写数字识别实战教程(含PyTorch环境搭建)——CNN篇_阿里云 cu126-优快云博客
形态学概述——图像处理的"外科手术刀"
形态学处理(Morphological Operations) 是数字图像处理中的核心概念,其灵感来源于地质学中的结构分析。在OpenCV中,这类操作通过特定的**结构元素(Kernel)**对图像进行局部区域形态改造,如同使用精密的手术刀对图像特征进行"修剪"和"整形"。
核心价值
- 精准操控:通过腐蚀/膨胀等基础操作组合,实现去噪、分割、边缘提取等复杂任务
- 结构保持:在修改图像特征时保留主体几何形状(工业零件尺寸测量关键)
- 多场景适用:兼容二值图与灰度图,广泛用于医学影像分析、车牌识别、文档处理等领域
OpenCV实现特点
# 统一入口函数
cv2.morphologyEx() # 支持7种形态学变体
# 结构元素自由定制
cv2.getStructuringElement() # 可生成矩形/十字/椭圆等15种形态模板
典型应用场景
- 🏭 工业检测:清除PCB板图像中的划痕噪点
- 🩺 医疗影像:分离X光片中的骨骼与软组织
- 📸 智能摄影:修复老照片的断裂划痕
下文中,我们将从结构元素的选择技巧开始,逐步解剖每个形态学操作的数学原理与工程实践。
一、二维化
(一)原理
通过设定阈值将灰度图像转化为黑白图像,消除噪声干扰,突出目标区域形态特征。常用方法:全局阈值法、自适应阈值法。
参考一下这篇博客中二值化的说明:OpenCV threshold函数详解-优快云博客
由于这里是二值化处理灰度图片,所以一般使用参数:
或者
(二)API 及参数解析
cv2.threshold(src, thresh, maxval, type[, dst])
上方为全局二值化API
- thresh 设置的阈值
- type参数详解:cv2.THRESH_BINARY(标准二值化)、cv2.THRESH_OTSU(自动阈值)
cv2.adaptiveThreshold(img, maxVal, adaptiveMethod, type[, dst], blocksize, C)
上方为自适应二值化API
(三)代码示例
import cv2
import numpy as np
img = cv2.imread('./hand.png', 0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
ret,binary=cv2.threshold(img,0,255,cv2.THRESH_BINARY)
cv2.imshow('img', img)
cv2.imshow('binary', binary)
cv2.waitKey()
二、腐蚀(key)
(一)原理
通过结构元素扫描图像,用邻域内最小值替换锚点像素,消除细小物体
(二)API 及参数解析
cv2.erode(src, kernel[, dst[, anchor[, iterations[, borderType]]]])
# kernel设计技巧:矩形/十字/椭圆形结构元素的选择策略
# iterations参数实验建议:2-3次迭代效果最佳
(三)代码示例
import cv2
import numpy as np
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.namedWindow('dst1', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 640, 640)
cv2.resizeWindow('dst1', 640, 640)
img = cv2.imread('./j.png', 0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
ret,binary=cv2.threshold(img,0,255,cv2.THRESH_BINARY)
dst = cv2.erode(img, kernel, iterations=1)
cv2.imshow('img', img)
cv2.imshow('dst1', dst)
cv2.waitKey()
三、膨胀(key)
(一)原理
与腐蚀相反的操作,用邻域最大值替换锚点像素,修复断裂、填补孔洞
(二)API 及参数解析
cv2.dilate(src, kernel[, dst[, anchor[, iterations]]])
# 特殊结构元素应用:cv2.MORPH_ELLIPSE处理不规则边缘
(三)代码示例
import cv2
import numpy as np
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.namedWindow('dst1', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 640, 640)
cv2.resizeWindow('dst1', 640, 640)
img = cv2.imread('./j.png', 0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
ret,binary=cv2.threshold(img,0,255,cv2.THRESH_BINARY)
dst = cv2.dilate(binary, kernel, iterations=1)
cv2.imshow('img', img)
cv2.imshow('dst1', dst)
cv2.waitKey()
四、开运算
(一)原理
先腐蚀后膨胀,有效去除椒盐噪声同时保持主体形状(即去除外部噪点)
记忆联想:伤口先腐蚀再膨胀,表皮太薄炸开了
(二)API 及参数解析
cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)
(三)代码示例
import cv2
import numpy as np
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.namedWindow('dst1', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 640, 640)
cv2.resizeWindow('dst1', 640, 640)
img = cv2.imread('./dotj.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
ret,binary=cv2.threshold(img,0,255,cv2.THRESH_BINARY)
dst1 = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
cv2.imshow('img', img)
cv2.imshow('dst1', dst1)
cv2.waitKey()
五、闭运算
(一)原理
先膨胀后腐蚀,填充物体内部小孔,连接邻近物体(即去除内部噪点)
记忆联想:脓包先膨胀再腐蚀,会形成闭口伤疤
(二)API 及参数解析
cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel)
(三)代码示例
import cv2
import numpy as np
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.namedWindow('dst1', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 640, 640)
cv2.resizeWindow('dst1', 640, 640)
img = cv2.imread('./dotinj.png', 0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 9))
ret,binary=cv2.threshold(img,0,255,cv2.THRESH_BINARY)
dst1 = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
cv2.imshow('img', img)
cv2.imshow('dst1', dst1)
cv2.waitKey()
六、形态学梯度
(一)原理
膨胀图与腐蚀图的差异,类似图像边缘检测的"浮雕效果"(基本上只保留轮廓)
会不会有人联想到 Canny 呢~
(二)API 及参数解析
cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel)
(三)代码示例
import cv2
import numpy as np
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.namedWindow('dst1', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 640, 640)
cv2.resizeWindow('dst1', 640, 640)
img = cv2.imread('./dotinj.png', 0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
ret,binary=cv2.threshold(img,0,255,cv2.THRESH_BINARY)
dst1 = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
cv2.imshow('img', img)
cv2.imshow('dst1', dst1)
cv2.waitKey()
七、顶帽
(一)原理
工业应用:原始图像与开运算结果的差值,突出比背景亮的小物体(如PCB板检测)
说人话:保留外部噪点
(二)API 及参数解析
cv2.morphologyEx(src, cv2.MORPH_TOPHAT, kernel)
(三)代码示例
import cv2
import numpy as np
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.namedWindow('dst1', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 640, 640)
cv2.resizeWindow('dst1', 640, 640)
img = cv2.imread('./dotj.png')
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
ret,binary=cv2.threshold(img,0,255,cv2.THRESH_BINARY)
dst1 = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('img', img)
cv2.imshow('dst1', dst1)
cv2.waitKey()
八、黑帽
(一)原理
医疗影像应用
:闭运算结果与原始图像的差值,检测深色区域(如眼底血管分析)
说人话:保留内部噪点
(二)API 及参数解析
cv2.morphologyEx(src, cv2.MORPH_BLACKHAT, kernel)
(三)代码示例
import cv2
import numpy as np
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.namedWindow('dst1', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 640, 640)
cv2.resizeWindow('dst1', 640, 640)
img = cv2.imread('./dotinj.png', 0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
ret,binary=cv2.threshold(img,0,255,cv2.THRESH_BINARY)
dst1 = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('img', img)
cv2.imshow('dst1', dst1)
cv2.waitKey()
九、进阶应用
形态学重构(morphological reconstruction)
未完待续,持续更新中~
客官都看到这啦,真的不三连一下嘛~
您的支持就是我最大的动力!!!