在图像中,边界位置才会有梯度,opencv中的常见算子有:
1、Sobel算子
可以有效的提取图像边缘,但是对图像中较弱的边缘提取效果较差
2、scharr算子
Scharr算子是对Sobel算子差异性的增强,是通过将滤波器中的权重系数放大来增大像素值间的差异,能有效的提取出较弱的边缘,但两者在检测图像边缘的原理和使用方式上相同
3、Laplacian算子
1)Laplacian算子具有各方向同性的特点,能够对任意方向的边缘进行提取,具有无方向性的优点,因此使用Laplacian算子提取边缘不需要分别检测X方向的边缘和Y方向的边缘,只需要一次边缘检测即可。
2)Laplacian算子是一种二阶导数算子,对噪声比较敏感,所以需要配合配合高斯滤波一起使用
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
def cv_show(name,img):
cv2.imshow(name,img)
cv2.waitKey()
cv2.destroyAllWindows()
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
•ddepth:图像的深度
•dx和dy分别表示水平和竖直方向
•ksize是Sobel算子的大小
img = cv2.imread('pie.png',cv2.IMREAD_GRAYSCALE) #灰度图
cv_show("img",img)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
#边界位置会有梯度,白到黑是正数,黑到白就是负数了,所有的负数会被截断成0,所以要取绝对值
sobelx = cv2.convertScaleAbs(sobelx)
cv_show(sobelx,'sobelx') #显示白色圆圈,上下位置有空隙
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)
cv_show(sobely,'sobely') #显示白色圆圈,左右位置有空隙
#先计算下x,y,在求和
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show(sobelxy,'sobelxy')
#不同算子的差异
img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)#关注的东西更多,更敏感,描绘更细致
scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx,0.5,scharry,0.5,0)
laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
res = np.hstack((sobelxy,scharrxy,laplacian))
cv_show(res,'res')