引言

在现代城市中,行人和车辆的检测与计数对交通管理和城市规划具有重要意义。通过使用深度学习技术,可以实现对行人和车辆的实时检测与计数,提高交通管理的效率。本文将详细介绍如何构建一个基于深度学习的行人车辆检测与计数系统,包括环境搭建、数据准备、模型训练、系统实现和用户界面设计等步骤。

系统概述

本系统的实现流程如下:

  1. 环境搭建
  2. 数据收集与处理
  3. 模型训练
  4. 系统实现
  5. 用户界面设计

环境搭建

首先,需要搭建一个适合深度学习的开发环境。本文使用Python 3.8或以上版本,并依赖于多个深度学习和图像处理库。

安装必要的库

使用以下命令安装所需库:

pip install numpy pandas matplotlib opencv-python torch torchvision ultralytics pyqt5
  • 1.

数据收集与处理

数据收集

收集包含行人和车辆的图像数据集,可以从公开的行人和车辆数据集下载,或者通过摄像头自行采集。确保数据集包含不同角度、不同光照条件下的行人和车辆图像。

数据处理

将图像数据整理到指定的文件夹结构,并标注行人和车辆的位置。以下是示例的文件夹结构:

datasets/
    ├── images/
    │   ├── train/
    │   │   ├── image1.jpg
    │   │   ├── image2.jpg
    │   ├── val/
    │   │   ├── image1.jpg
    │   │   ├── image2.jpg
    ├── labels/
        ├── train/
        │   ├── image1.txt
        │   ├── image2.txt
        ├── val/
            ├── image1.txt
            ├── image2.txt
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

每个标签文件的内容如下:

class x_center y_center width height
  • 1.

其中,class表示类别编号(行人和车辆分别有不同的类别编号),x_centery_center为归一化后的中心坐标,widthheight为归一化后的宽度和高度。

模型训练

使用YOLO模型进行训练。

配置文件

创建一个配置文件config.yaml

path: datasets
train: images/train
val: images/val
test: images/test

nc: 2  # 类别数
names: ['person', 'vehicle']
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
训练代码

使用以下代码训练模型:

from ultralytics import YOLO

# 加载模型
model = YOLO('yolov8n.pt')

# 训练模型
model.train(data='config.yaml', epochs=50, imgsz=640, batch=16, lr0=0.01)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

系统实现

训练好的模型可以用于实时行人和车辆检测与计数。使用OpenCV读取视频流,并调用YOLO模型进行检测与计数。

检测与计数代码
import cv2
from ultralytics import YOLO

# 加载训练好的模型
model = YOLO('best.pt')

# 打开视频流
cap = cv2.VideoCapture('traffic_video.mp4')

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    # 检测行人和车辆
    results = model(frame)
    person_count = 0
    vehicle_count = 0
    for result in results:
        bbox = result['bbox']
        label = result['label']
        confidence = result['confidence']

        if label == 'person':
            person_count += 1
        elif label == 'vehicle':
            vehicle_count += 1

        # 画框和标签
        cv2.rectangle(frame, (bbox[0], bbox[1]), (bbox[2], bbox[3]), (0, 255, 0), 2)
        cv2.putText(frame, f'{label} {confidence:.2f}', (bbox[0], bbox[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)

    # 显示计数结果
    cv2.putText(frame, f'Persons: {person_count}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
    cv2.putText(frame, f'Vehicles: {vehicle_count}', (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

    # 显示结果
    cv2.imshow('Pedestrian and Vehicle Detection and Counting', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.

用户界面设计

为了提高系统的易用性,我们设计了一个用户友好的界面。使用PyQt5实现用户界面,提供图像或视频播放和检测计数结果显示。

界面代码

以下是一个简单的PyQt5界面代码示例:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QPushButton, QFileDialog
from PyQt5.QtGui import QPixmap, QImage
import cv2
from ultralytics import YOLO

class PedestrianVehicleDetectionUI(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
        self.model = YOLO('best.pt')
        
    def initUI(self):
        self.setWindowTitle('Pedestrian and Vehicle Detection System')
        self.layout = QVBoxLayout()
        
        self.label = QLabel(self)
        self.layout.addWidget(self.label)
        
        self.button = QPushButton('Open Image or Video', self)
        self.button.clicked.connect(self.open_file)
        self.layout.addWidget(self.button)
        
        self.setLayout(self.layout)
    
    def open_file(self):
        options = QFileDialog.Options()
        file_path, _ = QFileDialog.getOpenFileName(self, "Open File", "", "All Files (*);;MP4 Files (*.mp4);;JPEG Files (*.jpg);;PNG Files (*.png)", options=options)
        
        if file_path:
            if file_path.endswith('.mp4'):
                self.detect_pedestrian_vehicle_video(file_path)
            else:
                self.detect_pedestrian_vehicle_image(file_path)
    
    def detect_pedestrian_vehicle_image(self, file_path):
        frame = cv2.imread(file_path)
        results = self.model(frame)
        person_count = 0
        vehicle_count = 0
        for result in results:
            bbox = result['bbox']
            label = result['label']
            confidence = result['confidence']
                
            if label == 'person':
                person_count += 1
            elif label == 'vehicle':
                vehicle_count += 1

            cv2.rectangle(frame, (bbox[0], bbox[1]), (bbox[2], bbox[3]), (0, 255, 0), 2)
            cv2.putText(frame, f'{label} {confidence:.2f}', (bbox[0], bbox[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)

        cv2.putText(frame, f'Persons: {person_count}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
        cv2.putText(frame, f'Vehicles: {vehicle_count}', (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
        
        height, width, channel = frame.shape
        bytesPerLine = 3 * width
        qImg = QImage(frame.data, width, height, bytesPerLine, QImage.Format_RGB888).rgbSwapped()
        
        self.label.setPixmap(QPixmap.fromImage(qImg))
    
    def detect_pedestrian_vehicle_video(self, file_path):
        cap = cv2.VideoCapture(file_path)
        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                break

            results = self.model(frame)
            person_count = 0
            vehicle_count = 0
            for result in results:
                bbox = result['bbox']
                label = result['label']
                confidence = result['confidence']

                if label == 'person':
                    person_count += 1
                elif label == 'vehicle':
                    vehicle_count += 1

                cv2.rectangle(frame, (bbox[0], bbox[1]), (bbox[2], bbox[3]), (0, 255, 0), 2)
                cv2.putText(frame, f'{label} {confidence:.2f}', (bbox[0], bbox[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)

            height, width, channel = frame.shape
            bytesPerLine = 3 * width
            qImg = QImage(frame.data, width, height, bytesPerLine, QImage.Format_RGB888).rgbSwapped()
            
            self.label.setPixmap(QPixmap.fromImage(qImg))
            QApplication.processEvents()

        cap.release()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = PedestrianVehicleDetectionUI()
    ex.show()
    sys.exit(app.exec_())
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.

总结与声明

本文详细介绍了如何构建一个基于深度学习的行人车辆检测与计数系统。从环境搭建、数据收集与处理、模型训练、系统实现到用户界面设计,提供了完整的实现步骤和代码示例。通过本系统,可以实现对行人和车辆的实时检测与计数,为智能交通管理提供有力支持。