圖像梯度是指圖像某像素在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軸方向同時求梯度: