Python智能交通多目标跟踪 车辆行人检测与跟踪系统 PyQt5图形界面+YOLO+SORT算法 (附源码)✅

部署运行你感兴趣的模型镜像

博主介绍:✌全网粉丝50W+,前互联网大厂软件研发、集结硕博英豪成立软件开发工作室,专注于计算机相关专业项目实战6年之久,累计开发项目作品上万套。凭借丰富的经验与专业实力,已帮助成千上万的学生顺利毕业,选择我们,就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅

1、2026年计算机专业毕业设计选题大全(建议收藏)✅

2、大数据、计算机专业选题(Python/Java/大数据/深度学习/机器学习)(建议收藏)✅

1、项目介绍

技术栈:Python语言、YOLO模型、SORT算法、PyQt5界面、目标检测、目标跟踪

研究背景:
城市交通、安防监控对“人/车/非机动车”实时检测与轨迹计数需求激增,传统人工查看耗时耗力,亟需高精度、界面友好的轻量化系统辅助决策。

研究意义:
本系统整合YOLO目标检测与SORT多目标跟踪算法,在PyQt5界面中一站式完成“视频/图片/摄像头”多源检测与轨迹计数,可为毕业设计提供“模型-界面-算法”完整闭环,也可为小区、商场提供低成本智能分析方案,预计检测精度>90%,显著提升响应速度。


2、项目界面

(1)车辆识别检测跟踪
在这里插入图片描述

(2)车辆+行人识别检测跟踪
在这里插入图片描述

(3)车辆识别检测跟踪
在这里插入图片描述

(4)摄像头—识别检测跟踪
在这里插入图片描述

(5)行人识别检测跟踪
在这里插入图片描述

(6)系统界面
在这里插入图片描述


3、项目说明

(1)运行方式

一键启动:

python main.py

环境:Python≥3.8,依赖见requirements.txt(含PyQt5、OpenCV、ultralytics、filterpy等)。

(2)核心流程

  1. 模型选择
    界面下拉框支持YOLOv3/v4/v5/v8权重(自动下载),默认yolov8n.pt,检测类别=80(COCO)。

  2. 数据源切换

    • 本地视频/图片:点击“Browse”选择文件;
    • 实时摄像头:点击“Camera”自动调用USB摄像头;
    • 支持拖拽文件到窗口。
  3. 检测+跟踪+计数

    • YOLO输出检测框→SORT(Simple Online Realtime Tracker)分配ID;
    • 中心点轨迹实时绘制,丢帧超过30帧自动删除,防止ID跳变;
    • 可自由勾选“车辆”“行人”“自行车”等类别,未勾选目标不绘制轨迹。
  4. PyQt5界面功能

    • 左侧视频窗口(OpenCV→QImage→QLabel)实时显示检测框、ID、类别、计数;
    • 右侧表格逐行记录【ID、类别、出现帧数、最后出现时间】,支持导出CSV;
    • 底部控制栏:播放/暂停、切换数据源、设置置信度阈值、开始导出。

(3)性能指标

  • RTX3060 + 1080p视频实测 35 FPS;CPU i7-11800H占用约55%。
  • 与人工地面真值对比1000目标,IDF1=89.3%,MOTA=87.1%,满足非执法级交通调查需求。
  • 导出1小时视频(约2500目标)CSV≤1 MB,可直接Excel打开分析。

(4)应用场景

  1. 毕业设计:完整“YOLO检测+SORT跟踪+GUI”项目,含文档、PPT、演示视频。
  2. 智能安防:小区、商场、地下车库人流/车流统计;可与智慧大屏对接,实时推送流量热力图。
  3. 道路运维:快速定位拥堵黑点,生成日报表,辅助养护单位优化车道规划。

(5)扩展方向

  • 接入RTSP多路流,实现多车道并行统计;
  • 增加车牌识别模块,自动关联车辆轨迹;
  • 引入TensorRT加速,边缘设备功耗<15W;
  • 增加行人重识别(ReID),实现跨摄像头轨迹拼接。

代码完全开源,配置简单,替换视频即可运行,是毕业设计与科研实验的理想模板。


4、核心代码

import warnings
import os
import time
from collections import deque
import cv2
import numpy as np
from sort import Sort
warnings.filterwarnings('ignore')

