边缘检测是计算机视觉领域最热门的技术之一,常用在很多应用程序的预处理过程中,使用边缘检测可以标记出数字图像中亮度突然变化的点。图像属性的显著变化通常反应了其所表示的物理世界的重要事件或变化,比如表面方向不连续,深度不连续。
程序中用到的检测方法
Sobel滤波器边缘检测 | https://zhuanlan.zhihu.com/p/59640437 |
拉普拉斯边缘检测器 | https://blog.csdn.net/hdu_master/article/details/108294900 |
Canny边缘检测 | https://blog.csdn.net/weixin_40647819/article/details/91411424 |
Sobel算子是一个差分算子,它计算表示图像亮度的函数梯度的近似值。对于图像中的每个点,Sobel算子都可以对应出梯度向量或向量的范数。Sobel算子使用的算法基于图像与滤波器的卷积,计算的是整形数据,并且在水平方向和垂直方向进行运算,因而更加节约计算成本。拉普拉斯边缘检测是一种过零点的方法,它寻找的是二阶导数过零点的像素点,通常是拉普拉斯函数或非线性函数的差分表示。
下面举例实现
#边缘检测
import sys
import cv2
#input_file = sys.argv[1]
input_file = 'flower.png'
img = cv2.imread(input_file,cv2.IMREAD_GRAYSCALE)#转换成灰度图像
# 将图像调整为原来的0.6倍
scaling_factor = 0.4
img_scaled = cv2.resize(img, None, fx=scaling_factor, fy=scaling_factor,
interpolation=cv2.INTER_LINEAR)#双线性插值
cv2.imshow('New',img)
#提取出图像的高度和宽度
h,w = img.shape
#Sobel滤波器是一种边缘检测,它使用3X3的卷积核检测垂直边缘和水平边缘
sobel_horizontal = cv2.Sobel(img_scaled,cv2.CV_64F,1,0,ksize=5)#水平检测
sobel_vertical = cv2.Sobel(img_scaled,cv2.CV_64F,0,1,ksize=5)#垂直检测
laplacian = cv2.Laplacian(img_scaled,cv2.CV_64F)#拉普拉斯检测
canny = cv2.Canny(img_scaled,50,240)#Canny边缘检测
#显示所有输出图片
cv2.imshow('Original',img)
cv2.imshow('sobel_horizontal',sobel_horizontal)
cv2.imshow('sobel_vertical',sobel_vertical)
cv2.imshow('laplacian',laplacian)
cv2.imshow('canny',canny)
cv2.waitKey()
原图 | ![]() |
灰度图片 | ![]() |
sobel水平边缘检测 | ![]() |
sobel垂直边缘检测 | ![]() |
拉普拉斯边缘检测 | ![]() |
Canny边缘检测 | ![]() |
可以看出,尽管拉普拉斯边缘检测器弥补了Sobel边缘检测器的不足,但是拉普拉斯边缘检测器的输出仍有很多噪声。Canny边缘检测器由于问题的方式不同,所以更胜于前两者。Canny边缘检测是一个多阶段的过程,它使用滞后阈值得到清晰的边缘。