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

news2024/11/22 22:24:42

文章目录

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

一、情况介绍

前几天也是参加了研究生数学建模竞赛(也就是华为杯),也是和本校的两个数学学院的朋友在网上组的队伍。昨天(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.coloradmin.cn/o/2168926.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows安装openssl开发库

1 下载openssl安装包并安装 下载网址&#xff1a; https://slproweb.com/products/Win32OpenSSL.html 下载对应的安装版本。 双击安装包&#xff0c;一路下一步完成安装。注意&#xff1a;1.安装路径不要有空格&#xff1b; 2. 建议不要把DLL拷贝到系统路径。 2 编辑代码 …

“类型名称”在Go语言规范中的演变

Go语言规范&#xff08;The Go Programming Language Specification&#xff09;[1]是Go语言的核心文档&#xff0c;定义了该语言的语法、类型系统和运行时行为。Go语言规范的存在使得开发者在实现Go编译器时可以依赖一致的标准&#xff0c;它确保了语言的稳定性和一致性&#…

制造企业为何需要PLM系统?PLM系统解决方案对制造业重要性分析

制造企业为何需要PLM系统&#xff1f;PLM系统解决方案对制造业重要性分析 新华社9月23日消息&#xff0c;据全国组织机构统一社会信用代码数据服务中心统计&#xff0c;我国制造业企业总量突破600万家。数据显示&#xff0c;2024年1至8月&#xff0c;我国制造业企业数量呈现稳…

数据结构之链表(1),单链表

目录 前言 一、什么是链表 二、链表的分类 三、单链表 四、单链表的实现 五、SList.c文件完整代码 六、使用演示 总结 前言 本文讲述了什么是链表&#xff0c;以及实现了完整的单链表。 ❤️感谢支持&#xff0c;点赞关注不迷路❤️ 一、什么是链表 1.概念 概念&#xff1a;链…

【学习笔记】手写 Tomcat 六

目录 一、线程池 1. 构建线程池的类 2. 创建任务 3. 执行任务 测试 二、URL编码 解决方案 测试 三、如何接收客户端发送的全部信息 解决方案 测试 四、作业 1. 了解工厂模式 2. 了解反射技术 一、线程池 昨天使用了数据库连接池&#xff0c;我们了解了连接池的优…

在 Docker 版 RStudio 中安装 Seurat V4 的完整教程 (同样适用于普通R环境安装)

在单细胞RNA测序&#xff08;scRNA-seq&#xff09;数据分析领域&#xff0c;Seurat 是一个广泛使用且功能强大的R包&#xff0c;提供了丰富的数据处理和可视化工具。为了简化环境配置和依赖管理&#xff0c;使用Docker来部署RStudio并安装Seurat V4是一种高效且可重复的方法。…

SpringCloud 2023各依赖版本选择、核心功能与组件、创建项目(注意事项、依赖)

目录 1. 各依赖版本选择2. 核心功能与组件3. 创建项目3.1 注意事项3.2 依赖 1. 各依赖版本选择 SpringCloud: 2023.0.1SpringBoot: 3.2.4。参考Spring Cloud Train Reference Documentation选择版本 SpringCloud Alibaba: 2023.0.1.0*: 参考Spring Cloud Alibaba选择版本。同时…

TMR技术的发展及其应用技术的介绍

目录 概述 1 TMR传感器介绍 1.1 原理介绍 1.2 技术演进历史 2 TMR技术的应用 2.1 电阻特性 2.2 技术比较 2.3 磁道特性 3 多维科技的芯片&#xff08;TMR1202&#xff09; 3.1 芯片介绍 3.2 特性 ​3.3 典型应用 参考文献 概述 本文主要介绍TMR技术的发展及其技术…

修改系统显示大小修改系统屏幕密度

文章目录 需求及场景一、界面位置及密度位置测试 一、修改density修改属性值属性位置修改默认值获取需要修改的值 二、部分资源参考总结 需求及场景 国内Android系统平台太多了&#xff0c;RK、全志、mtk、展讯&#xff0c;相同平台也会有不同的Android版本&#xff0c;不同版…

使用电子模拟器 Wokwi 运行 ESP32 示例(Arduino IDE、VSCode、ESP32C3)

文章目录 Wokwi 简介安装客户端&#xff08;Mac/Linux&#xff09;创建 Token Arduino IDEVSCode 配置安装 wokwi 插件打开编译后目录 ESP32C3 示例Arduino IDE创建模拟器运行模拟器 Wokwi 简介 Wokwi 是一款在线电子模拟器。您可以使用它来模拟 Arduino、ESP32、STM32 以及许…

【azure-openai】批量翻译demo【python】【gradio】

要求&#xff1a;拥有azure-openai-api&#xff0c;上传文件为csv格式&#xff0c;utf-8编码。 注意&#xff1a;如果出现乱码&#xff0c;重新运行&#xff0c;换种方式打开&#xff0c;有时候wps会自动改编码。 实现功能&#xff1a;选择语言&#xff0c;使用gpt4omini&…

IOS-IPA签名工具 request_post 任意文件读取复现

0x01 产品描述&#xff1a; 苹果手机中的IPA是指iOS应用程序&#xff08;iPhone应用程序&#xff09;的安装包文件&#xff0c;其文件扩展名为.ipa。IPA文件是经过编译的、已签名的应用程序文件&#xff0c;可以在iOS设备上安装和运行。通常&#xff0c;开发者通过Xcode等开发工…

OpenHarmony(鸿蒙南向)——平台驱动指南【I2C】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 概述 功能简介 I2C&#xff08;Inter Integrated Circuit&#x…

【HarmonyOS】分页滚动文本组件

【HarmonyOS】实现分页滚动文本组件&#xff1a;为何选择 Scroll Text 而非 textOverflow import { promptAction } from kit.ArkUIEntry Component struct Page37 {State lineHeight: number 0 // 单行文本的高度State pageHeight: number 0 // 每页的最大高度State totalC…

相机、镜头参数详解以及相关计算公式

一、工业相机参数 1、分辨率 相机每次采集图像的像素点数&#xff0c;也是指这个相机总共有多少个感光晶片。在采集图像时&#xff0c;相机的分辨率对检测精度有很大的影响&#xff0c;在对同样打的视场成像时&#xff0c;分辨率越高&#xff0c;对细节的展示越明显。 相机像素…

【高频SQL基础50题】1-5

目录 1.可回收且低脂的产品 2. 使用唯一标识码替换员工ID 3.有趣的电影 4.每位教师所教授的科目种类的数量 5.每位经理的下属员工数量 1.可回收且低脂的产品 查询题。 # Write your MySQL query statement below SELECT product_id FROM Products WHERE low_fats"…

基于微信的原创音乐小程序的设计与实现+ssm论文源码调试讲解

第二章 开发工具及关键技术介绍 2.1 JAVA技术 Java主要采用CORBA技术和安全模型&#xff0c;可以在互联网应用的数据保护。它还提供了对EJB&#xff08;Enterrise JavaBeans&#xff09;的全面支持&#xff0c;java servlet AI&#xff0c;JS&#xff08;java server ages&…

基于单片机的宠物喂食(ESP8266、红外、电机)

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于STC89C52单片机&#xff0c;采用L298N驱动连接P2.3和P2.4口进行电机驱动&#xff0c; 然后串口连接P3.0和P3.1模拟ESP8266&#xff0c; 红外传感器连接ADC0832数模转换器连接单片机的P1.0~P1.…

网络基础概念和 socket 编程

网络基础概念和 socket 编程 学习目标&#xff1a; 了解 OSI 七层模型、TCP/IP 四层模型结构了解常见的网络协议格式掌握网络字节序和主机字节序之间的转换理解 TCP 服务器端通信流程理解 TCP 客户端通信流程实现 TCP 服务器端和客户端的代码 推荐一个非常好的学习资料仓库 协…

RPA自动化流程机器人有哪些优势?

在数字化快速推进的大背景下&#xff0c;人工智能正在以前所未有的速度改变着生活和生产方式&#xff0c;而RPA自动化流程机器人作为其中一种最重要的革命性的技术&#xff0c;已经成为企业数字化中不可或缺的重要力量&#xff0c;让员工加速从“重复性工作”中摆脱出来。 金智…