
OpenCV Canny边缘检测(学习笔记)
Canny边缘检测
Canny边缘检测主要是按照如下步骤来进行的边缘检测:
1.使用高斯滤波器,以平滑图像,滤除噪声。(降噪)
2.计算图像中每个像素点的梯度强度和方向。(使用sobel算子)
3.应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
4.应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
5.通过抑制孤立的弱边缘最终完成边缘检测。
高斯滤波器
边缘检测易受噪声影响,所以使用高斯滤波器平滑图像,降低噪声。
计算梯度大小
使用sobel算子计算图像中每个像素点的梯度大小和方向。
通过的sobel求导得出3*3
的卷积核,通过上面两个公式得出对应的梯度。
接着我们通过下面的公式进行计算梯度的大小和方向。
基本的方向就那标志的8种方向。
非极大值抑制
遍历图像中的所有的像素点,判断当前像素点是否是周围像素点中具有相同方向梯度的最大值。
举例:在下图中,第一列方向都是向上,只取最大梯度值7
;第二列方向也都是向上,取最大梯度值8
;
保留黄色背景的像素点,其他的归为0
。
双阈值处理
指定两个值minVal
和maxVal
,设定最小的阈值和最大的阈值。
规则如下:
1.梯度值>maxVal:则处理为边界。
2.minVal<梯度值<maxVal:连有边界则保留,否则舍弃
3.梯度值<minVal:则舍弃
举例:
B
线条虽然在minVal
与maxVal
之间,但是没有高于maxVal
的线条作为连接,所以直接舍弃。C
线条虽然也在此区间,但是它有A
线条的连接所以它可以保留。
代码实践
接下来我们使用canny
对lena.jpg
图片进行边缘处理,分别展示阈值在80-150
和50-100
之间的区别。
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
# 展示图片
def cv_show(img,name):
cv2.imshow(name,img)
cv2.waitKey()
cv2.destroyAllWindows()
img=cv2.imread("lena.jpg",cv2.IMREAD_GRAYSCALE)
v1=cv2.Canny(img,80,150)
v2=cv2.Canny(img,50,100)
res = np.hstack((v1,v2))
cv_show(res,'res')
我们发现阈值在50-100
区间更细。
再对一张car.png
的图片做例子:
img=cv2.imread("car.png",cv2.IMREAD_GRAYSCALE)
v1=cv2.Canny(img,120,250)
v2=cv2.Canny(img,50,100)
res = np.hstack((v1,v2))
cv_show(res,'res')
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

