目录
概要
代码说明
1. 导入库
2. 加载预训练的车辆检测模型
3. 读取视频
4. 初始化变量
5. 逐帧处理视频
6. 处理帧
7. 处理检测结果
8. 计算框的坐标
9. 检查车辆中心是否已计数
10. 绘制检测框
11. 显示车流量
12. 退出条件
13. 释放资源
整体代码
效果展示
可拓展的地方
总结
概要
实时车辆检测和计数,利用 YOLO 模型的快速检测能力,通过距离阈值来减少重复计数的问题。代码结构清晰,易于理解,并为后续功能扩展(如目标跟踪)提供了基础。
代码说明
1. 导入库
import cv2
import numpy as np
cv2
是 OpenCV 库,用于计算机视觉任务。numpy
是一个用于处理数组和矩阵的库,特别适合进行数值计算。
2. 加载预训练的车辆检测模型
net = cv2.dnn.readNet("../needFiles/yolov3.weights", "../needFiles/yolov3.cfg")
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]
cv2.dnn.readNet
加载 YOLO 模型的权重和配置文件。getLayerNames
获取模型的所有层的名称。getUnconnectedOutLayers
返回未连接的输出层的索引,并用这些索引生成output_layers
列表。
3. 读取视频
cap = cv2.VideoCapture("./videos/test1.mp4")
- 使用
cv2.VideoCapture
打开视频文件,准备逐帧读取。
4. 初始化变量
car_count = 0
detected_centers = [] # 用于存储已检测车辆的中心位置
distance_threshold = 50 # 设置距离阈值
car_count
用于统计检测到的车辆数量。detected_centers
列表存储已检测车辆的中心位置,以避免重复计数。distance_threshold
设置检测车辆中心位置的距离阈值。
5. 逐帧处理视频
while cap.isOpened():ret, frame = cap.read()if not ret:break
- 使用
while
循环逐帧读取视频。 cap.read()
返回布尔值ret
和当前帧frame
,当读取完成时,跳出循环。
6. 处理帧
height, width, _ = frame.shape
blob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)
outputs = net.forward(output_layers)
- 获取当前帧的高度和宽度。
cv2.dnn.blobFromImage
将帧转换为模型可以处理的 blob 格式。setInput
设置输入层。forward
方法执行前向传播,获取检测结果。
7. 处理检测结果
for output in outputs:for detection in output:scores = detection[5:]class_id = np.argmax(scores)confidence = scores[class_id]if confidence > 0.5: # 置信度阈值
- 遍历模型的输出结果。
- 提取每个检测结果的置信度分数,并找到最大置信度对应的类别。
- 设置置信度阈值(0.5),只处理高置信度的检测。
8. 计算框的坐标
center_x = int(detection[0] * width)
center_y = int(detection[1] * height)
w = int(detection[2] * width)
h = int(detection[3] * height)
- 计算检测框的中心坐标和宽高,归一化的值需要乘以帧的宽度和高度。
9. 检查车辆中心是否已计数
if all(np.linalg.norm(np.array(center) - np.array(dc)) > distance_threshold for dc in detected_centers):detected_centers.append(center) # 添加到已检测集合car_count += 1 # 计数
- 使用距离计算,确保新检测的车辆中心位置与已检测车辆的中心之间的距离大于阈值。
- 如果符合条件,则将新中心添加到
detected_centers
并增加计数。
10. 绘制检测框
cv2.rectangle(frame, (center_x - w // 2, center_y - h // 2),(center_x + w // 2, center_y + h // 2), (0, 255, 0), 2)
- 使用
cv2.rectangle
在检测到的车辆周围绘制绿色矩形框。
11. 显示车流量
cv2.putText(frame, f"Car Count: {car_count}", (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
cv2.imshow("Video", frame)
- 在视频帧上绘制当前车辆计数的文本。
- 使用
cv2.imshow
显示处理后的帧。
12. 退出条件
if cv2.waitKey(1) & 0xFF == ord('q'):break
- 等待按键,如果按下 'q' 则退出循环。
13. 释放资源
cap.release()
cv2.destroyAllWindows()
- 释放视频捕捉对象并关闭所有 OpenCV 窗口。
整体代码
import cv2
import numpy as np# 加载预训练的车辆检测模型
net = cv2.dnn.readNet("../needFiles/yolov3.weights", "../needFiles/yolov3.cfg")
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]# 读取视频
cap = cv2.VideoCapture("./videos/test1.mp4")# 车流量计数
car_count = 0
detected_centers = [] # 用于存储已检测车辆的中心位置
distance_threshold = 50 # 设置距离阈值while cap.isOpened():ret, frame = cap.read()if not ret:break# 处理帧height, width, _ = frame.shapeblob = cv2.dnn.blobFromImage(frame, 0.00392, (416, 416), (0, 0, 0), True, crop=False)net.setInput(blob)outputs = net.forward(output_layers)# 处理检测结果for output in outputs:for detection in output:scores = detection[5:]class_id = np.argmax(scores)confidence = scores[class_id]if confidence > 0.5: # 置信度阈值# 计算框的坐标center_x = int(detection[0] * width)center_y = int(detection[1] * height)w = int(detection[2] * width)h = int(detection[3] * height)center = (center_x, center_y)# 检查车辆中心是否已经被计数# 判断与已检测车辆的距离if all(np.linalg.norm(np.array(center) - np.array(dc)) > distance_threshold for dc in detected_centers):detected_centers.append(center) # 添加到已检测集合car_count += 1 # 计数# 画框cv2.rectangle(frame, (center_x - w // 2, center_y - h // 2),(center_x + w // 2, center_y + h // 2), (0, 255, 0), 2)# 显示当前车流量cv2.putText(frame, f"Car Count: {car_count}", (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)cv2.imshow("Video", frame)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()
cv2.destroyAllWindows()
效果展示
车流效果展示
可拓展的地方
-
目标跟踪:
- 使用目标跟踪算法(如 SORT 或 Deep SORT)来持续跟踪车辆,避免在视频中重复计数。
-
检测其他对象:
- 扩展模型以检测其他对象(如行人、摩托车等),并相应地更新计数。
-
统计功能:
- 实现更详细的统计信息,如不同类型车辆的计数、车速估算等。
-
数据记录与分析:
- 将检测结果和车辆信息存储到文件或数据库中,以便后续分析和可视化。
-
实时警报:
- 根据特定条件(如车流量过高)触发警报或通知。
-
可视化优化:
- 优化界面显示,例如添加图表展示车流量变化、使用不同颜色区分不同类型车辆等。
-
用户界面:
- 创建一个图形用户界面(GUI),让用户能够选择视频文件、设置参数、查看统计信息。
-
多摄像头支持:
- 扩展系统以支持多摄像头输入,整合不同角度的车流数据。
-
深度学习模型更新:
- 集成自定义训练的模型,以提高特定场景下的检测准确率。
-
环境适应:
- 增加对不同光照和天气条件下的自适应处理能力,提高鲁棒性。
总结
我不爱总结。。。。开玩笑的,但我不总结