圖像梯度-Sobel算子
—卷積的作用除了實現圖像模糊或者去噪,還可以尋找一張圖像上所有梯度信息,這些梯度信息是圖像的最原始特徵數據,進一步處理之後就可以生成一些比較高級的特徵用來表示一張圖像實現基於圖像特徵的匹配,圖像分類等應用。
—Sobel算子是一種很經典的圖像梯度提取算子,其本質是基於圖像空間域卷積,背後的思想是圖像一階導數算子的理論支持。
—sobel算子主要用於獲得數字圖像的一階梯度,常見的應用和物理意義是邊緣檢測。(Laplacian邊緣檢測並不侷限於水平方向或垂直方向,這是Laplacian與soble的區別)
import cv2
import numpy as np
#顯示圖像函數
def cv_show(name,img):
cv2.imshow(name,img)
while cv2.waitKey(100) != 27:# loop if not get ESC
if cv2.getWindowProperty(name,cv2.WND_PROP_VISIBLE) <= 0:
break
cv2.destroyWindow(name)
img = cv2.imread('pie.png',cv2.IMREAD_GRAYSCALE)
cv_show('image',img)
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
- ddepth:圖像的深度,一般取-1
- dx和dy分別表示水平和豎直方向
- ksize是Sobel算子的大小
#沿水平方向對其梯度進行提取
sobel_x = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) #ddepth = -1/CV_64F
cv_show('sobel',sobel_x)
白到黑是正數,黑到白就是負數了,所有的負數會被截斷成0,所以要取絕對值
sobel_x = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobel_x = cv2.convertScaleAbs(sobel_x)
cv_show('sobel_abs_X',sobel_x)
#沿着豎直方向
sobel_y = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobel_y = cv2.convertScaleAbs(sobel_y)
cv_show('sobel_abs_y',sobel_y)
分別計算x和y,再求和
sobel_xy = cv2.addWeighted(sobel_x,0.5,sobel_y,0.5,0)
cv_show('sobel_xy',sobel_xy)
不建議直接計算
sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobelxy = cv2.convertScaleAbs(sobelxy)
cv_show('sobelxy',sobelxy)
以lena照片爲例,觀察提取到的邊緣特徵
img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE)
cv_show('lena',img)
sobel_x = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobel_x = cv2.convertScaleAbs(sobel_x)
sobel_y = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobel_y = cv2.convertScaleAbs(sobel_y)
sobel_xy = cv2.addWeighted(sobel_x,0.5,sobel_y,0.5,0)
cv_show('sobel_lena',sobel_xy)
import matplotlib.pyplot as plt
plt.imshow(sobel_xy) #plt與cv2的顯示圖像彩色通道順序不一樣所以顯色有差異
<matplotlib.image.AxesImage at 0x13be31828>
圖像梯度-Scharr算子
圖像梯度-Scharr算子,能夠捕獲更加細緻的紋理信息。
scharr_x = cv2.Scharr(img,cv2.CV_64F,1,0)
scharr_y = cv2.Scharr(img,cv2.CV_64F,0,1)
scharr_x = cv2.convertScaleAbs(scharr_x)
scharr_y = cv2.convertScaleAbs(scharr_y)
scharr_xy = cv2.addWeighted(scharr_x,0.5,scharr_y,0.5,0)
# cv_show('scharr',scharr_xy)
plt.imshow(scharr_xy)
<matplotlib.image.AxesImage at 0x13c3d3198>
圖像梯度-laplacian算子
laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
res = np.hstack((sobel_xy,scharr_xy,laplacian))
cv_show('res',res)