边缘就是图像上不同区域之间的交界处,就是灰度或者颜色变换很大的一系列的点。
在数学上我们判断一个点变换是否剧烈一般通过导数或者微分来判断。因为当斜率接近90度时,导数会趋近于无限大,所以我们一般采用微分的形式。dy/dx,当dx趋向于无限小,dy/dx 就是x在该函数上的导数,所以dy/dx就可以来近似导数。当我们固定dx,比较不同点的变化率时只用比较dy就好了,所以计算整幅图像的微分,dy的大小就是边缘的强弱了,我们也称之为梯度。
1.Prewitt算子
2.sobel算子
和Prewitt一样,Sobel算子也是用周围8个像素来估计中心像素的梯度,但是Sobel算子认为靠近中心像素的点应该给予更高的权重,所以Sobel算子把与中心像素4邻接的像素的权重设置为2或-2。如下图:
3.candy算子
使用高斯滤波器,以平滑图像,滤除噪声。
计算图像中每个像素点的梯度强度和方向(一般使用sobel算子)。
应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应(细化边缘)。
应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。
通过抑制孤立的弱边缘最终完成边缘检测。
4.Laplacian算子(拉普拉斯算子)
拉普拉斯算子采用的是二阶差分算子计算边缘的,就是对一阶差分再做一次差分。
f ’'(x, y) = -4 f(x, y) + f(x-1, y) + f(x+1, y) + f(x, y-1) + f(x, y+1)。所以Laplacian算子是:
代码展示:
1.sobel
import cv2
import numpy as np
img=cv2.imread("C:\\Users\\Acer\\Desktop\\1.png",cv2.IMREAD_GRAYSCALE)
sobelx=cv2.Sobel(img,cv2.CV_64F,1,0)
sobely=cv2.Sobel(img,cv2.CV_64F,0,1)
sobelx=cv2.convertScaleAbs(sobelx)
sobely=cv2.convertScaleAbs(sobely)
sobelxy=cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv2.imshow("sobelxy",sobelxy)
cv2.waitKey()
cv2.detroyAllWindows()
处理结果:
2.Laplacian
import cv2
import numpy as np
img=cv2.imread("C:\\Users\\Acer\\Pictures\\1.png",cv2.IMREAD_GRAYSCALE)
r=cv2.Laplacian(img,cv2.CV_64F)
r=cv2.convertScaleAbs(r)
cv2.imshow("original",img)
cv2.imshow("Laplacian",r)
cv2.waitKey(0)
cv2.destroyAllWindows()
来源:https://blog.csdn.net/weixin_42028758/article/details/100976501