OpenCV+python:圆检测
1,圓檢測基本原理
對霍夫變換有了這樣一種理解-----實際上就是坐標變換,是一種數學上的變換,然后再轉換到參數坐標系進行討論,最終確定待檢測圓(或者其他形狀)的數學方程。在極坐標系下,圓的數學表達式如下:
類似于霍夫變換直線檢測,這里我們也定義一個累加器,但是與直線檢測不同的是,直線檢測參數是二維的,而圓的參數是三維的。如果一個圓上的點,都沿著其梯度方向畫線,那么所有線的角點就是圓心。OpenCV中的霍夫梯度算法就利用這個原理,先計算可能的圓心,然后再去計算可能的半徑。
霍夫梯度檢測圓形的算法如下:
I、估計圓心
(1)把原圖做一次Canny邊緣檢測,得到邊緣檢測的二值圖
(2) 對原始圖像執行一次Sobel算子,計算出所有像素的鄰域梯度值
(3)初始化圓心空間N(a,b),令所有的N(a,b)=0
(4)遍歷Canny邊緣二值圖中的所有非零像素點,沿著梯度方向畫線,將線段經過的所有累加器中的點(a,b)的N(a,b)+=1
(5)統計排序N(a,b),得到可能的圓心
II、估計半徑(針對某一個圓心a,b)
(1)計算Canny圖中所有非0點距離圓心的距離
(2)距離從小到大排序,根據閾值,選取合適的可能半徑(比如3和3.5都被劃為半徑值3中)
(3)初始化半徑空間r,N(r)=0
(4)遍歷Canny圖中的非0點,對于點所滿足的半徑r,N?+=1
(5)統計得到可能的半徑值
利用霍夫變換檢測其他圖形的原理也是這樣。找出表達式以及參數空間,遍歷圖像,找出參數空間中符合要求的參數。
2,源代碼示例:
import cv2 as cv
import numpy as npdef detect_circles_demo(image):dst = cv.pyrMeanShiftFiltering(image, 10, 100) #均值遷移,EPT邊緣保留濾波,霍夫噪聲敏感,所以要先消除噪聲cimage = cv.cvtColor(dst, cv.COLOR_BGR2GRAY)circles = cv.HoughCircles(cimage, cv.HOUGH_GRADIENT, 1, 20, param1=60, param2=28, minRadius=0, maxRadius=0)"""HoughCircles(image, method, dp, minDist, circles=None, param1=None, param2=None, minRadius=None, maxRadius=None)
1.image:輸入圖像 (灰度圖)2.method:指定檢測方法. 現在OpenCV中只有霍夫梯度法,加快速度3.dp:累加器圖像的反比分辨=1,默認即可4.minDist = 檢測到圓心之間的最小距離,這是一個經驗值。這個大了,那么多個圓就是被認為一個圓。5.param_1 = 50: Canny邊緣函數的高閾值6.param_2 = 30: 圓心檢測閾值.根據你的圖像中的圓大小設置,當這張圖片中的圓越小,那么此值就設置應該被設置越小。當設置的越小,那么檢測出的圓越多,在檢測較大的圓時則會產生很多噪聲。所以要根據檢測圓的大小變化。7.min_radius = 0: 能檢測到的最小圓半徑, 默認為0.8.max_radius = 0: 能檢測到的最大圓半徑, 默認為0"""circles = np.uint16(np.around(circles)) #around對數據四舍五入,轉化為整數for i in circles[0, :]:cv.circle(image, (i[0], i[1]), i[2], (0, 0, 255), 2) #畫圓cv.circle(image, (i[0], i[1]), 2, (255, 0, 0), 2) #標記中心cv.imshow("circles", image)src = cv.imread("F:/images/coins.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
detect_circles_demo(src)
cv.waitKey(0)cv.destroyAllWindows()
運行結果:
總結
以上是生活随笔為你收集整理的OpenCV+python:圆检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: chao字开头的成语有哪些啊?
- 下一篇: 苹果6多少钱呀啊?