2024年研究生数学建模“华为杯”E题——肘部法则、k-means聚类、目标检测(python)、ARIMA、逻辑回归、混淆矩阵(附:目标检测代码)

文章目录

  • 一、情况介绍
  • 二、思路情况
  • 二、代码展示
  • 三、感受

一、情况介绍

前几天也是参加了研究生数学建模竞赛(也就是华为杯),也是和本校的两个数学学院的朋友在网上组的队伍。昨天(9.25)通宵干完论文(一条烂命就是干!),我们选择的是E题,题目内容简单点就是,高速公路上可能会堵车,对堵车情况进行预测,并且启动应急车道舒缓交通压力,通过的是4个监测点的视频。
emmm,这次比赛我想法是,队长担任模型,我是负责出图、做软件(知道我的人应该清楚,我本科就是软件),结果比赛第二天下午的时候,论文进展几乎为0,我就清楚了,这个队伍没有一个适合的模型,然后我就上了,当一次“不正规”的模型(至于为什么不正规,我下面会讲,不过也是圆梦了我本科的一个想法,就是软件转模型,当一次模型)

二、思路情况

这里我就不展示我的摘要了,哈哈哈哈,当然我的摘要,也是被指导老师夸奖了。
这里我说下思路情况:
对于第一问第一小问首先就是数据获取,和队友讨论下,确定了三个参数:车流量、车速、车流密度。(原本是想继续加的,但是实在想不到什么比较好的参数),嗯花了2天时间数据才处理完成,中间磕磕绊绊,出的数据都不符合实际,最后准备造的时候,发现出的数据正常了,然后出成折线图,对各个时间段的各参数的情况进行分析。比如什么时段到什么时段车速多少、车密度和之前对比怎么样。第二小问,首先使用肘部法则,确定聚类数(我看下图,确定为5),之后使用k-means聚类聚5类,最后按照数据使用ARIMA时间序列模型,预测5分钟的数据。第三小问,使用交叉验证验证有效性。

对于第二问:先说下,对于这题重点是,提供理论依据,想了下又需要第一问产生关联,所以就是介绍了基于时间序列预测结果的逻辑回归模型,并且都是二分类问题,把理论依据给说明了

对于第三问第一小问,就是首先用k-means聚类两类,之后使用逻辑回归,两者进行对比。第二小问,量化的话,我们使用了混淆矩阵,放入k-means作为真实值,逻辑回归作为预测值,带入混淆矩阵。

对于第四问:我乍一看,再一分析,我以为是最优化问题,有目标函数,也有约束条件。但是约束条件太空洞了。没有什么预算之类的,反正我没想到怎么搞,最后是确定预测精度随着时间的变化,确定安装视频监控点的位置。

二、代码展示

对于问题一,使用yolov5算法对视频数据进行检测

import torch
import cv2
import numpy as np
import matplotlib.pyplot as plt
import os
import pandas as pd
from scipy.spatial import distance
import warnings

# 忽略特定的FutureWarning
warnings.filterwarnings('ignore', category=FutureWarning)

# 加载YOLOv5模型
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)

# 定义观测区域的长度(单位:公里),假设为50米
observation_length = 0.05  # 50米等于0.05公里

# 初始化OpenCV的多目标追踪器
tracker = cv2.legacy.MultiTracker_create()

# 追踪车辆的结构
class Vehicle:
    def __init__(self, bbox, tracker):
        self.bbox = bbox  # 车辆的检测框
        self.tracker = tracker  # 对应的追踪器
        self.positions = []  # 存储每帧车辆中心的位置

    def add_position(self, center):
        self.positions.append(center)

    def calculate_speed(self, fps):
        # 如果追踪到的点少于2个,无法计算速度
        if len(self.positions) < 2:
            return 0
        # 计算速度,根据前后位置和时间差
        prev_center = self.positions[-2]
        current_center = self.positions[-1]
        pixel_distance = distance.euclidean(prev_center, current_center)
        speed = (pixel_distance / 1000) * fps / observation_length  # km/h
        return speed

# 初始化车辆列表
vehicles = []


