边缘检测分为两类:基于搜索和基于零穿越
基于搜索:寻找图像的一阶导数的最大值来检测边界,然后利用计算结果估计边缘的局部方向,通常采用梯度的方向,并利用此方向找到局部梯度模的最大值,代表算法是Sobel算子和Scharr算子
基于零穿越:通过寻找图像二阶导数零穿越来寻找边界,代表算法是Laplacian算子
Sobel算子检测效率高,但是检测结果不如Canny准确
sobel算子注意以下几点:
1.soble计算后会出现小于0或大于255,所以在sobel函数中需要传入cv_16s转化为16位有符号的数据类型
2.使用sobel算子后还需要使用cv.convertScaleAbs重新转换为uint8
3.最终需要使用cv.addWeighted将x和y方向的梯度结合
#1 读取图片
img= cv2.imread(r'.\\Image_20220709101917854.bmp',0)
#2 计算sobel算子
x = cv2.Sobel(img,cv2.CV_16S,1,0)
y = cv2.Sobel(img,cv2.CV_16S,0,1)
#3 将数据进行转换
Scale_abX = cv2.convertScaleAbs(x)
Scale_abY = cv2.convertScaleAbs(y)
#4结果合成
result = cv2.addWeighted(Scale_abX,0.5,Scale_abY,0.5,0)
plt.imshow(result,cmap="gray")
plt.show()
img= cv2.imread(r'.\\Image_20220709101917854.bmp',0)
x = cv2.Laplacian(img,cv2.CV_16S)
result=cv2.convertScaleAbs(x)
plt.imshow(result,cmap="gray")
plt.show()
Canny边缘检测原理:
第一步:噪声去除,使用高斯滤波
第二步:计算图像梯度,使用Sobel算子计算x和y方向上的梯度和方向
第三步:非极大值抑制,对每个像素进行扫描,看这个点的梯度是不是周围具有相同梯度方向的点最大的
第四部:滞后阈值