OpenCV for Python之圖像梯度
Opencv4官方文檔:https://docs.opencv.org/2.4.4-beta/
Opencv4 for Python中文文檔點擊下載:OpenCV4 for Python 中文文檔
1 圖像梯度的概念
梯度簡單來說就是求導,在圖像上表現出來的就是提取圖像的邊緣(無論是橫向的、縱向的、斜方向的等等),所需要的是一個核模板。模板的不同結果也不同。所以能夠看到,全部的算子函數,歸結究竟都能夠用函數cv2.filter2D()來表示,不同的方法給予不同的核模板,然後演化爲不同的算子。OpenCV提供三種類型的梯度濾波器或高通濾波器,即Sobel,Scharr和Laplacian
2 Sobel 算子
Sobel算子是高斯平滑加微分運算的聯合運算,因此它更抗噪聲。逆可以指定要採用的導數方向,垂直或水平(分別通過參數yorder和xorder)。逆還可以通過參數ksize指定內核的大小。如果ksize = -1 ,則使用3x3 Scharr濾波器,比3x3 Sobel濾波器具有更好的結果。
demo:
def sobel_demo(image):
grad_x = cv.Sobel(image, cv.CV_32F, 1, 0) # 採用Scharr邊緣更突出,Sobel改爲Scharr即可
grad_y = cv.Sobel(image, cv.CV_32F, 0, 1)
gradx = cv.convertScaleAbs(grad_x) # 由於算完的圖像有正有負,所以對其取絕對值
grady = cv.convertScaleAbs(grad_y)
# 計算兩個圖像的權值和,dst = src1*alpha + src2*beta + gamma
gradxy = cv.addWeighted(gradx, 0.5, grady, 0.5, 0)
cv.imshow("gradx", gradx)
cv.imshow("grady", grady)
cv.imshow("gradient", gradxy)
result:
3 Scharr 算子
原理和sobel算子原理一樣,只是卷積核不一樣,因此準確度更高一點
demo:
def sobel_demo(image):
grad_x = cv.Scharr(image, cv.CV_32F, 1, 0) # 採用Scharr邊緣更突出,Sobel改爲Scharr即可
grad_y = cv.Scharr(image, cv.CV_32F, 0, 1)
gradx = cv.convertScaleAbs(grad_x) # 由於算完的圖像有正有負,所以對其取絕對值
grady = cv.convertScaleAbs(grad_y)
# 計算兩個圖像的權值和,dst = src1*alpha + src2*beta + gamma
gradxy = cv.addWeighted(gradx, 0.5, grady, 0.5, 0)
cv.imshow("gradx", gradx)
cv.imshow("grady", grady)
cv.imshow("gradient", gradxy)
result:
4 Laplacian 算子
demo:
def laplace_demo(image): # 二階導數,邊緣更細
dst = cv.Laplacian(image,cv.CV_32F)
lpls = cv.convertScaleAbs(dst)
cv.imshow("laplace_demo", lpls)
result:
5 自定義算子
def custom_laplace(image):
# 以下算子與上面的Laplace_demo()是一樣的,增強採用np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])
kernel = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])
dst = cv.filter2D(image, cv.CV_32F, kernel=kernel)
lpls = cv.convertScaleAbs(dst)
cv.imshow("custom_laplace", lpls)
result:
轉載請註明轉自:https://leejason.blog.csdn.net/article/details/106448002