图像梯度是指图像某像素在x和y两个方向上的变化率(与相邻像素比较),是一个二维向量,由2个分量组成,X轴的变化、Y轴的变化 。
其中X轴的变化是指当前像素右侧(X加1)的像素值减去当前像素左侧(X减1)的像素值。
同理,Y轴的变化是当前像素下方(Y加1)的像素值减去当前像素上方(Y减1)的像素值。
其实Sobel算子求梯度也是分为x轴方向和y轴方向,说白了就是将一个卷积核进行上下左右划分,x轴方向上就是右➖左,y轴方向上就是下➖上
cv2.Sobel(img,cv2.CV_64F,1,0,ksize = 3)
第一个参数:当前的图像对象名称
第二个参数:当前图像的深度,通常情况下指定为-1,表示输出和输入的深度是一样的;cv2.CV_64F可以存6字节的大小,为了方便后面的取绝对值操作
第三个参数:是否算X轴的水平方向,若为1表示计算X轴方向,若为0表示不计算X轴方向
第四个参数:是否算Y轴的竖直方向,若为1表示计算Y轴方向,若为0表示不计算Y轴方向
第五个参数:ksize指定的卷积核是多大的,通常情况下都是奇数大小,例如:3×3的卷积核
import cv2
import numpy as npdef show_photo(name,picture):cv2.imshow(name,picture)cv2.waitKey(0)cv2.destroyAllWindows()#原图:
img = cv2.imread('E:\Jupyter_workspace\study\data/pie.png',cv2.IMREAD_GRAYSCALE)
show_photo('img',img)#x轴方向
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize = 3)#这里的CV_64F可以存储的位数很多,以便于后续的取绝对值操作
show_photo('sobelx',sobelx)
#由于右减左,下减上原则
#原图左部分,右为圈内白色左为圈外黑色,白-黑结果为正,显示
#原图右部分,右为圈外黑色左为圈内白色,黑-白结果为负,不显示#y轴方向
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize = 3)#这里的CV_64F可以存储的位数很多,以便于后续的取绝对值操作
show_photo('sobely',sobely)
#由于右减左,下减上原则
#原图下部分,下为圈内白色上为圈外黑色,白-黑结果为正,显示
#原图上部分,下为圈外黑色上为圈内白色,黑-白结果为负,不显示
原图:
白到黑是正数,黑到白是负数,所有的负数都被截断为0(显示黑色),也就是只显示一半的轮廓
x轴方向取梯度:
y轴方向取梯度:
故此时需要进行绝对值操作,为了将两边的轮廓都显示出来
import cv2
import numpy as npdef show_photo(name,picture):#显示图像函数cv2.imshow(name,picture)cv2.waitKey(0)cv2.destroyAllWindows()#原图:
img = cv2.imread('E:\Jupyter_workspace\study\data/pie.png',cv2.IMREAD_GRAYSCALE)
show_photo('img',img)#x轴方向,取绝对值
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize = 3)
sobelx = cv2.convertScaleAbs(sobelx)#取绝对值
show_photo('sobelx',sobelx)#y轴方向,取绝对值
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize = 3)
sobely = cv2.convertScaleAbs(sobely)#取绝对值
show_photo('sobely',sobely)#分别计算x和y,再求和
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)#进行加权后相加,最好一个参数表示偏移量,一般默认为0
show_photo('sobelxy',sobelxy)#### 不建议直接计算,最后的效果并不是特别好
#### 需要求梯度的时候分别计算然后求和效果会好些
sobelxy = cv2.Sobel(img,cv2.CV_64F,1,1,ksize = 3)
sobelxy = cv2.convertScaleAbs(sobelxy)
show_photo('sobelxy',sobelxy)
原图:
x轴方向,取绝对值:
y轴方向,取绝对值:
分别计算x和y,再求和:
直接计算:
不建议直接计算,最后的效果并不是特别好
需要求梯度的时候分别计算然后求和效果会好些
换一张照片来进行梯度操作效果更明显
import cv2
import numpy as npdef show_photo(name,picture):#显示图像函数cv2.imshow(name,picture)cv2.waitKey(0)cv2.destroyAllWindows()img = cv2.imread('E:\Jupyter_workspace\study\data/test1.png',cv2.IMREAD_GRAYSCALE)
show_photo('img',img)#显示原图sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize = 3)#求X轴方向梯度
sobelx = cv2.convertScaleAbs(sobelx)#取绝对值
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize = 3)#求Y轴方向梯度
sobely = cv2.convertScaleAbs(sobely)#取绝对值
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)#加权相加
show_photo('sobelxy',sobelxy)#显示整体梯度后的效果img = cv2.imread('E:\Jupyter_workspace\study\data/test1.png',cv2.IMREAD_GRAYSCALE)
sobelxy = cv2.Sobel(img,cv2.CV_64F,1,1,ksize = 3)#X轴和Y轴同时求方向梯度
sobelxy = cv2.convertScaleAbs(sobelxy)
show_photo('sobelxy',sobelxy)
原图:
分别对X轴方向求梯度和Y轴方向求梯度,然后加权求和:
对X轴方向和Y轴方向同时求梯度: