ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OpenCV 计算机视觉:图像膨胀与腐蚀,图像边缘检测

OpenCV 计算机视觉:图像膨胀与腐蚀,图像边缘检测 OpenCV 入门图像形态学与边缘检测今天的课程主要学习了图像形态学和边缘检测。图像形态学主要处理物体的形状和结构例如去除噪声、填补空洞、连接断裂区域边缘检测则用于寻找图像中灰度变化明显的位置帮助我们提取物体轮廓。这两类操作是计算机视觉中非常重要的基础知识后续的轮廓检测、目标识别和图像分割都可能用到它们。一、什么是图像形态学图像形态学是一类基于图像形状的处理方法通常需要使用一个小矩阵扫描图像。这个小矩阵叫作结构元素也可以理解为形态学运算中的kernel。例如import numpy as np kernel np.ones( (3, 3), np.uint8 )这里创建了一个3×3的结构元素1 1 1 1 1 1 1 1 1结构元素的大小和形状会影响处理结果结构元素越大处理效果通常越明显迭代次数越多腐蚀或膨胀程度越明显不同形状的结构元素可能得到不同结果。常见的形态学操作包括腐蚀膨胀开运算闭运算形态学梯度顶帽黑帽。二、图像腐蚀腐蚀可以理解为让前景区域变小或者让白色物体的边界向内收缩。使用cv2.erode()import cv2 import numpy as np image cv2.imread( sun.png, cv2.IMREAD_GRAYSCALE ) kernel np.ones( (3, 3), np.uint8 ) erosion cv2.erode( image, kernel, iterations1 ) cv2.imshow(original, image) cv2.imshow(erosion, erosion) cv2.waitKey(0) cv2.destroyAllWindows()iterations表示腐蚀执行的次数erosion_1 cv2.erode( image, kernel, iterations1 ) erosion_3 cv2.erode( image, kernel, iterations3 )通常来说迭代次数越多白色区域被削弱得越明显。腐蚀可以用于去除小的白色噪声断开粘连的物体缩小目标轮廓去除细小的突出部分。需要注意腐蚀的效果与前景颜色有关。通常在二值图中把白色区域作为前景、黑色区域作为背景。三、图像膨胀膨胀与腐蚀相反它会让前景区域变大让白色物体的边界向外扩张。使用cv2.dilate()dilation cv2.dilate( image, kernel, iterations1 ) cv2.imshow(dilation, dilation) cv2.waitKey(0) cv2.destroyAllWindows()膨胀可以用于填补物体中的小空洞连接相互接近的区域加粗文字和线条修复断裂的边缘。例如文字图像中某些笔画断开了可以使用膨胀将它们连接起来text cv2.imread( wenzi.png, cv2.IMREAD_GRAYSCALE ) kernel np.ones( (2, 2), np.uint8 ) text_dilation cv2.dilate( text, kernel, iterations2 )腐蚀和膨胀并不是简单地把所有像素变黑或变白而是根据结构元素覆盖范围内的像素关系决定当前像素的结果。四、开运算开运算是先腐蚀再膨胀OpenCV 中使用opening cv2.morphologyEx( image, cv2.MORPH_OPEN, kernel )代码如下opening cv2.morphologyEx( image, cv2.MORPH_OPEN, kernel, iterations1 )开运算的主要作用是去除小的白色噪声平滑物体轮廓断开较窄的连接去除细小的突出部分。例如二值图像中存在很多零散的小白点可以先使用开运算进行清理。开运算先腐蚀会去除小区域再进行膨胀使主要目标大致恢复原来的大小。因此开运算相比单独腐蚀更加温和。五、闭运算闭运算是先膨胀再腐蚀使用closing cv2.morphologyEx( image, cv2.MORPH_CLOSE, kernel )闭运算的主要作用是填补目标内部的小孔洞连接较窄的断裂区域弥合轮廓中的细小间隙让目标轮廓更加完整。例如在指纹、文字或物体轮廓图中如果线条中间出现断裂可以使用闭运算进行修复fingerprint cv2.imread( zhiwen_duan.png, cv2.IMREAD_GRAYSCALE ) closing cv2.morphologyEx( fingerprint, cv2.MORPH_CLOSE, kernel )开运算更擅长“去除小的白色区域”闭运算更擅长“填补小的黑色区域”。实际选择哪一种需要观察噪声和目标的具体情况。六、顶帽和黑帽顶帽运算的公式是顶帽 原始图像 - 开运算结果使用tophat cv2.morphologyEx( image, cv2.MORPH_TOPHAT, kernel )顶帽可以提取比周围区域更亮的细节。例如在不均匀背景中提取明亮的小目标。黑帽运算的公式是黑帽 闭运算结果 - 原始图像使用blackhat cv2.morphologyEx( image, cv2.MORPH_BLACKHAT, kernel )黑帽可以提取比周围区域更暗的细节。简单理解顶帽突出亮目标黑帽突出暗目标开运算去除小亮区域闭运算填补小暗区域。七、什么是边缘检测边缘通常出现在图像亮度变化剧烈的位置例如黑白物体的交界处物体与背景的边界文字轮廓边缘检测的本质是计算图像像素值变化的速度。像素变化越剧烈越可能是边缘。边缘检测常用于提取物体轮廓目标检测形状识别文字识别图像分割。常见方法包括Sobel 算子Scharr 算子Laplacian 算子Canny 算法。八、Sobel 算子Sobel 算子会分别计算水平方向和垂直方向的像素变化。基本格式cv2.Sobel( src, ddepth, dx, dy, ksize3 )其中src输入图像ddepth输出图像的数据深度dxx 方向导数的阶数dyy 方向导数的阶数ksize算子大小常见为 3、5、7。读取灰度图gray cv2.imread( yuan.png, cv2.IMREAD_GRAYSCALE )计算 x 方向边缘sobel_x cv2.Sobel( gray, cv2.CV_64F, dx1, dy0 )计算 y 方向边缘sobel_y cv2.Sobel( gray, cv2.CV_64F, dx0, dy1 )最后需要将结果转换为可以显示的 8 位图像sobel_x cv2.convertScaleAbs( sobel_x ) sobel_y cv2.convertScaleAbs( sobel_y )也可以将两个方向的结果加权组合sobel_xy cv2.addWeighted( sobel_x, 1, sobel_y, 1, 0 )九、为什么使用 CV_64F图像像素通常是uint8取值范围是 0255。但 Sobel 计算的是像素变化结果可能出现负数。如果直接使用cv2.Sobel( gray, -1, 1, 0 )负数可能因为数据类型限制无法正常保存导致部分边缘信息丢失。因此课程代码中使用cv2.CV_64F让结果可以保存负数sobel_x_64 cv2.Sobel( gray, cv2.CV_64F, 1, 0 )然后通过convertScaleAbs()取绝对值并转换为适合显示的格式sobel_x cv2.convertScaleAbs( sobel_x_64 )这是使用 Sobel 时非常容易忽略的细节。十、Scharr 算子Scharr 算子可以看作 Sobel 算子在3×3核大小下的优化版本。使用方法scharr_x cv2.Scharr( gray, cv2.CV_64F, dx1, dy0 ) scharr_y cv2.Scharr( gray, cv2.CV_64F, dx0, dy1 ) scharr_x cv2.convertScaleAbs( scharr_x ) scharr_y cv2.convertScaleAbs( scharr_y )Scharr 在处理细小边缘时通常比3×3的 Sobel 更准确速度与 Sobel 接近。简单对比Sobel使用灵活可以选择不同大小的算子Scharr主要用于3×3情况边缘精度通常更高两者都可以计算 x 方向和 y 方向的梯度。十一、Laplacian 算子Sobel 和 Scharr 会分别计算 x、y 两个方向而 Laplacian 直接计算图像变化的二阶导数。使用laplacian cv2.Laplacian( gray, cv2.CV_64F, ksize3 ) laplacian cv2.convertScaleAbs( laplacian )Laplacian 不需要分别设置dx和dy因为它会综合各个方向的变化。它对噪声比较敏感因此实际使用中通常先进行高斯滤波blurred cv2.GaussianBlur( gray, (3, 3), 0 ) laplacian cv2.Laplacian( blurred, cv2.CV_64F )十二、Canny 边缘检测Canny 是一种效果较好的边缘检测算法edges cv2.Canny( gray, 100, 150 )其中100是低阈值150是高阈值。Canny 通常包括四个主要步骤1. 图像降噪先使用高斯滤波去除噪声防止噪声被误认为边缘。2. 梯度计算通常使用 Sobel 算子计算像素变化的大小和方向。3. 非极大值抑制一条边缘可能比较粗需要保留梯度方向上的最大值把其他非最大值抑制为 0从而得到更细的边缘。4. 双阈值边界跟踪Canny 使用高阈值和低阈值对边缘进行筛选高于高阈值强边缘直接保留低于低阈值不是边缘直接删除位于两个阈值之间根据是否连接到强边缘决定是否保留。完整示例import cv2 image cv2.imread( zl.png ) gray cv2.cvtColor( image, cv2.COLOR_BGR2GRAY ) blurred cv2.GaussianBlur( gray, (5, 5), 0 ) edges cv2.Canny( blurred, 100, 150 ) cv2.imshow(gray, gray) cv2.imshow(edges, edges) cv2.waitKey(0) cv2.destroyAllWindows()如果阈值过低噪声和无关细节会被检测出来如果阈值过高一些真实边缘可能被忽略。因此阈值需要根据图像实际情况调整。十三、形态学和边缘检测的综合流程实际项目中通常不会只使用一个函数而是将多个处理步骤组合起来读取图像 ↓ 转换为灰度图 ↓ 高斯滤波降噪 ↓ Canny边缘检测 ↓ 形态学膨胀或闭运算 ↓ 提取完整目标边缘对应代码如下import cv2 import numpy as np image cv2.imread( zl.png ) gray cv2.cvtColor( image, cv2.COLOR_BGR2GRAY ) blurred cv2.GaussianBlur( gray, (5, 5), 0 ) edges cv2.Canny( blurred, 80, 150 ) kernel np.ones( (3, 3), np.uint8 ) edges_closed cv2.morphologyEx( edges, cv2.MORPH_CLOSE, kernel ) cv2.imshow(original, image) cv2.imshow(edges, edges) cv2.imshow(closed edges, edges_closed) cv2.waitKey(0) cv2.destroyAllWindows()这种流程可以用于提取物体轮廓、检测文字边缘和分析简单形状。十四、总结今天的课程主要学习了图像形态学和边缘检测。形态学操作依赖结构元素kernel。腐蚀会缩小前景区域膨胀会扩大前景区域。开运算是先腐蚀后膨胀适合去除小噪声闭运算是先膨胀后腐蚀适合填补空洞和连接断裂区域。形态学梯度可以突出轮廓顶帽用于提取亮细节黑帽用于提取暗细节。边缘检测则是寻找像素变化剧烈的位置。Sobel 分别计算 x、y 方向的梯度Scharr 是 Sobel 在3×3情况下的优化Laplacian 直接计算二阶变化Canny 则通过降噪、梯度计算、非极大值抑制和双阈值跟踪得到较细的边缘。图像处理通常不是一步完成的而是根据任务组合多个操作灰度化 → 滤波降噪 → 边缘检测 → 形态学修复掌握这些基础后就可以继续学习轮廓检测、目标定位、形状识别和图像分割。
返回列表