智慧交通day02-车流量检测实现13:基于虚拟线圈法的车辆统计+视频中的车流量统计原理解析
1.基于虛擬線圈法的車輛統計
基于虛擬線圈的車流量統計算法原理與交通道路上的常見的傳統的物理線圈類似,由于物理線圈需要埋設在路面之下,因此會有安裝、維護費用高,造成路面破壞等問題,而采用基于視頻的虛擬線圈的車輛計數方法完全避免了以上問題,且可以針對多個感興趣區域進行檢測。
虛擬線圈車輛計數法的原理是在采集到的交通流視頻中,在需要進行車輛計數的道路或路段上設置一條或一條以上的檢測線對通過車輛進行檢測,從而完成計數工作。檢測線的設置原則一般是在檢測車道上設置一條垂直于車道線,居中的虛擬線段,通過判斷其與通過車輛的相對位置的變化,完成車流量統計的工作。如下圖所示,綠色的線就是虛擬檢測線:
在該項目中我們進行檢測的方法是,計算前后兩幀圖像的車輛檢測框的中心點連線,若該連線與檢測線相交,則計數加一,否則計數不變。
那怎么判斷兩條線段是否相交呢?
假設有兩條線段AB,CD,若AB,CD相交,我們可以確定:
1.線段AB與CD所在的直線相交,即點A和點B分別在直線CD的兩邊;
2.線段CD與AB所在的直線相交,即點C和點D分別在直線AB的兩邊;
上面兩個條件同時滿足是兩線段相交的充要條件,所以我們只需要證明點A和點B分別在直線CD的兩邊,點C和點D分別在直線AB的兩邊,這樣便可以證明線段AB與CD相交了。
在上圖中,線段AB與線段CD相交,于是我們可以得到兩個向量AC,AD,C和D分別在AB的兩邊,向量AC在向量AB的逆時針方向,AB×AC > 0;向量AD在向量AB的順時針方向,AB×AD < 0,兩叉乘結果異號。
這樣,方法就出來了:如果線段CD的兩個端點C和D,與另一條線段的一個端點(A或B,只能是其中一個)連成的向量,與向量AB做叉乘,若結果異號,表示C和D分別在直線AB的兩邊,若結果同號,則表示CD兩點都在AB的一邊,則肯定不相交。
所以我們利用叉乘的方法來判斷車輛是否經過檢測線。
2.基于虛擬線圈法的實現
實現車流量檢測的代碼如下:
1.檢測AB和CD兩條直線是否相交
# 檢測AB和CD兩條直線是否相交 def intersect(A, B, C, D):return ccw(A, C, D) != ccw(B, C, D) and ccw(A, B, C) != ccw(A, B, D)# 計算有A,B,C三點構成的向量CA,BA之間的關系, def ccw(A, B, C):return (C[1] - A[1]) * (B[0] - A[0]) > (B[1] - A[1]) * (C[0] - A[0])遍歷跟蹤框判斷其與檢測線是否相交,并進行車輛計數
總結
前面我們已經完成了視頻中車輛的檢測功能,下面我們對車輛進行跟蹤,并將跟蹤結果繪制在視頻中。
2.視頻中的車流量統計
主要分為以下步驟:
- 對目標進行追蹤
- 繪制車輛計數結果
- 將檢測結果繪制在視頻中并進行保存
1.對目標進行追蹤
# yolo中檢測結果為0時,傳入跟蹤器中會出現錯誤,在這里判斷下,未檢測到目標時不進行目標追蹤if np.size(dets) == 0:continueelse:tracks = tracker.update(dets) # 將檢測結果傳入跟蹤器中,返回當前畫面中跟蹤成功的目標,包含五個信息:目標框的左上角和右下角橫縱坐標,目標的置信度# 對跟蹤器返回的結果進行處理boxes = [] # 存放tracks中的前四個值:目標框的左上角橫縱坐標和右下角的橫縱坐標indexIDs = [] # 存放tracks中的最后一個值:置信度,用來作為memory中跟蹤框的Keyprevious = memory.copy() # 用于存放上一幀的跟蹤結果,用于碰撞檢測memory = {} # 存放當前幀目標的跟蹤結果,用于碰撞檢測# 遍歷跟蹤結果,對參數進行更新for track in tracks:boxes.append([track[0], track[1], track[2], track[3]]) # 更新目標框坐標信息indexIDs.append(int(track[4])) # 更新置信度信息memory[indexIDs[-1]] = boxes[-1] # 將跟蹤框以key為:置信度,value為:跟蹤框坐標形式存入memory中繪制車輛計數的相關信息
將結果保存在視頻中
# 未設置視頻的編解碼信息時,執行以下代碼if writer is None:# 設置編碼格式fourcc = cv2.VideoWriter_fourcc(*"mp4v")# 視頻信息設置writer = cv2.VideoWriter("./output/output.mp4",fourcc,30,(frame.shape[1], frame.shape[0]),True)# 將處理后的幀寫入到視頻中writer.write(frame)# 顯示當前幀的結果cv2.imshow("", frame)# 按下q鍵退出if cv2.waitKey(1) & 0xFF == ord('q'):break總結
對目標進行追蹤
繪制車輛計數的相關信息
將結果保存在視頻中
總結
以上是生活随笔為你收集整理的智慧交通day02-车流量检测实现13:基于虚拟线圈法的车辆统计+视频中的车流量统计原理解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习(1606):数据请求与json
- 下一篇: 前端学习(1735):前端系列javas