opencv筆記(車輛計數實現)
注意:更準確的車輛計數實現應考慮深度學習。
基本實現思路
- 加載視頻
- 通過形態學識別車輛
- 對車輛進行統計
- 顯示車輛統計信息
涉及知識
- 窗口展示
- 圖像/視頻加載
- 基本圖形的繪制
- 車輛識別
- 基本圖像運算與處理
- 形態學
- 輪廓查找
分步驟代碼
加載視頻
import cv2
# 創建窗口對象
cv2.namedWindow('video', cv2.WINDOW_NORMAL)
cap = cv2.VideoCapture('2.mp4')
while 1:
ok, frame = cap.read()
if ok:
# 窗口顯示
cv2.imshow('video', frame)
key = cv2.waitKey(1)
if key == 27 or cv2.getWindowProperty('color', cv2.WND_PROP_VISIBLE) < 1.0:
break
else:
break
# 釋放資源
cap.release()
cv2.destroyAllWindows()
通過形態學識別車輛
import cv2
# 車輛過濾條件應根據參照物適配,此處僅為演示原理
min_w = 100
min_h = 100
line_high = 200
line_width = 6
cv2.namedWindow('video', cv2.WINDOW_AUTOSIZE)
cap = cv2.VideoCapture('6.ts')
bs = cv2.createBackgroundSubtractorMOG2()
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
cars = []
while 1:
ok, frame = cap.read()
if ok:
# 轉換繪圖圖
cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 高斯去噪
blur = cv2.GaussianBlur(frame, (3, 3), 5)
# 去除背景
mask = bs.apply(blur)
# 腐蝕
erode = cv2.erode(mask, kernel, iterations=2)
# 膨脹
dilate = cv2.dilate(erode, kernel, iterations=2)
# 閉運算
close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel)
close = cv2.morphologyEx(close, cv2.MORPH_CLOSE, kernel)
# 查找輪廓
contours, _ = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 過濾、繪制輪廓,車輛計數
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
# 過濾
if w < min_w or h < min_h:
continue
# 繪制輪廓
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow('video', frame)
key = cv2.waitKey(42)
if key == 27:
break
else:
break
# 釋放資源
cap.release()
cv2.destroyAllWindows()
對車輛進行統計
import cv2
# 車輛過濾條件應根據參照物適配,此處僅為演示原理
min_w = 100
min_h = 100
# 檢測線高度、誤差
line_high = 190
line_offset = 5
cv2.namedWindow('video', cv2.WINDOW_AUTOSIZE)
cap = cv2.VideoCapture('6.ts')
bs = cv2.createBackgroundSubtractorMOG2()
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
car_count = 0
while 1:
ok, frame = cap.read()
if ok:
# 轉換繪圖圖
cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 高斯去噪
blur = cv2.GaussianBlur(frame, (3, 3), 3)
# 去除背景
mask = bs.apply(blur)
# 腐蝕
erode = cv2.erode(mask, kernel, iterations=3)
# 膨脹
dilate = cv2.dilate(erode, kernel, iterations=3)
# 閉運算
close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel)
close = cv2.morphologyEx(close, cv2.MORPH_CLOSE, kernel)
# 查找輪廓
contours, _ = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 繪制檢測線
cv2.line(frame, (0, line_high), (frame.shape[1], line_high), (255, 0, 0), 3)
# 過濾、繪制輪廓,車輛計數
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
# 過濾
if w < min_w or h < min_h:
continue
# 搜集有效車輛(此處有邏輯限制:車輛不能停止于檢測線區域內)
center = y + h / 2
if line_high - line_offset < center < line_high + line_offset:
car_count += 1
# 繪制輪廓
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow('video', frame)
key = cv2.waitKey(42)
if key == 27:
break
else:
break
# 釋放資源
cap.release()
cv2.destroyAllWindows()
顯示車輛統計信息
import cv2
# 車輛過濾條件應根據參照物適配,此處僅為演示原理
min_w = 100
min_h = 100
# 檢測線高度、誤差
line_high = 150
line_offset = 3
cv2.namedWindow('video', cv2.WINDOW_AUTOSIZE)
cap = cv2.VideoCapture('6.ts')
bs = cv2.createBackgroundSubtractorMOG2()
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
car_count = 0
while 1:
ok, frame = cap.read()
if ok:
# 轉換繪圖圖
cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 高斯去噪
blur = cv2.GaussianBlur(frame, (3, 3), 3)
# 去除背景
mask = bs.apply(blur)
# 腐蝕
erode = cv2.erode(mask, kernel, iterations=3)
# 膨脹
dilate = cv2.dilate(erode, kernel, iterations=3)
# 閉運算
close = cv2.morphologyEx(dilate, cv2.MORPH_CLOSE, kernel)
close = cv2.morphologyEx(close, cv2.MORPH_CLOSE, kernel)
# 查找輪廓
contours, _ = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 繪制檢測線
cv2.line(frame, (0, line_high), (frame.shape[1], line_high), (255, 0, 0), 3)
# 過濾、繪制輪廓,車輛計數
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
# 過濾
if w < min_w or h < min_h:
continue
# 搜集有效車輛(此處有邏輯限制:車輛不能停止于檢測線區域內,準確計數應該為每輛車提供唯一標識)
center = y + h / 2
if line_high - line_offset < center < line_high + line_offset:
car_count += 1
# 繪制輪廓
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame, f'Cars: {car_count}', (300, 60), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 3)
cv2.imshow('video', frame)
key = cv2.waitKey(42)
if key == 27:
break
else:
break
# 釋放資源
cap.release()
cv2.destroyAllWindows()
浙公網安備 33010602011771號