首頁 > 軟體

Python+OpenCV之影象梯度詳解

2022-09-30 14:01:14

1. Sobel運算元

OpenCV系列—本文底頁有多個常用方法連結

1.1 Sobel介紹

cv2.Sobel(src, ddepth, dx, dy, ksize)

  • ddepth:影象的深度
  • dx和dy分別表示水平和豎直方向
  • ksize是Sobel運算元的大小

import cv2  # opencv讀取的格式是BGR


def cv_show(img, name):
    cv2.imshow(name, img)
    cv2.waitKey()
    cv2.destroyAllWindows()


img = cv2.imread('../img/pie.png', cv2.IMREAD_GRAYSCALE)
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()

pie.png原圖(右擊另存為下載):

1.2 橫向Sobel運算元

採用上述公式中的 G x G_{x} Gx​濾波器掃描整張圖,提取了左右兩邊有梯度差的位置,但是橫向看圓的上頂端和下頂端的梯度不明顯所以呈現圖片如下上下端為虛線的圓

sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
cv_show(sobelx, 'sobelx')

結果如下:

白-黑是正數,黑-白就是負數了,所有的負數會被截斷成0,所以要取絕對值。

sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
cv_show(sobelx, 'sobelx')

加入絕對值後,梯度結果就可以有一個完整的圓:

1.3 縱向Sobel運算元

採用上述公式中的 G y G_{y} Gy​濾波器掃描整張圖,提取了上下兩邊有梯度差的位置,但是縱向看圓的左頂端和右頂端的梯度不明顯所以呈現圖片如左右端為虛線的圓

sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobely = cv2.convertScaleAbs(sobely)
cv_show(sobely, 'sobely')

1.4 合併橫縱向的方法提取更好的邊緣的結果

將橫向梯度提取濾波器 Gx與縱向梯度提取濾波器Gy相加,即可得到效果較好的圓的邊緣梯度資訊

sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
cv_show(sobelxy, 'sobelxy')

不推薦

sobelxy = cv2.Sobel(img, cv2.CV_64F, 1, 1, ksize=3)
sobelxy = cv2.convertScaleAbs(sobelxy)
cv_show(sobelxy, 'sobelxy')

結果顯示,相對於分開使用橫縱向運算元邊緣重影嚴重:

1.5 利用1.3方法繪製素描風格

lena.jpg原圖,另存為儲存:

import cv2  # opencv讀取的格式是BGR


img = cv2.imread('../img/lena.jpg', cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
cv_show(sobelxy, 'sobelxy')

2. Scharr運算元

import cv2  # opencv讀取的格式是BGR


img = cv2.imread('../img/lena.jpg', cv2.IMREAD_GRAYSCALE)

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)

二階動量對紋理細節區分更加豐富結果圖如下:

3. Laplacian運算元

import cv2  # opencv讀取的格式是BGR


img = cv2.imread('../img/lena.jpg', cv2.IMREAD_GRAYSCALE)

laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)   

需要配合其他操作共同使用,單個使用的效果不如上面兩個運算元,結果圖如下:

到此這篇關於Python+OpenCV之影象梯度詳解的文章就介紹到這了,更多相關OpenCV影象梯度內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com