博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业项目实战6年之久,选择我们就是选择放心、选择安心毕业✌
> 🍅想要获取完整文章或者源码,或者代做,拉到文章底部即可与我联系了。🍅

点击查看作者主页,了解更多项目!

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

1、毕业设计:2025年计算机专业毕业设计选题汇总(建议收藏)✅

2、大数据毕业设计:2025年选题大全 深度学习 python语言 JAVA语言 hadoop和spark(建议收藏)✅

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

1、项目介绍

深度学习车流量监测统计系统 YOLOv8模型 智慧交通大数据 多目标跟踪算法 毕业设计

技术栈:
Python语言、COCO2017数据集、YOLOv8模型、自定义区域、车流量监控计数

本项目是面向智慧交通领域与毕业设计需求开发的深度学习车流量监测统计系统,以 Python 为开发语言,核心采用 YOLOv8 目标检测模型,结合 COCO2017 数据集与多目标跟踪算法,构建具备自定义检测区域、精准车流量计数、可视化监测的完整解决方案,可应用于城市道路管控、高速车流统计、交通枢纽调度等场景,兼具技术创新性与实际应用价值,符合毕业设计的技术深度与功能完整性要求。​
技术架构上,项目以 YOLOv8 模型为核心驱动力 —— 作为 YOLO 系列的先进版本,其在目标检测精度与实时性上表现优异,能高效识别视频流中的车辆目标,搭配多目标跟踪算法,可避免车辆因遮挡、跨帧移动导致的计数遗漏;COCO2017 数据集为模型训练提供充足支撑,涵盖丰富的车辆样本,确保模型对不同车型、路况的泛化能力;同时依托 Python 的灵活性,实现各模块的高效协同,为车流量监测提供稳定技术基础。​
核心功能聚焦 “自定义区域划定 - 车流量精准计数 - 结果可视化呈现” 全流程。系统支持通过运行find_region_and_exec.py文件加载指定视频(可在第 39 行修改视频路径),用户通过键盘与鼠标操作划定检测区域:敲击空格键暂停视频并进入编辑界面,鼠标左键选点、右键删点、滚轮结束当前区域绘制,且需遵循 “先左后右” 划定规则避免计数颠倒,完成两个四边形区域划定后按 ESC 键,系统自动调用car_count.py执行推理(约 10 秒),随后弹出监测画面并统计车流量。此外,系统能实时记录左右区域车辆数量,精准反馈道路车流变化,为交通管控提供数据支撑。​
界面设计贴合实用需求,监测画面清晰展示自定义区域与车流量统计结果,操作流程虽需遵循特定步骤,但通过详细说明降低了使用门槛。整体而言,该项目将深度学习技术与智慧交通需求深度融合,技术路线清晰、功能落地性强,既满足毕业设计的学术规范,又能为实际交通流量监测提供有效解决方案。

2、项目界面

(1)自定义检测区域
在这里插入图片描述

(2)车流量监测统计
在这里插入图片描述

(3)自定义检测区域

在这里插入图片描述

(4)车流量监测统计

在这里插入图片描述

(5)车流量监测统计
在这里插入图片描述

3、项目说明

(1)配置好运行环境之后,运行【find_region_and_exec.py文件】,
运行该py文件会加载目录video中的视频,然后程序会播放该视频,敲击键盘空格键,视频会暂停播放,再次敲击空格键,会进入编辑界面,然后就可以在画面上划定区域了。
(如需要加载自己的视频,请在该find_region_and_exec.py文件第39行修改文件路径源码)

按照下面的步骤进行区域划定:
1 鼠标左键点击选点
2 鼠标右键点击删除点
3 点击滚轮,结束当前区域绘制,开始下个区域绘制
4 按 ESC 退出

特别注意:
要先划视频左边的区域,再划视频右边的区域,否则后续车流量统计左边右边道路的统计数会反掉
(左边道路的车数量在右边显示,右边道路的车数量在左边显示)只要按照先左后右就可以避免这个问题。

