之前有手動一個一個影片看的方式查看大型重機檢核的觀察影片,發現小型車的數據遺漏了很多,那時候就想應該可以用程式的方式抓出「未保持安全車距」這個違規。但是沒有實際動手做就不了了之。
今天回想到這件事情,就在壓力之下在網路上找了一個 python + opencv motion detection 的程式碼來跑看看,發現竟然會 work,就拿著這份 code 去改,改成可以 detect 車輛車距的程式。
先講 motion detection 的部分,原理很簡單,基本上背景是不會動的,因此我們可以把每個畫面灰階化、高斯模糊後,與背景相減取得 delta,然後二值化、膨脹,就可以找出每個物體的邊框。
那要怎麼樣抓出車距呢?我一開始的想法是認為,先畫出一條線,當第一輛車通過後 (負緣觸發) 記錄下時間,等到第二輛車通過 (正緣觸發) 就可以透過兩個時間 * 時速算出距離。問題是我們不知道時速,這部分就只能夠透過假設的方式認定車速會高於最低速限,低於最高速限。但這樣好像有點不妥當,不夠精確。
第二個想法是,畫出兩條線,間距 10 公尺 (最低車距),在車道中剛好是一黑一白,當兩條線都被 motion detect 的 rectangle 壓到的時候,就代表車距不足。這個就不必依賴於速限,同時又能夠抓出車距不足的問題。只是會有 false positive,下面會再提到。
前面這個想法還要先解決一個問題:怎麼判斷 rectangle 通過給定的線?在這邊給定的線其實只是用 opencv 透過兩個點畫上去的而已。屏除掉艱澀的幾何算法,我們可以透過 Bresenham’s line algorithm 把兩點之間的直線點都算出來,算出來就能夠每次暴力的對每個偵測出來的 rectangle 去算直線中的點有沒有在 rectangle 裡面。至於時間複雜度……反正我們知道直線點很少,rectangle 也很少,還可以將就著用。
將所有的所需都完成後,我們就能夠用程式去跑,直接抓出可能的違規影像,例如說:
當然,也有很多 false positive,例如說:
到現在只有跑了兩個影片,但是感覺 CP 值不高。每個影片都要重新設定線段,大概要花 5 分鐘。接著再花 5 分鐘跑完一整個小時的影片。接著花 20 分鐘從所有抓出來的照片中挑選在高公局檢核小組裡面遺漏的部分。以兩個片段而言這次遺漏了 15 輛小型車違規。但是只會增加小型車 0.06% 的違規率。假設每個都遺漏這麼多好了,全部 18 個影片也只會增加 0.54% 的違規率而已。從 1.5% 變成 2.04%,操作起來的 CP 值真的不高。
Leave a Reply