【OpenCV-图像处理】Canny 边缘检测——OpenCV官方教程翻译(全网最详细)

一、目标

  • Canny边缘检测的概念
  • 使用OpenCV函数 Canny 检测边缘.

二、基本理论

Canny 边缘检测算法 是 John F. Canny 于 1986年开发出来的一个多级边缘检测算法,也被很多人认为是边缘检测的最优算法,.
最优边缘检测的三个主要评价标准是:

  • 低错误率: 标识出尽可能多的实际边缘,同时尽可能的减少噪声产生的误报。
  • 高定位性: 标识出的边缘要与图像中的实际边缘尽可能接近。
  • 最小响应: 图像中的边缘只能标识一次。

Canny边缘检测的步骤

  1. 使用高斯滤波器,以平滑图像,滤除噪声。
  2. 计算图像中每个像素点的梯度强度和方向。
  3. 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
  4. 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
  5. 通过抑制孤立的弱边缘最终完成边缘检测。
    (双阈值检测的范围越大,检测越明显的边界,抑制微小边界;范围越小,检测的边界细节越多)

1.消除噪声
由于边缘检测对图像中的噪声很敏感,所以第一步是使用5x5的高斯滤波器去除图像中的噪声。
在这里插入图片描述
计算过程:将高斯核K归一化变为归一化高斯核H后,遍历平滑图像中的每一个像素点。
在这里插入图片描述
详细介绍参见我之前写的博文【OpenCV-图像处理】图像平滑处理函数

2.计算图像的梯度

计算梯度幅值和方向。 此处,按照Sobel滤波器的步骤,用Sobel核在水平方向和垂直方向对平滑后的图像进行滤波,得到水平方向(Gx)和垂直方向(Gy)的一阶导数。:

b.运用一对卷积阵列 (分别作用于 x 和 y 方向):在这里插入图片描述

a.使用下列公式计算梯度幅值和方向:
在这里插入图片描述
梯度方向近似到四个可能角度之一(一般 0°, 45°, 90°, 135°)

计算过程:
详细介绍参见我之前写的博文:【OpenCV-图像处理】如何计算图像梯度,以及如何使用梯度来检测边缘

3.非极大值抑制
这一步排除非边缘像素, 仅仅保留了一些细线条(候选边缘)。
在这里插入图片描述
在这里插入图片描述

4.滞后阈值(双阈值检测)
最后一步,Canny 使用了滞后阈值,滞后阈值需要两个阈值(高阈值和低阈值):

  • 如果某一像素位置的幅值超过高阈值, 该像素被保留为边缘像素。
  • 如果某一像素位置的幅值小于低阈值, 该像素被排除。
  • 如果某一像素位置的幅值在两个阈值之间,该像素仅仅在连接到一个高于高阈值的像素时被保留。

Canny 推荐的 高:低 阈值比在 2:1 到3:1之间。
在这里插入图片描述

三、Canny边缘检测运算

3.1 cv2.Canny()函数

edges = cv2.Canny	(	InputArray 	image,
						double 	threshold1,
						double 	threshold2,
						int 	apertureSize = 3,
						bool 	L2gradient = false 
)			
参数说明
image8位输入图像(灰度图像)
edges输出图像 (支持原地计算,可为输入图像)
threshold1迟滞过程的第一个阈值minVal
threshold2迟滞过程的第二个阈值maxVal
apertureSizeSobel算子的核大小,缺省值是3
L2gradient它指定了寻找梯度大小的方程。如果为真,则使用上述更准确的方程,否则使用此函数:Edge_Gradient(G)=

举例演示

原图展示:
在这里插入图片描述

#######Canny边缘检测########
import numpy as np
import cv2 
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']        #文字字体为黑体

#读取图像
img = cv2.imread('car.jpg',0)   #第二个参数0与cv2.IMREAD_GRAYSCALE等价,代表转换为灰度图

#Canny边缘检测
edges1 = cv2.Canny(img,100,200)  #阈值为100-200 
edges2 = cv2.Canny(img,20,200)  #阈值为100-200 
edges3 = cv2.Canny(img,100,400)  #阈值为100-200 

plt.subplot(221),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(222),plt.imshow(edges1,cmap = 'gray')
plt.title('Edge Image1(阈值为100-200 )'), plt.xticks([]), plt.yticks([])
plt.subplot(223),plt.imshow(edges2,cmap = 'gray')
plt.title('Edge Image2(阈值为20-200 )'), plt.xticks([]), plt.yticks([])
plt.subplot(224),plt.imshow(edges3,cmap = 'gray')
plt.title('Edge Image3(阈值为100-400 )'), plt.xticks([]), plt.yticks([])
plt.show()

运行结果:
在这里插入图片描述
主要参考于OpenCV官方网站:http://www.opencv.org.cn/

目前博主已更新OpenCV平滑处理函数、形态学操作函数的详细介绍,链接如下:
【OpenCV-图像处理】图像平滑处理函数

【OpenCV-图像处理】形态学变换函数

【OpenCV-图像处理】图像阈值处理

【OpenCV-图像处理】如何计算图像梯度,以及如何使用梯度来检测边缘

<后续还会继续翻译和整理【OpenCV-图像处理】相关内容,如果需要,可持续关注我哦~>

<翻译和整理不易,留个赞或评论支持一下我吧^^>

如有疑问,欢迎批评指正^^

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路遥_.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值