opencv学习笔记(六)---图像梯度
圖像梯度的算法有很多方法:sabel算子,scharr算子,laplacian算子,sanny邊緣檢測(下個隨筆)。。。
這些算子的原理可參考:https://blog.csdn.net/poem_qianmo/article/details/25560901
下面是我的一些理解:
sabel算子:
sobel算子主要用于獲得數字圖像的一階梯度,常見的應用和物理意義是邊緣檢測。
函數:
Python: cv2.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]]) → dst? (參數就不一一說了,常用的就那幾個,其他默認即可)
?
|
?
?
原理
?
算子使用兩個33的矩陣(圖1)算子使用兩個33的矩陣(圖1)去和原始圖片作卷積,分別得到橫向G(x)和縱向G(y)的梯度值,如果梯度值大于某一個閾值,則認為該點為邊緣點
?
Gx方向的相關模板:
?
?
Gy方向的相關模板:
?
具體計算如下:
圖像的每一個像素的橫向及縱向灰度值通過以下公式結合,來計算該點灰度的大小:
?
通常,為了提高效率使用不開平方的近似值:
#sobels算子 img = cv.imread("E:/pictures/lena.jpg",cv.IMREAD_UNCHANGED) sobelx= cv.Sobel(img,cv.CV_64F,1,0) #cv.CV_64F將像素值轉換為double型,不然計算后為負值的像素會被截斷為0 sobelx = cv.convertScaleAbs(sobelx) #轉換為uint8類型(x方向) sobely = cv.Sobel(img,cv.CV_64F,0,1) sobely = cv.convertScaleAbs(sobely) sobelxy11 = cv.Sobel(img,cv.CV_64F,1,1) #直接x,y方向一起計算(效果不好,應分開計算,再求權重和) sobelxy11 = cv.convertScaleAbs(sobelxy11) sobelxy = cv.addWeighted(sobelx,0.5,sobely,0.5,0) #圖像權重和 cv.imshow("orginal",img) #dst = cv.addWidget(src1,alpha,src2,beta,gamma) cv.imshow("sobelx",sobelx) #src1 圖一 alpha->圖一的權重 src2->圖二 beta->圖二的權重 gamma->修正值 cv.imshow("sobely",sobely) #dst = src1*alpha+src2*beta+gamma cv.imshow("sobelxy",sobelxy) cv.imshow("sobelxy11",sobelxy11) cv.waitKey() cv.destroyAllWindows()用sobel函數同時對想x,y方向檢測的效果并不好,一般不用。
scharr算子:
函數:
Python: cv2.Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]]) → dst
|
?
scharr算子是對sabel算子的增強,可以看到上圖中很多細小的邊緣都沒檢測到,那么scharr算子就是解決這個問題的,它比sabel算子更精確,速度和復雜程度卻一樣,只是因為用的核不一樣
是scharr 的卷積核,他的原理和sabel算子一樣。
?
#scharr算子 scharr算子是對sabel算子的增強 scharr算子等價于ksize=-1的sabel算子 img = cv.imread("E:/pictures/lena.jpg",cv.IMREAD_GRAYSCALE) scharrx= cv.Scharr(img,cv.CV_64F,1,0) #scharrx算子要滿足dx>=0&&dy>=0&&dx+dy=1 scharrx = cv.convertScaleAbs(scharrx) scharry = cv.Scharr(img,cv.CV_64F,0,1) scharry = cv.convertScaleAbs(scharry) scharrxy = cv.addWeighted(scharrx,0.5,scharry,0.5,0) #sabel算子和 scharr算子的比較 sobelx= cv.Sobel(img,cv.CV_64F,1,0) sobelx = cv.convertScaleAbs(sobelx) sobely = cv.Sobel(img,cv.CV_64F,0,1) sobely = cv.convertScaleAbs(sobely) sobelxy = cv.addWeighted(sobelx,0.5,sobely,0.5,0) cv.imshow("orginal",img) cv.imshow("sobelxy",sobelxy) cv.imshow("scharrxy",scharrxy) cv.waitKey() cv.destroyAllWindows()?
laplacian算子:
Laplace算子和Sobel算子一樣,屬于空間銳化濾波操作,只不過是用的二階微分,看官網的一些解釋:
The function calculates the Laplacian of the source image by adding up the second x and y derivatives calculated using the Sobel operator:
This is done when ksize > 1 . When ksize == 1 , the Laplacian is computed by filtering the image with the following aperture:
cv.Laplace(src, dst, ksize=3) → None
|
?
?
#拉普拉斯算子 img = cv.imread("E:/pictures/erode1.jpg",cv.IMREAD_GRAYSCALE) r = cv.Laplacian(img,cv.CV_64F) r = cv.convertScaleAbs(r) #關鍵代碼就這兩行,拉普拉斯算子不用再求x,y的權重和,因為這個函數都計算好了 cv.imshow("orginal",img) cv.imshow("laplacian",r) cv.waitKey() cv.destroyAllWindows()
?
Canny邊緣檢測:
Python: cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]]) → edges
threshold1和threshold2是兩個閾值,越小檢測效果越好
?
import cv2 as cv import numpy as npimg = cv.imread("E:/pictures/lena.jpg") result1 = cv.Canny(img,50,100) result2 = cv.Canny(img,100,200) cv.imshow("orginal",img) cv.imshow("result1",result1) cv.imshow("result2",result2) cv.waitKey() cv.destroyAllWindows()?
?
轉載于:https://www.cnblogs.com/ling2000/p/10588294.html
總結
以上是生活随笔為你收集整理的opencv学习笔记(六)---图像梯度的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php可变数量的参数
- 下一篇: MB_SELECT_GR_BLOCKED