拓冰建站拓冰建站
首页 / 资讯中心 / 正文

【计算机视觉入门】—— OpenCV图像处理基础(图像形态学与边缘检测)

文章目录前言一、图像形态学Morphology1.1 什么是图像形态学1.2 结构元素 Kernel1.3 腐蚀Erode1.4 膨胀Dilate1.5 开运算MORPH_OPEN 腐蚀 膨胀1.6 闭运算MORPH_CLOSE 膨胀 腐蚀1.7 梯度运算MORPH_GRADIENT 膨胀 - 腐蚀1.8 顶帽TOPHAT与黑帽BLACKHAT二、边缘检测Edge Detection2.1 什么是边缘2.2 Sobel算子2.3 Scharr 算子2.4 Laplacian 算子2.5 Canny 最优边缘检测2.6 四种边缘检测效果展示2.7 四种边缘检测算子对比总结总结前言一、图像形态学Morphology1.1 什么是图像形态学图像形态学是一种基于图像形状进行处理的方法。主要研究如何利用结构元素(kernel)对图像中的形状进行改变。常用于去除噪声填充空洞提取边缘连接断裂区域OpenCV中的主要形态学操作操作作用腐蚀缩小目标区域膨胀扩大目标区域开运算去除噪声闭运算填充孔洞梯度提取边缘顶帽提取亮区域黑帽提取暗区域1.2 结构元素 Kernel形态学操作依赖一个结构元素Kernel在图像上滑动扫描。例如kernelnp.ones((3,3),np.uint8)表示3×3大小的矩阵。注意Kernel 大小直接影响处理强度——越大腐蚀 / 膨胀越剧烈细节保留越少。1.3 腐蚀Erode原理腐蚀Erosion让图像中的白色区域变小。简单理解如果一个像素周围存在黑色像素那么该像素可能被腐蚀掉。作用去除小噪声、消除细小连接函数cv2.erode( src, kernel, iterations )参数含义src 输入图像kernel 结构元素iterations 腐蚀次数代码示例importcv2importnumpyasnp# 读取图像imgcv2.imread(img.png)ifimgisNone:print(错误未找到图像文件)exit()kernelnp.ones((3,3),np.uint8)erosioncv2.erode(img,kernel,iterations2)cv2.imshow(original,img)cv2.imshow(erosion,erosion)cv2.waitKey(0)cv2.destroyAllWindows()腐蚀效果1.4 膨胀Dilate原理与腐蚀相反核覆盖区域任意一个白色像素中心像素就置白。效果扩大白色区域、填充孔洞、连接断裂线条。函数cv2.dilate( src , kernel, iterations )代码示例importcv2importnumpyasnp wordscv2.imread(words.png)ifwordsisNone:print(未找到 words.png)exit()kernelnp.ones((2,2),np.uint8)dilatedcv2.dilate(words,kernel,iterations2)cv2.imshow(original,words)cv2.imshow(dilated,dilated)cv2.waitKey(0)cv2.destroyAllWindows()膨胀效果1.5 开运算MORPH_OPEN 腐蚀 膨胀作用消除白色细小噪点、断开细粘连保留物体整体大小。常用于指纹、文字去噪。代码示例importcv2importnumpyasnp fingerprintcv2.imread(fingerprint_noise.png)iffingerprintisNone:exit()kernelnp.ones((3,3),np.uint8)fingerprint_01cv2.morphologyEx(fingerprint,cv2.MORPH_OPEN,kernel)cv2.imshow(original,fingerprint)cv2.imshow(MORPH_OPEN,fingerprint_01)cv2.waitKey(0)cv2.destroyAllWindows()开运算效果1.6 闭运算MORPH_CLOSE 膨胀 腐蚀作用填充前景内部小黑孔洞、弥合细小缝隙。代码示例importcv2importnumpyasnp fingerprintcv2.imread(fingerprint.png)iffingerprintisNone:exit()kernelnp.ones((4,4),np.uint8)fingerprint_closedcv2.morphologyEx(fingerprint,cv2.MORPH_CLOSE,kernel)cv2.imshow(original,fingerprint)cv2.imshow(MORPH_CLOSE,fingerprint_closed)cv2.waitKey(0)cv2.destroyAllWindows()闭运算效果1.7 梯度运算MORPH_GRADIENT 膨胀 - 腐蚀作用提取物体外轮廓等价于手动相减。代码示例importcv2importnumpyasnp wordscv2.imread(words.png)ifwordsisNone:exit()wordscv2.imread(words.png)cv2.imshow(words,words)cv2.waitKey(0)kernelnp.ones((2,2),np.uint8)# 膨胀words_pzcv2.dilate(words,kernel,iterations1)cv2.imshow(words_pz,words_pz)cv2.waitKey(0)# 腐蚀words_fscv2.erode(words,kernel,iterations1)cv2.imshow(words_fs,words_fs)cv2.waitKey(0)# 膨胀-腐蚀gradientcv2.morphologyEx(words,cv2.MORPH_GRADIENT,kernel)cv2.imshow(gradient,gradient)cv2.waitKey(0)cv2.destroyAllWindows()梯度运算效果1.8 顶帽TOPHAT与黑帽BLACKHAT顶帽 原图 - 开运算提取比背景更亮的微小细节用于光照不均时的亮纹理增强。黑帽 闭运算 - 原图提取比背景更暗的孔洞、暗线条。tophatcv2.morphologyEx(sun,cv2.MORPH_TOPHAT,kernel)blackhatcv2.morphologyEx(sun,cv2.MORPH_BLACKHAT,kernel)二、边缘检测Edge Detection2.1 什么是边缘边缘指图像中灰度发生明显变化的位置。例如黑色背景中的白色物体边界位置黑 → 白 。变化明显。常应用于目标检测、轮廓提取、图像分割、特征提取。2.2 Sobel算子Sobel是什么Sobel算子是一种一阶微分边缘检测算子。通过计算x方向梯度和y方向梯度获得边缘。函数cv2.Sobel(src,ddepth,dx,dy,ksize)参数含义src输入图像ddepth输出深度dxx方向导数dyy方向导数ksize卷积核大小Sobel代码分析img_xcv2.Sobel( img, -1, dx1, dy0 )存在一个隐藏问题。问题-1-1表示输出数据类型和输入一致。如果输入uint8 范围0~255但是Sobel计算可能产生负数。uint8无法保存。导致边缘信息丢失。因此正确写法img_xcv2.Sobel(img,cv2.CV_64F,1,0)img_xcv2.convertScaleAbs(img_x)保留负梯度转换为可显示图片代码示例importcv2 imgcv2.imread(yuan.png,0)img_x_64cv2.Sobel(img,cv2.CV_64F,dx1,dy0)# 默认int8改为float64,可保存负数img_x_fullcv2.convertScaleAbs(img_x_64)# 转换为绝对值负数转换为正数img_y_64cv2.Sobel(img,cv2.CV_64F,dx0,dy1)# 默认int8改为float64, 可保存负数img_y_fullcv2.convertScaleAbs(img_y_64)# 转换为绝对值负数转换为正数img_xy_fullcv2.addWeighted(img_x_full,1,img_y_full,1,0)cv2.imshow(original,img)cv2.imshow(img_xy_sobel_full,img_xy_full)cv2.waitKey(0)cv2.destroyAllWindows()效果显示2.3 Scharr 算子特点是Sobel的改进版本仅支持 ksize3内核权重更大对细微梯度更敏感边缘细节更丰富。函数img_xcv2.Scharr( img, cv2.CV_64F, 1, 0 )代码示例importcv2 imgcv2.imread(01.jpg,0)img_x_64cv2.Scharr(img,cv2.CV_64F,dx1,dy0)# 默认int8改为float64,可保存负数img_x_fullcv2.convertScaleAbs(img_x_64)# 转换为绝对值负数转换为正数img_y_64cv2.Scharr(img,cv2.CV_64F,dx0,dy1)# 默认int8改为float64, 可保存负数img_y_fullcv2.convertScaleAbs(img_y_64)# 转换为绝对值负数转换为正数img_xy_fullcv2.addWeighted(img_x_full,1,img_y_full,1,0)cv2.imshow(img_xy_Scharr_full,img_xy_full)cv2.waitKey(0)cv2.destroyAllWindows()2.4 Laplacian 算子原理不区分方向直接计算二阶导数捕捉灰度突变点对噪声敏感。函数img_lapcv2.Laplacian( img, cv2.CV_64F, ksize3 )代码示例importcv2 imgcv2.imread(01.jpg,cv2.IMREAD_GRAYSCALE)img_lapcv2.Laplacian(img,cv2.CV_64F,ksize3)img_lap_fullcv2.convertScaleAbs(img_lap)cv2.imshow(img_lap_full,img_lap_full)cv2.waitKey(0)cv2.destroyAllWindows()2.5 Canny 最优边缘检测Canny是工业中最常用边缘检测算法。优点边缘定位准确错误率低边缘单一Canny 四大步骤高斯滤波消除噪声干扰。Sobel 计算梯度幅值与方向。非极大值抑制NMS细化粗边缘只保留梯度方向上的局部最大值。双阈值筛选高阈值 强边缘低阈值 弱边缘只有与强边缘连通的弱边缘才被保留。函数cv2.Canny(image, threshold1, threshold2, edgesNone, apertureSize3, L2gradientFalse)threshold1低阈值threshold2高阈值代码示例importcv2 imgcv2.imread(01.jpg,cv2.IMREAD_GRAYSCALE)cv2.imshow(img,img)cv2.waitKey(0)img_cannycv2.Canny(img,100,150)cv2.imshow(img_canny,img_canny)cv2.waitKey(0)cv2.destroyAllWindows()2.6 四种边缘检测效果展示从左到右依次为原始灰度图、Sobel 、Scharr 、Laplacian 、Canny2.7 四种边缘检测算子对比总结算法导数特点优点缺点Sobel一阶计算梯度速度快抗噪一般Scharr一阶优化Sobel精度更高仍需后处理Laplacian二阶检测变化响应明显容易受噪声影响Canny综合多阶段算法效果最好计算量较高总结形态学本质是形状处理核心是结构元Kernel六种操作腐蚀/膨胀/开/闭/梯度/顶帽黑帽各有用途。边缘检测中Sobel/Scharr 为一阶微分分方向注意必须用 CV_64F 保留负梯度。Laplacian 为二阶微分无方向对噪声敏感需先滤波。Canny 为综合最优方案包含滤波梯度NMS双阈值四步。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门