def process_video_yolov5(video_path):
    cap = cv2.VideoCapture(video_path)
    if not cap.isOpened():
        print(f"无法打开视频文件 {video_path}")
        return

    fps = int(cap.get(cv2.CAP_PROP_FPS))  # 获取视频帧率
    frame_count = 0
    vehicle_count_per_25_frames = []  # 每25帧的车辆总数
    speed_per_25_frames = []  # 每25帧通过蓝线的车辆平均速度
    density_per_25_frames = []  # 每25帧的车辆密度(蓝线以下车辆数)
    total_vehicle_count = 0

    # 获取视频帧的宽度和高度,用于绘制蓝线
    frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    blue_line_y = int(frame_height * 0.25)  # 在视频四分之一处画一根水平蓝线

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

        # 每25帧重新检测一次车辆,并更新跟踪器
        if frame_count % 25 == 0:
            # 使用YOLOv5进行车辆检测
            results = model(frame)
            detections = results.xyxy[0].cpu().numpy()  # [x1, y1, x2, y2, conf, cls]

            # 清空旧的跟踪器并添加新检测到的车辆
            vehicles.clear()
            for *box, conf, cls in detections:
                if int(cls) in [2, 3, 5, 7]:  # 汽车, 卡车等车辆类
                    x1, y1, x2, y2 = map(int, box)
                    bbox = (x1, y1, x2 - x1, y2 - y1)  # 计算检测框
                    tracker = cv2.TrackerCSRT_create()  # 使用CSRT追踪器
                    tracker.init(frame, bbox)
                    vehicle = Vehicle(bbox, tracker)
                    vehicles.append(vehicle)
                    total_vehicle_count += 1

        else:
            # 更新车辆的追踪位置
            for vehicle in vehicles:
                success, bbox = vehicle.tracker.update(frame)
                if success:
                    # 计算中心点并保存
                    x, y, w, h = map(int, bbox)
                    center_x, center_y = (x + x + w) // 2, (y + y + h) // 2
                    vehicle.add_position((center_x, center_y))

        # 绘制蓝线
        cv2.line(frame, (0, blue_line_y), (frame_width, blue_line_y), (255, 0, 0), 2)

        frame_count += 1

        # 每25帧,计算一次车辆数量、通过蓝线的车辆平均速度和车辆密度
        if frame_count % 25 == 0:
            # 统计当前帧的车辆数
            current_vehicle_count = len(vehicles)
            vehicle_count_per_25_frames.append(current_vehicle_count)

            # 计算每辆车的平均速度
            speeds = [vehicle.calculate_speed(fps) for vehicle in vehicles]
            avg_speed = np.mean(speeds) if speeds else 0
            speed_per_25_frames.append(avg_speed)

            # 计算蓝线以下的车辆密度
            vehicles_below_line = sum(1 for vehicle in vehicles if vehicle.bbox[1] > blue_line_y)
            density_per_25_frames.append(vehicles_below_line)

            print(f"每25帧车辆总数: {current_vehicle_count}, 平均速度: {avg_speed} km/h, 蓝线以下车辆数: {vehicles_below_line}")

        # 显示结果
        cv2.imshow('Vehicle Detection with YOLOv5', frame)

        # 按 'q' 键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()

    print(f"视频 {video_path} 处理完成,车辆总数: {total_vehicle_count}")
    return vehicle_count_per_25_frames, speed_per_25_frames, density_per_25_frames


