当前位置:   article > 正文

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

opencv canny

一、目标

  • 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 
)			
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
参数说明
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()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

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

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

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

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

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

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/173481
推荐阅读
相关标签
  

闽ICP备14008679号