前往
大廳
主題

OpenCV 實例探討 - 圓形偵測

Jerry | 2023-06-01 18:24:13 | 巴幣 1000 | 人氣 611

情境:
有一垂直地面向下拍攝的鏡頭,地面上放有一固定位置的圓形(從鏡頭的角度看)物體作為辨識的目標,鏡頭可能會在固定的高度水平移動,也就是目標大小基本不變,要考慮目標可能在畫面中位置的變化。假設目標不總是出現在畫面中,鏡頭移動時目標可能會跑到畫面外,目標有大約90%以上的面積出現在畫面中時,需要能夠將其辨識出來。
寫一支程式在以上敘述的情景中辨識出目標,假設地面除了目標外,沒有其他圓形物體,但是要考慮到地面雜訊的干擾。
以上是最近處理到的一個情況,實際做起來不難,順便就在這邊分享一些內容。這邊以Python的一些語法或結構做討論,如果需要C++的協助,也歡迎提出。
請注意這邊僅分享部分程式內容及概念,不會放上完整程式碼。

首先這個問題最主要就是要找到畫面中的圓,我們可以直接用OpenCV 的HoughCircles 來實現,以下是使用OpenCV 官方文件中的參數找到畫面中的圓的結果:
想當然結果慘不忍睹,因為參數沒有根據情況調整。

接著調了一下參數後:
這邊第一個問題就出現了,因為演算法的關係,一些肉眼看起來不是圓的地方也剛好被當成圓了,考慮到現實情況,如果直接用演算法處理這些圓的話會沒完沒了。如果再把參數調得更嚴格,則變成有時候目標的圓也會偵測不到。

我們再回去分析這個情境:
• 場景中只有一個圓形物體是我們的目標
• 場景中除了目標外沒有其他圓形物體
• 影像是連續拍攝的

這邊先看第一點,既然只有一個目標,那麼我們可以直接透過操作參數,來找到畫面中最有可能是圓的物體。
要做到這點,可以直接將HoughCircles 中的minDist,也就是兩個圓心之間的最短距離,設為“畫面對角距離+2×最大半徑+1”,這樣一來就可以保證畫面中只找到一個圓,而假設我們的目標在畫面中,場景中又沒有其他圓,這邊找到的圓就可以確定有很高的機率是我們要的了。(其他參數應照實際狀況調整)
只是要注意,這樣做HoughCircles運算時間可能會大幅上升 (這邊不考慮這個問題)。

我們現在已經可以在目標出現時,找到我們要的目標,現在考慮到目標不在畫面中的情況 (另一段影像的截圖):
可以看到假如畫面中沒有目標,仍可能會誤判 (雖然用來測試的3段影片只出現這一幀誤判)。
如果參數調整得好,這個情形可以改善很多,但有沒有更好的辦法確保不會出現誤判呢?

這時候就真的要寫一點演算法來處理了,基本的概念是:
假如目標有出現在畫面中,連續的影像應該要能夠在接近的位置拍攝到半徑接近的圓形;假如目標不在畫面中,即使有在畫面中找到圓形,這個圓形在接下來幾幀的位置和半徑都會劇烈變化,因為這只是畫面中幾個點湊巧連成的圓。
這邊我們就可以透過處理連續幾幀的圓形偵測結果,判斷畫面中找到的圓是目標,或者只是雜訊。

首先看圓形偵測的部分,我們有一個長度為5的陣列,每個位置的初始值為None,每次都將在新一幀畫面找到的圓的資訊存入陣列尾端,如果找不到圓則存入None,接著將陣列最前端的元素移除,讓陣列始終保持在長度為5。如此一來我們就有了連續5幀圓形偵測的結果。
假設我們取5張連續的影像,設定一個信心值60%,那麼在這5張影像中,要有3張是包含位置和半徑接近的圓,這幾個圓的最後一個圓才會被當成現在的目標。
執行結果:
當然這個演算法還可以更快,只是這邊我們只取5張影像找到的圓做運算,實際上光是HoughCircles 返回結果的時間就會是這個演算法需要的幾十甚至幾千倍(取決於影像大小),再加上這個方式個人覺得容易理解與維護,所以就不再修改。

如果需要再進一步講解程式內容,或是覺得哪邊有問題,都歡迎詢問。

雖然說不會透漏完整程式碼,但好像重點都貼上來了w

創作回應

終老孤獨死肥仔
請問你的resolution是什麼?
2023-10-06 11:01:36
終老孤獨死肥仔
請問你的resolution是什麼?
2023-10-06 11:01:40
Jerry
只有320*240,原本是640*480但是放到比較慢的設備會跑不太動,而且解析度降下去之後效果也差不多
2023-10-06 12:24:25

相關創作

更多創作