# 绘制并保存车流密度、流量、速度的折线图到桌面,并生成Excel文件
def save_to_excel_and_plot(vehicle_counts, speed_counts, density_counts):
    time_points = list(range(1, len(vehicle_counts) + 1))  # X轴为每25帧的时间点

    # 创建DataFrame
    df = pd.DataFrame({
        'Time (every 25 frames)': time_points,
        'Vehicle Count (Flow)': vehicle_counts,
        'Average Speed (km/h)': speed_counts,
        'Vehicle Density (below blue line)': density_counts  # 添加蓝线以下车辆密度列
    })

    # 获取桌面路径
    desktop_path = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Desktop')  # Windows
    save_dir = desktop_path

    if not os.path.exists(save_dir):
        os.makedirs(save_dir)

    # 保存Excel文件
    excel_path = os.path.join(save_dir, 'vehicle_data_with_density.xlsx')
    df.to_excel(excel_path, index=False)
    print(f"数据已保存到 {excel_path}")

    # 绘制折线图
    plt.figure(figsize=(10, 6))

    # 绘制车辆流量
    plt.plot(time_points, vehicle_counts, marker='o', linestyle='-', color='b', label='Vehicle Count')

    # 绘制平均速度
    plt.plot(time_points, speed_counts, marker='s', linestyle='-', color='g', label='Average Speed')

    # 绘制蓝线以下车辆密度
    plt.plot(time_points, density_counts, marker='^', linestyle='-', color='r', label='Vehicle Density (below blue line)')

    plt.title('Vehicle Data over Time (every 25 frames)')
    plt.xlabel('Time (every 25 frames)')
    plt.ylabel('Value')
    plt.grid(True)
    plt.legend()

    # 保存图表到桌面
    save_path = os.path.join(save_dir, 'vehicle_data_with_density_plot.png')
    plt.savefig(save_path)
    print(f"图表已保存到 {save_path}")

    plt.show()


# 处理视频
video_paths = ['20240501_20240501135236_20240501160912_135235.mp4']
for video_path in video_paths:
    vehicle_counts, speed_counts, density_counts = process_video_yolov5(video_path)
    save_to_excel_and_plot(vehicle_counts, speed_counts, density_counts)

在这里插入图片描述

下面这个代码是对于之前的物体识别进行的初稿,出的效果很好看

import torch
import cv2
import numpy as np

# 加载YOLOv5模型
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)

def process_video_yolov5(video_path):
    cap = cv2.VideoCapture(video_path)
    if not cap.isOpened():
        print(f"无法打开视频文件 {video_path}")
        return

    vehicle_count = 0

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

        # 使用YOLOv5进行检测
        results = model(frame)

        # 解析检测结果,results.pandas().xyxy 返回检测结果的 DataFrame
        detections = results.xyxy[0].cpu().numpy()  # [x1, y1, x2, y2, conf, cls]

        for *box, conf, cls in detections:
            # 检测类别ID,2: 汽车, 3: 摩托车, 5: 公共汽车, 7: 卡车
            if int(cls) in [2, 3, 5, 7]:
                x1, y1, x2, y2 = map(int, box)
                vehicle_count += 1
                # 在图像上绘制检测框
                cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)

        # 显示结果
        cv2.imshow('Vehicle Detection with YOLOv5', frame)

        # 按 'q' 键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()
    print(f"视频 {video_path} 处理完成,车辆总数: {vehicle_count}")

# 处理视频
video_paths = ['20240501_20240501135236_20240501160912_135235.mp4']
for video_path in video_paths:
    process_video_yolov5(video_path)

在这里插入图片描述
两者结合就是下面这个
在这里插入图片描述

三、感受