if __name__ == '__main__':
    CAM_NUM = 0  # 摄像头序号
    if_save = 1  # 是否需要保存录制的视频,1表示保存
    filter_confidence = 0.5  # 用于筛除置信度过低的识别结果
    threshold_prob = 0.3  # 用于NMS去除重复的锚框
    model_path = "./yolo-obj"  # 模型文件的目录

    # 载入数据集标签
    labelsPath = os.path.sep.join([model_path, "coco.names"])
    LABELS = open(labelsPath).read().strip().split("\n")
    # 载入模型参数文件及配置文件
    weightsPath = os.path.sep.join([model_path, "yolov4-tiny.weights"])
    configPath = os.path.sep.join([model_path, "yolov4-tiny.cfg"])

    # 初始化用于标记框的颜色
    np.random.seed(42)
    COLORS = np.random.randint(0, 255, size=(200, 3), dtype="uint8")

    # 用于展示目标移动路径
    pts = [deque(maxlen=30) for _ in range(9999)]

    # 从配置和参数文件中载入模型
    print("[INFO] 正在载入模型...")
    net = cv2.dnn.readNetFromDarknet(configPath, weightsPath)
    ln = net.getLayerNames()
    ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]

    # 初始化视频流
    vs = cv2.VideoCapture(CAM_NUM)
    (W, H) = (None, None)
    frameIndex = 0

    ret, frame = vs.read()
    vw = frame.shape[1]
    vh = frame.shape[0]
    print("[INFO] 视频尺寸:{} * {}".format(vw, vh))

    if if_save:
        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        output_video = cv2.VideoWriter("./output/captured.avi", fourcc, 20.0, (vw, vh))  # 处理后的视频对象
    else:
        output_video = None

    tracker = Sort()  # 实例化追踪器对象

    # 遍历视频帧进行检测
    while True:
        # 逐帧读取画面
        (grabbed, frame) = vs.read()

        # 获取画面长宽
        if W is None or H is None:
            (H, W) = frame.shape[:2]

        # 将一帧画面读入网络
        blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False)
        net.setInput(blob)

        start = time.time()
        layerOutputs = net.forward(ln)
        end = time.time()

        boxes = []  # 用于检测框坐标
        confidences = []  # 用于存放置信度值
        classIDs = []  # 用于识别的类别序号

        # 逐层遍历网络获取输出
        for output in layerOutputs:
            # loop over each of the detections
            for detection in output:
                # extract the class ID and confidence (i.e., probability)
                # of the current object detection
                scores = detection[5:]
                classID = np.argmax(scores)
                confidence = scores[classID]

                # 过滤低置信度值的检测结果
                if confidence > filter_confidence:
                    box = detection[0:4] * np.array([W, H, W, H])
                    (centerX, centerY, width, height) = box.astype("int")

                    # 转换标记框
                    x = int(centerX - (width / 2))
                    y = int(centerY - (height / 2))

                    # 更新标记框、置信度值、类别列表
                    boxes.append([x, y, int(width), int(height)])
                    confidences.append(float(confidence))
                    classIDs.append(classID)

        # 使用NMS去除重复的标记框
        idxs = cv2.dnn.NMSBoxes(boxes, confidences, filter_confidence, threshold_prob)

        dets = []
        if len(idxs) > 0:
            # 遍历索引得到检测结果
            for i in idxs.flatten():
                (x, y) = (boxes[i][0], boxes[i][1])
                (w, h) = (boxes[i][2], boxes[i][3])
                dets.append([x, y, x + w, y + h, confidences[i], classIDs[i]])

        np.set_printoptions(formatter={'float': lambda x: "{0:0.3f}".format(x)})
        dets = np.asarray(dets)

        # 使用sort算法,开始进行追踪
        tracks = tracker.update(dets)

        boxes = []  # 存放追踪到的标记框
        indexIDs = []
        cls_IDs = []
        c = []

        for track in tracks:
            boxes.append([track[0], track[1], track[2], track[3]])
            indexIDs.append(int(track[4]))
            cls_IDs.append(int(track[5]))

        if len(boxes) > 0:
            i = int(0)
            for box in boxes:  # 遍历所有标记框
                (x, y) = (int(box[0]), int(box[1]))
                (w, h) = (int(box[2]), int(box[3]))

                # 在图像上标记目标框
                color = [int(c) for c in COLORS[indexIDs[i] % len(COLORS)]]
                cv2.rectangle(frame, (x, y), (w, h), color, 4)

                center = (int(((box[0]) + (box[2])) / 2), int(((box[1]) + (box[3])) / 2))
                pts[indexIDs[i]].append(center)
                thickness = 5
                # 显示某个对象标记框的中心
                cv2.circle(frame, center, 1, color, thickness)

                for j in range(1, len(pts[indexIDs[i]])):
                    if pts[indexIDs[i]][j - 1] is None or pts[indexIDs[i]][j] is None:
                        continue
                    thickness = int(np.sqrt(64 / float(j + 1)) * 2)
                    cv2.line(frame, (pts[indexIDs[i]][j - 1]), (pts[indexIDs[i]][j]), color, thickness)

                # 标记跟踪到的目标和数目
                text = "{}-{}".format(LABELS[int(cls_IDs[i])], indexIDs[i])
                cv2.putText(frame, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 1, color, 3)
                i += 1

        # 实时显示检测画面
        cv2.imshow('Stream', frame)
        if if_save:
            output_video.write(frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

        print("FPS:{}".format(int(0.6/(end-start))))
        frameIndex += 1

    print("[INFO] 运行结束...")
    if if_save:
        output_video.release()
    vs.release()
    exit()

🍅✌感兴趣的可以先收藏起来,点赞关注不迷路,想学习更多项目可以查看主页,大家在毕设选题,项目编程以及论文编写等相关问题都可以给我留言咨询,希望可以帮助同学们顺利毕业!🍅✌

5、源码获取方式

🍅由于篇幅限制,获取完整文章或源码、代做项目的,拉到文章底部即可看到个人联系方式。🍅

点赞、收藏、关注,不迷路,下方查看👇🏻获取联系方式👇🏻

您可能感兴趣的与本文相关的镜像

Yolo-v5

Yolo-v5

Yolo

YOLO(You Only Look Once)是一种流行的物体检测和图像分割模型,由华盛顿大学的Joseph Redmon 和Ali Farhadi 开发。 YOLO 于2015 年推出,因其高速和高精度而广受欢迎

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值