例如,划定两个四边形区域的操作步骤如下:
第一次鼠标左键(画第一个点),
第二次鼠标左键(画第二个点,此时第一个点与第二点之间自动划线),
第三次鼠标左键(画第三个点,此时第二个点与第三点之间自动划线),
第四次鼠标左键(画第四个点,此时第三个点与第四点之间自动划线),
第五次鼠标左键(一定要与第一个点大致重合)。
然后点击鼠标中间的滚轮,第一个四边形区域划定完毕,开始第二个区域划定:
第一次鼠标左键(画第一个点),
第二次鼠标左键(画第二个点,此时第一个点与第二点之间自动划线),
第三次鼠标左键(画第三个点,此时第二个点与第三点之间自动划线),
第四次鼠标左键(画第四个点,此时第三个点与第四点之间自动划线),
第五次鼠标左键(一定要与第一个点大致重合)。
然后然后点击鼠标中间的滚轮,第二个四边形区域划定完毕。
之后。敲击键盘ESC键,程序会自动执行car_count.py程序进行推理,大概等待10秒左右,画面会自动弹出。

4、核心代码


# -*- encoding: utf-8 -*-





import cv2
import time
import numpy as np
import argparse
import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"


from ultralytics import YOLO

def exec_inference_video(file_path,region_1,region_2):
    # 可以使用yolo原始权重,也可以用直接使用onnx格式的权重加速推理
    # 但请注意目标追踪是建立在目标检测的基础之上,它比单纯的目标检测更耗费算力,用cpu跑很慢,即使是用onnx加速,推理速度也无法比拟在gpu、npu上的速度
    # 推荐电脑有gpu的话,安装gpu的pytorch在gpu上跑,电脑没有gpu的的话,用onnx格式跑
    # 特别注意:电脑有gpu的话不要安装成了cpu版本的pytroch,否则根本没有用gpu跑,用的还是cpu,速度还是很慢
    # 特别注意:直接 pip install torch 安装的是cpu版本的torch,即使电脑有显卡因为安装的是cpu版的torch所以还是用的cpu跑的,推理速度照样很慢
    # 安装gpu版本的torch 首先要在电脑上安装nivida显卡驱动,然后在https://pytorch.org/ 网站 根据自己的情况选择操作系统、cuda版本 生成torch安装命令
    # 比如我的电脑操作系统windows、有英伟达显卡、显卡驱动装好、cuda版本为11.8,pip安装gpu版本的torch的命令为:
    # pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118

    # model = YOLO("./yolov8n.onnx") #cpu
    model = YOLO("weights/yolov8l.pt")  # gpu

    # 基本逻辑:车辆从视频顶部往下部行走并进入区域,视为 下行 low;从视频画面下部往上部行走并进入区域,视为 上行 up。
    # 加载要使用的视频
    kamera = cv2.VideoCapture(file_path)
    font = cv2.FONT_HERSHEY_DUPLEX

    # 获取视频的高度与宽度
    weight, height = kamera.get(3), kamera.get(4)
    print(weight)
    print(height)

    # 注意opencv的坐标系是从左上方开始的,向下为y轴,向右为x轴

    start_y = int(height / 2)
    start_x = int(0)
    end_y = int(height / 2)
    end_x = int(weight)

    # 注意区域的位置应该根据视频而定,不是一成不变的
    # 这个区域在我这个视频中适用,但是换成其他的视频(比如视频画面是倾斜的)极有可能不适用,需要根据具体的视频设置具体的区域的位置
    # low 下行区域 左边区域
    region1 = np.array(region_1)
    region1 = region1.reshape((-1, 1, 2))

    # up 上行区域 右边区域

    region2 = np.array(region_2)
    region2 = region2.reshape((-1, 1, 2))

    # 下行的车辆id保存在这个变量中
    low_id = set()
    # 上行车辆的id保存在这个变量中
    up_id = set()

    while True:
        # 逐渐帧读取视频内容
        ret, frame = kamera.read()
        if not ret:
            break
        # opnecv读取的图片色彩空间为BGR,我们把它转化成RGB
        rgb_img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

        # 使用yolo8的追踪模式(采用byte-tracker多目标跟踪算法)
        results = model.track(rgb_img, persist=True,tracker="bytetrack.yaml", verbose=False)
        # 遍历yolo的处理结果,结果全部保存在返回的results(list类型)变量中,里面保存着结果信息,可以打印一下看一看(打印results[0])
        for i in range(len(results[0].boxes)):
            
            # 框的四个坐标位置
            x1, y1, x2, y2 = results[0].boxes.xyxy[i]
            # 置信度
            score = results[0].boxes.conf[i]
            # 类别标签label
            cls = results[0].boxes.cls[i]
            # print(cls)

            # 识别对象的id,可能为None
            ids = results[0].boxes.id[i]
            if ids == None:
                continue
            
            #
            # try:
            #     ids = results[0].boxes.id[i]
            #     # print(ids)
            # except:
            #     continue

            # float转化int
            x1, y1, x2, y2, score, cls, ids = int(x1), int(y1), int(x2), int(y2), float(score), int(cls), int(ids)

            # 设置0.1阈值,只有高于这个阈值,后续才会被标记,进入区域才会被计数
            if score < 0.1:
                continue
            # cls=2,5,7代表小汽车、公交车、大卡车,这有这几个后续才会被标记,进入区域才会被计数
            if cls not in (2, 5, 7):
                continue
            # 计算物体中心位置的坐标
            cx = int(x1 / 2 + x2 / 2)
            cy = int(y1 / 2 + y2 / 2)

            # 将识别的物体 用框标记出来
            cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2)
            # 将识别的物体用圆标记出来
            # cv2.circle(frame, (cx, cy), 4, (0, 255, 255), -1)

            # 判断从视频顶部进入画面的物体的中心位置与区域1的关系(在内部还是外部)
            inside_region1 = cv2.pointPolygonTest(region1, (cx, cy), False)

            # inside_region1为1表示在区域内部
            if inside_region1 > 0:
                low_id.add(ids)

            inside_region2 = cv2.pointPolygonTest(region2, (cx, cy), False)

            if inside_region2 > 0:
                up_id.add(ids)
        # 统计进出物体,并设置为字符串,下一步准备在画面上显示
        first_low = 'LOW:' + str(len(low_id))
        first_up = 'UP:' + str(len(up_id))

        # 设置画面左右上角的背景色
        frame[0:40, 0:120] = (102, 0, 153)
        frame[0:40, end_x - 120:end_x] = (102, 0, 153)
        # 将进出物体统计的个数输出到图片,展示
        cv2.putText(frame, first_low, (0, 30), font, 1, (255, 255, 255), 1)
        cv2.putText(frame, first_up, (end_x - 120, 30), font, 1, (255, 255, 255), 1)

        # 显示两个区域
        zeros = np.zeros((frame.shape), dtype=np.uint8)
        mask1 = cv2.fillPoly(zeros, [region1], color=(255, 0, 0))
        mask2 = cv2.fillPoly(zeros, [region2], color=(0, 255, 0))
        frame1 = cv2.addWeighted(frame, 1, mask1, 0.3, 0)
        frame2 = cv2.addWeighted(frame1, 1, mask2, 0.05, 0)
        # 逐帧显示处理后的画面
        cv2.imshow("frame", frame2)

        if cv2.waitKey(1) & 0xFF == ord("q"):
            break

    kamera.release()
    cv2.destroyAllWindows()

def parse_option():
    parser = argparse.ArgumentParser()
    parser.add_argument('--file_path', type=str)
    parser.add_argument('--region1', type=str)
    parser.add_argument('--region2', type=str)
    opt = parser.parse_args()
    return opt
if __name__=='__main__':
    opt=parse_option()
    file_path=opt.file_path
    region1=eval(opt.region1)
    region2=eval(opt.region2)
    exec_inference_video(file_path,region1,region2)

5、源码获取方式

🍅由于篇幅限制,获取完整文章或源码、代做项目的,查看【用户名】、【专栏名称】就可以找到我啦🍅

感兴趣的可以先收藏起来,点赞、关注不迷路,下方查看👇🏻获取联系方式👇🏻

更多推荐