图像梯度计算的是图像变化的速度,对于图像的边缘部分,其灰度值变化较大,梯度值也较大;对于图像中比较平滑的部分,其灰度值变化较小,相应的梯度值也较小。
一般情况下,图像梯度计算的图像的边缘信息
- Sobel算子,Scharr算子,Laplacian算子
Sobel
dst=cv2.Sobel(src,ddepth,dx,dy,ksize)
其中
- ddepth代表输出图像的深度,为了避免负数截为0,采用cv2.CV_64F,同时要加上绝对值,以保证偏导数可以正确地显示出来
- dx表示x方向上的求导阶数
- dy表示y方向上的求导阶数
- ksize代表Sobel核的大小。该值为-1时,会使用Scharr算子进行运算
对参数取绝对值
dst=cv2.convertScaleAbs(src)
import cv2
import numpy as np
#注意,此处不能用np.uint8,要用np.int16
img=np.random.randint(-256,256,size=[4,5],dtype=np.int16)
rst=cv2.convertScaleAbs(img)
print("img:\n",img)
print("rst\n",rst)
img:
[[ 15 -129 129 95 126]
[-207 -108 -161 -39 -188]
[-217 174 225 -181 89]
[ -67 236 -106 -215 -233]]
rst
[[ 15 129 129 95 126]
[207 108 161 39 188]
[217 174 225 181 89]
[ 67 236 106 215 233]]
方向
dx,dy通常值为0或者1,最大值是2。如果是0表示在该方向上没有求导
- 计算x方向边缘梯度 (1,0)
- 计算y方向边缘梯度 (0,1)
- dx与dy的值均为1(1,1)
- 计算x方向和y方向的边缘叠加,组合叠加
x方向
import cv2
import numpy as np
img=cv2.imread("D:/6.jpg",0)
Sobelx=cv2.Sobel(img,-1,1,0)
cv2.imshow("img",img)
cv2.imshow("x",Sobelx)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i20882701/73b0ae500992f9ba.png)
获取x方向完整边缘信息
import cv2
import numpy as np
img=cv2.imread("D:/6.jpg",0)
Sobelx=cv2.Sobel(img,cv2.CV_64F,1,0)
Sobelx=cv2.convertScaleAbs(Sobelx)
cv2.imshow("img",img)
cv2.imshow("x",Sobelx)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i20882701/15597b4df86ce1e2.png)
获取y方向完整边缘信息
import cv2
img=cv2.imread("D:/6.jpg")
Sobely=cv2.Sobel(img,cv2.CV_64F,0,1)
Sobely=cv2.convertScaleAbs(Sobely)
cv2.imshow("img",img)
cv2.imshow("y",Sobely)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i20882701/27a7bc594389a7f4.png)
dx=1,dy=1时的执行效果
import cv2
import numpy as np
img=cv2.imread("D:/6.jpg")
rst=cv2.Sobel(img,cv2.CV_64F,1,1)
rst=cv2.convertScaleAbs(rst)
cv2.imshow("img",img)
cv2.imshow("rst",rst)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i20882701/815541d657dde789.png)
计算x方向和y方向的边缘叠加
import cv2
import numpy as np
img=cv2.imread("D:/6.jpg")
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)
rst=cv2.addWeighted(Sobelx,0.5,Sobely,0.5,0)
rst=cv2.convertScaleAbs(rst)
cv2.imshow("img",img)
cv2.imshow("rst",rst)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i20882701/abd4455000bc9e34.png)
使用不同方式处理图像在两个方向的边缘信息
- 1.dx=1&&dy=1
- 2.叠加
import cv2
import numpy as np
img=cv2.imread("D:/renlian.jpg")
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)
rst1=cv2.addWeighted(Sobelx,0.5,Sobely,0.5,0)
rst2=cv2.Sobel(img,cv2.CV_64F,1,1)
cv2.imshow("rst1",rst1)
cv2.imshow("rst2",rst2)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i20882701/f9b2f9bd0f386bd2.png)
Scharr
对比Sobel,下面两句是等价的
dst=cv2.Sobel(src,ddepth,dx,dy,-1)
dst=cv2.Scharr(src,ddepth,dx,dy)
其中ddepth的作用和Sobel一样,设置为cv2.CV_64F,然后对计算结果取绝对值
接着dx和dy的取值只能是(1,0)或者(0,1)
import cv2
img=cv2.imread("D:/6.jpg")
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)
rst=cv2.addWeighted(Scharrx,0.5,Scharry,0.5,0)
img=cv2.imshow("img",img)
rst=cv2.imshow("rst",rst)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i20882701/0a9b927b0fa1ad0a.png)
import cv2
img=cv2.imread("D:/6.jpg")
Scharrx=cv2.Sobel(img,cv2.CV_64F,1,0,-1)
Scharry=cv2.Sobel(img,cv2.CV_64F,0,1,-1)
Scharrx=cv2.convertScaleAbs(Scharrx)
Scharry=cv2.convertScaleAbs(Scharry)
rst=cv2.addWeighted(Scharrx,0.5,Scharry,0.5,0)
img=cv2.imshow("img",img)
rst=cv2.imshow("rst",rst)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i20882701/45f1c52e924bb651.png)
Sobel算子和Scharr算子的比较
import cv2
img=cv2.imread("D:/hjb.jpg")
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)
cv2.imshow("img",img)
cv2.imshow("Sobel",Sobelxy)
cv2.imshow("Scharr",Scharrxy)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i20882701/f318c9a7dc91b31b.png)
Laplacian 算子及函数使用
其具有旋转不变性,可以满足不同方向的图像边缘锐化(边缘检测)的要求,而且需要对结果取绝对值
import cv2
img=cv2.imread("D:/6.jpg")
Laplacian=cv2.Laplacian(img,cv2.CV_64F)
Laplacian=cv2.convertScaleAbs(Laplacian)
cv2.imshow("img",img)
cv2.imshow("Laplacian",Laplacian)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i20882701/251e9bdd4b93cdea.png)
网友评论