比赛真的是很锻炼人的能力,但是也是收获颇丰。
首先就是遇到两个很好很好的朋友,zxz,lsy,两个队友,哈哈哈哈哈感觉,比完赛感觉我们都认识三年了一样,很熟了。
其次就是我安装完成了torch、pycharm、以及虚拟环境的概念的、库的安装(这一点真的很关键,因为我也在想我发论文准备看着机器视觉的方向发展,而且我之前的深度之眼的专栏,也是到了安装anacoda、pycharm、cuda(原来我的电脑nvidia本来就有)、ptorch,之后就卡住了,因为感觉分不清他们,几个怕安装错了
然后,我队友也是帮我安装好类似公式编辑器的东西,还有一个公式识别的网站,两个搭配起来真的超级好用。
还有就是论文写作,也是相应的锻炼了自己论文写作能力把,也是完成了本科想当模型的梦想。哈哈哈哈哈,不想当模型的软件,不是好软件。也是写了数学建模方向的第一次的摘要,写的也是十分的充实,很开心的被认可了。(唯一的遗憾就是流程图、图啥的几乎是没有的,时间太少了)
最后,chatgpt真是神器,需要什么样的代码跟他说就行,报了什么错问他就行,提出问题,让他给出模型,,给他数据也能按照你的要求进行相应的处理,出图、分析,很牛逼。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/886569.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机毕业设计 基于Python的热门微博数据可视化分析系统的设计与实现 Python+Django+Vue 可视化大屏 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

计算机毕业设计Hadoop+Spark知识图谱体育赛事推荐系统 体育赛事热度预测系统 体育赛事数据分析 体育赛事可视化 体育赛事大数据 大数据毕业设计

《HadoopSpark知识图谱体育赛事推荐系统》开题报告 一、研究背景与意义 随着互联网技术的迅猛发展和大数据时代的到来&#xff0c;体育赛事数据的数量呈爆炸式增长。用户面对海量的体育赛事信息&#xff0c;常常感到信息过载&#xff0c;难以快速找到感兴趣的赛事内容。传统的…

软件管理【1.10】

软件管理【1.10】 13、软件管理13.1.包管理工具rpm13.2.yum和dnf13.2.1.配置yum源13.2.2.只下载安装包,不安装13.2.3.配置本地光盘ISO文件安装13.2.4.配置阿里云epel源13.2.5.base-for-centos7.repo13.2.6.base-for-rocky8.repo13.3.搭建私有yum仓库13.3.1.Apache实现网战功能…

Kafka和RabbitMQ区别

RabbitMQ的消息延迟是微秒级&#xff0c;Kafka是毫秒级&#xff08;1毫秒1000微秒&#xff09; 延迟消息是指生产者发送消息发送消息后&#xff0c;不能立刻被消费者消费&#xff0c;需要等待指定的时间后才可以被消费。 Kafka的单机呑吐量是十万级&#xff0c;RabbitMQ是万级…

sql-labs靶场第二关测试报告

目录 一、测试环境 1、系统环境 2、使用工具/软件 二、测试目的 三、操作过程 1、寻找注入点 2、注入数据库 ①Order by判断列数 ②判断回显地方 ③爆库&#xff0c;查看数据库名称 ④爆表&#xff0c;查看security库的所有表 ⑤爆列&#xff0c;查看users表的所有…

给出向量求叉乘(在垂直的时候可以简化)

1、可以用那个求行列式的方法求叉乘。 2、在两个向量垂直的时候&#xff0c;可以用简化方法&#xff0c;前面幅度相乘&#xff0c;然后ex叉乘ey是ez 注意叉乘结果无论原向量是不是垂直&#xff0c;叉乘结果都与两个向量垂直

HUAWEI New4.9G 与 2.6G 无法正常切换问题处理案例

HUAWEI New4.9G 与 2.6G 无法正常切换问题处理案例 在某地市的 XX 音乐节保障准备期间&#xff0c;为确保活动期间的网络质量&#xff0c;现场新开了 4.9G HUAWEI 室外基站。在网络优化和测试中&#xff0c;发现UE无法实现从 2.6G 到 4.9G 的正常切换。虽然现场具备 4.9G信号覆…

【STM32单片机_(HAL库)】4-5-1【定时器TIM】【感应开关盖垃圾桶】SG90舵机模块实验

1.硬件 STM32单片机最小系统SG90舵机模块 2.软件 sg90驱动文件添加main.c程序 #include "sys.h" #include "delay.h" #include "led.h" #include "sg90.h"int main(void) {HAL_Init(); /* 初始化HAL库 */…

【算法】链表:160.相交链表(easy)+双指针

系列专栏 《分治》 《模拟》 《Linux》 目录 1、题目链接 2、题目介绍 3、解法&#xff08;双指针&#xff09; 返回结果 算法正确性 时间复杂度 4、代码 1、题目链接 160. 相交链表 - 力扣&#xff08;LeetCode&#xff09; 2、题目介绍 ​ 3、解法&#xff08;…

Pikachu-xss防范措施 - href输出 js输出

总体原则&#xff1a; 输入做过滤&#xff0c;输出做转义 过滤&#xff1a;根据业务需要进行过滤&#xff0c;如&#xff1a;输入点要求输入手机号&#xff0c;则只允许输入手机号格式的数字&#xff1b; 转义&#xff1a;所有输出到前端的数据&#xff0c;都根据输出点进行转…

OpenCV计算机视觉库

计算机视觉和图像处理 Tensorflow入门深度神经网络图像分类目标检测图像分割OpenCVPytorchNLP自然语言处理 OpenCV 一、OpenCV简介1.1 简介1.2 OpenCV部署1.3 OpenCV模块 二、OpenCV基本操作2.1 图像的基本操作2.1.1 图像的IO操作2.1.2 绘制几何图像2.1.3 获取并修改图像的像素…

【算法篇】回溯算法类(2)(笔记)

目录 一、LeetCode 题目 1. 子集II 2. 递增子序列 3. 全排列 4. 全排列 II 5. 重新安排行程 6. N皇后 7. 解数独 二、题目思路整理 一、LeetCode 题目 1. 子集II https://leetcode.cn/problems/subsets-ii/description/https://leetcode.cn/problems/subsets-ii/des…

【C++】类与对象基础概念解析

恭喜你学习完C语言与数据结构的有关内容&#xff0c;现在让我们开始进行对C的学习吧~ &#x1f49d;&#x1f49d;&#x1f49d;如果你对C语言或数据结构还存在疑惑&#xff0c;欢迎观看我之前的作品 &#x1f449;【数据结构】 &#x1f449;【C语言】 目录 一、引言 二、类…

MapBox Android版开发 6 关于Logo

MapBox Android版开发 6 关于Logo Logo的显示查看源码及思路&#xff08;Logo&#xff09;第一步第二步 隐藏Logo示例查看源码及思路&#xff08;Info&#xff09;第一步第二步 隐藏Logo和Info示例 看到有网友留言问如何移除Logo&#xff0c;今天看了下V9源码&#xff0c;发现M…

CORE MVC 过滤器 (筛选器)《2》 TypeFilter、ServiceFilter

TypeFilter、ServiceFilter ServiceFilter vs TypeFilter ServiceFilter和TypeFilter都实现了IFilterFactory ServiceFilter需要对自定义的Filter进行注册&#xff0c;TypeFilter不需要 ServiceFilter的Filter生命周期源自于您如何注册&#xff08;全局、区域&#xff09;&…

Ps:打开与置入

在 Adobe Photoshop 中&#xff0c;理解不同的“打开”和“置入”命令及其用途&#xff0c;可以根据不同的需求选择最佳方式来管理和编辑图像文件。 ◆ ◆ ◆ 打开 1、Ps菜单&#xff1a;文件/打开 File/Open 快捷键&#xff1a;Ctrl O 用于直接打开现有的图像文件。 打开的…

【HDP】zookeeper未授权漏洞修复

目录 一、禁用四字命令 二、ZK-Client增加kerberos 一、禁用四字命令 Zookeeper四字命令的使用方式非常简单&#xff0c;通常有两种方式。第一种是通过Telnet方式&#xff0c;使用Telnet客户端登录ZooKeeper的对外服务端口&#xff0c;然后直接使用四字命令即可&#xff1b;第…

计算机网络-系分(5)

目录 计算机网络 DNS解析 DHCP动态主机配置协议 网络规划与设计 层次化网络设计 网络冗余设计 综合布线系统 1. 双栈技术 2. 隧道技术 3. 协议转换技术 其他网络技术 DAS&#xff08;Direct Attached Storage&#xff0c;直连存储&#xff09; NAS&#xff08;Net…

centos环境安装JDK详细教程

centos环境安装JDK详细教程 一、前期准备二、JDK安装2.1 rpm方式安装JDK2.2 zip方式安装JDK2.3 yum方式安装JDK 本文主要说明CentOS下JDK的安装过程。JDK的安装有三种方式&#xff0c;用户可根据实际情况选择&#xff1a; 一、前期准备 查看服务器操作系统型号&#xff0c;执…

【Android 14源码分析】Activity启动流程-3

忽然有一天&#xff0c;我想要做一件事&#xff1a;去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…