opencv案例: 车辆检测
生活随笔
收集整理的這篇文章主要介紹了
opencv案例: 车辆检测
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
opencv案例: 車輛檢測
說明:這是在嗶哩嗶哩上看李超老師的視頻時,他講的案例,我是搬運工。
-
實現功能:
1、識別出圖片中的汽車對象
2、對車輛進行統計,并將統計結果展示出來 -
涉及到的知識點:
圖像和視頻的加載、展示;
基本圖像繪制;
基本圖像運算與處理;
形態學處理(比如降噪、腐蝕膨脹);
輪廓查找。
- 實現代碼 import cv2
import numpy as npcap = cv2.VideoCapture(r'C:\Users\25584\Desktop\video.mp4') #加載視頻文件, 第十九章知識點
bgsubmog = cv2.bgsegm.createBackgroundSubtractorMOG() #視頻去背景,第二十一章知識點
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5)) #設置形態學處理的kernel,5x5的矩形即可,第八章知識點min_w = 90 #大輪廓和小輪廓的分界點
min_h = 90 #大輪廓和小輪廓的分界點
cars = [] #汽車輪廓的中心點坐標
line_height = 580 #紅計數線位置
offset = 7 #計數線上下的偏移量
carnum = 0 #車輛計數#------------用while循環讀取視頻中的圖像幀并處理------------
while True: #如果讀取成功就將捕獲的視頻幀顯示在video窗口里,如果讀取不成功就打印出warning,并退出循環ret, frame = cap.read() #cap對象的.read()方法if ret:cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #轉成灰度圖像blur = cv2.GaussianBlur(frame, (3,3), 5,5) #高斯平滑去噪,第七章知識點mask = bgsubmog.apply(blur) #去背景,背景去掉后,留下都是動的物體,比如汽車、刮風動的樹、草等,下面是形態學處理去除樹和草erode = cv2.erode(mask, kernel) #腐蝕,去掉小的斑塊,腐蝕后草就不見了,樹有時還能看到dilate = cv2.dilate(erode, kernel, iterations=3) #膨脹3次,還原放大,因為腐蝕后物體變小了,不利于我們計算。close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel, iterations=2) #閉操作2次,去掉汽車內部的小塊 Acnts, h = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) #查找輪廓,就是找到每一個移動的汽車了for c in cnts: #遍歷這些輪廓(x,y, w,h) = cv2.boundingRect(c) #給每個輪廓圈上矩形框,這樣輪廓就變成xywh四個參數了isValid = (w>=min_w) and (h>=min_h) #去除小輪廓,比如車燈的輪廓,我們不需要。判斷如果矩形框的最小寬高小于90,就是小輪廓,就忽略continueif not isValid:continue #寬高小于90的就忽略,跳過,繼續循環;如果大于90,就是有效的車輛,就把這個矩形框的中心點記下來cv2.rectangle(frame, (x,y), (x+w, y+h), (0,0,255), 2) #在原圖上,把大輪廓用紅色矩形框圈出來x1 = int(w/2) #計算大輪廓的中心點,也就是矩形框的中心點,并把中心點都放到cars里面y1 = int(h/2)cx = x + x1cy = y + y1cpoint = (cx, cy)cars.append(cpoint)cv2.line(frame, (10,line_height), (1200, line_height), (255,255,0),2) #畫一條計數線,穿過計數線的車就計數for (x,y) in cars: #看cars里面的中心點是否在計數線的附近,就是車經過了這個計數線我們就計數 if (y<(line_height+offset) and y>(line_height-offset)):carnum +=1cars=[]cv2.putText(frame, 'Cars Count:'+str(carnum), (100, 70), cv2.FONT_HERSHEY_SIMPLEX, 2, (255,0,255), 5) #第18章知識點,講計數結果顯示在視頻上cv2.imshow('video', frame) else:print('warning: video is not load correctly or the video is finished')breakkey = cv2.waitKey(1) #每一幀圖像就顯示一毫秒就可以,然后繼續循環if key == 27: #27是esc的ascall碼break
cap.release() #釋放視頻資源
cv2.destroyAllWindows() #釋放窗口資源
解釋:A:膨脹3次后我們發現汽車中間還有一些小斑塊,這些斑塊也要去掉,因為這些小斑塊影響后面對汽車畫輪廓,有斑塊輪廓就很亂,所以要把汽車內部的小斑塊也去掉,就用閉操作去斑塊。
總結: 本案例的車輛檢測方法是最傳統的一種方法,如果車輛計數不準確了,要么是我們的計數線設置的位置不合適,位置太低,從下往上的車可能就檢測不到;要么就是計數線上下的偏移量設置得不合適,過寬會出現重復計數,過窄容易漏計。所以這種方法的效果也是一般,最主要的原因還是我們在統計車輛的時候,無法對每個車輛做一個唯一的標識。由于視頻是連續的,如果車輛行駛的過快,我們很可能捕捉不到,出現漏計;如果車輛行駛的很慢,我們就可能捕捉它兩次甚至更多次,就出現重復計數。這是傳統車輛檢測方法的最重要的一個弊端?,F在我們一般都采用深度學習算法去檢測,我們通過訓練數據建立一個模型,用模型判斷每輛車并且判斷從進入視野到出了視野同一輛車有唯一一個標識,也就是現實車輛的追蹤的效果,這樣就不會漏記和重復計數。
總結
以上是生活随笔為你收集整理的opencv案例: 车辆检测的全部內容,希望文章能夠幫你解決所遇到的問題。