news 2026/9/4 21:45:06

基于YOLO与ByteTrack的智能交通监控系统:从目标检测到行为分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于YOLO与ByteTrack的智能交通监控系统:从目标检测到行为分析

简介:本资源是一套面向本科毕业设计与人工智能课程实践的YOLO交通智能分析系统实现方案,聚焦交通流量实时统计与压线、逆行、违停等典型违章行为检测两大核心任务。资源包共119个文件,含46个Python主程序与工具脚本(如run_app.bat等启动入口)、53个编译后pyc模块、3个PyQt界面文件(.ui)及yolov4-tiny.pt模型权重、cfg配置与names类别定义等关键深度学习组件,整体64.38MB,结构完整覆盖数据预处理、模型推理、GUI交互与结果可视化全流程。已有111人学习下载,适合具备Python基础与PyTorch入门经验的学习者开展端到端项目复现。读者可直接运行获得带GUI的交通监控演示系统,获取含视频流接入、目标轨迹追踪、流量热力图生成及违章截图存证的完整功能链,并参考README.md与SQL数据库设计理解工程落地逻辑。

1. 项目缘起:从“看见”到“理解”的交通监控升级

最近在整理硬盘,翻到了一个几年前做的老项目压缩包,名字就叫“基于YOLO的交通流量统计、违章行为检测.zip”。点开一看,里面代码、模型、数据集混杂在一起,文档也几乎没有,典型的“一次性项目”遗迹。但仔细想想,这个项目背后涉及的技术栈和思路,恰恰是当前很多智能交通、安防监控甚至工业质检项目的核心骨架。与其让它继续吃灰,不如借着这个机会,把它彻底拆解、重构一遍,把当时踩过的坑、摸索出来的门道,以及这几年技术演进带来的新思路,系统地梳理出来。

这个项目的核心目标很明确:利用计算机视觉技术,让监控摄像头不仅能“看见”车流,更能“理解”交通行为。具体来说,就是实现两个核心功能:一是实时统计通过某个路口的车辆数量(流量统计),二是自动识别诸如闯红灯、压线、逆行、违停等违章行为。听起来像是智慧城市大屏上那些酷炫系统的简化版,但麻雀虽小,五脏俱全。从视频流接入、目标检测、目标跟踪、轨迹分析,到行为规则判断和结果可视化,整个链路一个不少。

YOLO(You Only Look Once)作为这个项目的基石,其选择在当时和现在都极具代表性。它平衡了速度和精度,非常适合对实时性要求高的视频分析场景。但仅仅把YOLO模型跑起来,框出车辆和行人,距离真正的“流量统计”和“违章检测”还差得远。这里面涉及到跟踪算法(如DeepSORT、ByteTrack)的选型与集成、虚拟检测线或区域的设置、轨迹点的时间序列分析、以及针对不同违章行为的规则引擎设计。每一个环节都有其技术细节和调优空间。

所以,这篇文章不是简单地复现那个老项目,而是以它为蓝本,结合最新的实践认知(比如YOLOv8/v11的便捷性、更高效的跟踪算法、以及一些工程化部署的考量),手把手带你搭建一个可运行、可调试、可扩展的交通分析系统原型。无论你是想学习视频分析的全流程,还是需要为一个具体的场景(比如小区出入口管理、工地安全监控)快速搭建原型,相信这些内容都能给你提供直接的参考。

2. 核心组件选型与技术栈搭建:为什么是它们?

在动手写代码之前,技术选型决定了项目的天花板和地板。一个合理的选型能让后续开发事半功倍,反之则可能步步维艰。回顾我那个老项目和一些新的实践,以下这套技术栈是经过验证的、比较稳妥的组合。

2.1 目标检测器:YOLO系列的演进与v8的“甜点”选择

目标检测是整个流程的第一步,也是精度和速度的基石。YOLO系列发展迅速,从v5到v11,各有侧重。

  • YOLOv5:生态极其丰富,资料和社区解决方案最多,是很多项目的起点。它的PyTorch实现非常友好,训练和部署的教程铺天盖地。
  • YOLOv8:Ultralytics公司出品,可以看作是v5的“官方升级版”。它最大的优势是统一且优雅的API,分类、检测、分割、姿态估计任务都用同一套接口,大大降低了学习成本。其预训练模型性能优秀,并且自带完善的训练、验证、预测和导出(到ONNX、TensorRT等)流程。对于快速原型开发和新手来说,v8是目前综合体验最好的“甜点”。
  • YOLOv9/v10/v11:学术界的前沿,在结构上持续创新(如v9的可编程梯度信息PGI,v11的新主干网)。但对于工程落地,尤其是我们这种集成项目,它们的稳定性和周边工具链(如跟踪算法适配、部署优化)可能还不如v8成熟。除非有极致的精度追求,否则v8或v5是更务实的选择。

我的选择与理由:本次重构我将基于YOLOv8。原因很简单:它降低了从训练到部署的全流程门槛,让我们能把更多精力放在跟踪和行为分析逻辑上。使用它的Python SDK,几行代码就能完成模型加载和推理,并且其输出格式(边框、置信度、类别ID)非常规范,便于后续处理。

# 示例:使用YOLOv8进行预测的基础代码 from ultralytics import YOLO import cv2 # 加载预训练模型(例如官方的yolov8n.pt,或你自己训练的模型) model = YOLO('yolov8n.pt') # 读取视频帧 frame = cv2.imread('test_image.jpg') # 进行预测 results = model(frame)[0] # results是一个Results对象 # 解析结果 boxes = results.boxes.xyxy.cpu().numpy() # 边框坐标 [x1, y1, x2, y2] confidences = results.boxes.conf.cpu().numpy() # 置信度 class_ids = results.boxes.cls.cpu().numpy().astype(int) # 类别ID # 可以根据类别ID过滤出车辆(COCO数据集中,car=2, truck=7, bus=5等) vehicle_indices = [i for i, cls_id in enumerate(class_ids) if cls_id in [2, 5, 7]] vehicle_boxes = boxes[vehicle_indices]

注意:YOLOv8默认使用COCO数据集预训练,其中包含了‘car’, ‘truck’, ‘bus’等类别。如果你的场景有特殊车辆(如工程车、三轮车),可能需要在自己的数据集上微调模型。

2.2 多目标跟踪器:连接帧与帧的“记忆”

检测只能告诉我们每一帧里有什么,而跟踪负责将不同帧中的同一个目标关联起来,形成随时间变化的轨迹。这是流量统计(同一个车不能重复计数)和行为分析(需要连续轨迹判断行为)的关键。

  • SORT/DeepSORT:经典组合。SORT基于卡尔曼滤波预测和匈牙利算法匹配,速度极快但ID切换频繁。DeepSORT在SORT基础上加入了外观特征(Re-ID)模型,大大减少了ID切换,是过去几年的主流。
  • ByteTrack:2022年提出的新方法,核心思想是充分利用低分检测框。传统的跟踪会用一个高阈值(如0.5)过滤检测框,只跟踪高分框。ByteTrack认为,那些低分框(如0.1-0.5)也可能是真实目标,只是可能被遮挡或模糊。它先匹配高分框,再用低分框进行二次匹配和恢复,在保持高速度的同时,取得了比DeepSORT更好的性能,特别是在拥挤场景下。它几乎成为了新的默认选择
  • OC-SORT:针对遮挡场景做了特别优化,在目标频繁相互遮挡的场景下表现更鲁棒。

我的选择与理由:对于交通场景,车辆运动相对规律,遮挡情况中等。ByteTrack在精度和速度上取得了很好的平衡,且实现相对简单,不需要单独训练外观模型(DeepSORT需要)。我们将采用一个开源的ByteTrack Python实现,并将其与YOLOv8的输出进行对接。

跟踪器的输入是每一帧的检测结果[x1, y1, x2, y2, score, class_id],输出是带有唯一ID的跟踪框[x1, y1, x2, y2, track_id, class_id]。后续的所有分析都基于track_id

2.3 其他工具与框架

  • OpenCV:计算机视觉的“瑞士军刀”,用于视频流的读取、解码、显示、绘制(画框、画线、写字)以及一些简单的图像处理。必不可少。
  • NumPy/Pandas:进行高效的数值计算和轨迹数据(时间戳、位置、ID)的临时存储与分析。
  • 可视化与交互:可以使用OpenCV的imshow进行实时显示,或者用Matplotlib进行事后分析绘图。对于需要调整虚拟检测线位置的应用,可以写一个简单的鼠标回调函数来实现交互式绘制。

技术栈总结:我们将以YOLOv8 (检测) + ByteTrack (跟踪) + OpenCV (视频处理)为核心,用Python脚本将它们串联起来,构建整个系统。这个组合兼顾了性能、易用性和现代性。

3. 从检测到跟踪:构建稳定的目标轨迹

有了选型,接下来就是实现。第一步是把检测和跟踪模块无缝衔接,输出稳定的、带ID的目标轨迹。

3.1 视频流处理与检测循环

无论是处理离线视频文件还是实时RTSP流,核心都是一个循环:读取帧 -> 检测 -> 跟踪 -> 分析/显示 -> 写入结果。

import cv2 from ultralytics import YOLO # 假设我们已经有一个ByteTrack的跟踪器类 `ByteTracker` from bytetracker import ByteTracker # 初始化 model = YOLO('yolov8n.pt') tracker = ByteTracker() # 需要传入一些参数,如track_thresh, match_thresh等 cap = cv2.VideoCapture('your_traffic_video.mp4') while cap.isOpened(): ret, frame = cap.read() if not ret: break # YOLOv8 检测 results = model(frame, verbose=False)[0] # verbose=False关闭控制台日志 detections = [] if results.boxes is not None: boxes = results.boxes.xyxy.cpu().numpy() scores = results.boxes.conf.cpu().numpy() class_ids = results.boxes.cls.cpu().numpy().astype(int) # 只保留车辆类别的检测结果(根据COCO ID) for box, score, cls_id in zip(boxes, scores, class_ids): if cls_id in [2, 5, 7]: # car, bus, truck # 格式化为 [x1, y1, x2, y2, score, class] detections.append([*box, score, cls_id]) if len(detections) > 0: detections = np.array(detections) else: detections = np.empty((0, 6)) # ByteTrack 更新 # 注意:ByteTrack的update方法通常接受 [x1, y1, x2, y2, score] 格式,类别信息可能需要额外处理 online_targets = tracker.update(detections[:, :5], detections[:, 5], frame.shape[:2]) # online_targets 应包含 [x1, y1, x2, y2, track_id, class_id, ...] 等信息 # 此时,online_targets 就是当前帧的跟踪结果 # 接下来可以基于这些结果进行流量统计和违章分析(见下一节) # 可视化:在帧上绘制跟踪框和ID for t in online_targets: x1, y1, x2, y2, track_id = int(t[0]), int(t[1]), int(t[2]), int(t[3]), int(t[4]) cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(frame, f'ID:{track_id}', (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) cv2.imshow('Traffic Analysis', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()

3.2 跟踪器的调参与“幽灵”轨迹处理

跟踪器不是开箱即用就完美的,有几个关键参数直接影响效果:

  • track_thresh:检测框得分阈值,高于此值才被认为是有效检测并初始化为跟踪轨迹。通常设得比纯检测的置信度阈值低一点(如0.4),以捕捉更多可能目标。
  • match_thresh:轨迹和检测框的匹配阈值(对于ByteTrack,可能涉及IoU和外观特征等)。值太高匹配不上,ID切换多;值太低容易错误关联。
  • frame_rate:告诉跟踪器视频的帧率,用于调整卡尔曼滤波的运动模型参数。如果与实际帧率不符,预测会不准。

一个常见的坑是“幽灵轨迹”:当一个目标(比如一辆车)离开画面后,跟踪器可能因为惯性预测,还会在画面外维持几帧这个轨迹。如果此时你的流量统计检测线设在画面边缘,就可能错误地再计数一次。解决办法是设置一个轨迹生命计数器。当跟踪器连续多帧(比如30帧,约1秒)没有为某个track_id匹配到任何检测框时,就认为该目标已消失,将其从活跃跟踪列表和后续分析中移除。好的跟踪器实现(如ByteTrack)内部通常有这个机制,但你需要了解并可能调整这个“最大丢失帧数”参数。

4. 交通流量统计:如何让计数准确可靠?

流量统计听起来简单——目标穿过一条线就加一。但实现起来,要避免重复计数、漏计数,就需要一些技巧。

4.1 虚拟检测线与方向判断

我们通常在感兴趣的区域画一条“虚拟线”或一个“虚拟区域”。最常见的是在车道中央画一条垂直于车流的计数线

  1. 定义线:用两个点(line_start, line_end)定义这条线。
  2. 计算轨迹中心点:对于每个跟踪目标,我们取其边界框的底部中心点(cx, cy) = ((x1+x2)/2, y2)作为代表点。用底部中心是因为它更贴近地面,受车辆姿态(如刹车抬头)影响小。
  3. 判断穿越:核心是判断代表点从线的一侧运动到了另一侧。不能只判断当前帧的点是否在线“上”,因为一帧可能直接跨过去。我们需要结合历史轨迹。
    • 方法:记录每个track_id上一帧的代表点位置prev_point
    • 计算当前点curr_pointprev_point与检测线的关系。可以用计算点到直线的有向距离,或者更简单地,对于水平线,比较prev_ycurr_yline_y的大小。
    • 如果prev_point在线上方且curr_point在线下方(或反之),并且运动是垂直向下的(符合车流方向),则认为发生了一次穿越。
# 假设有一条水平计数线 y = line_y line_y = 300 # 用一个字典存储每个track_id的上一帧中心点 track_history = {} for t in online_targets: track_id = int(t[4]) cx = int((t[0] + t[2]) / 2) cy = int(t[3]) # 底部y坐标 if track_id in track_history: prev_cy = track_history[track_id] # 判断穿越:上一帧在线以上,当前帧在线以下,且是向下运动(防止计数回退) if prev_cy < line_y and cy >= line_y and cy > prev_cy: vehicle_count += 1 print(f"Vehicle ID:{track_id} crossed the line. Total: {vehicle_count}") # 更新历史位置 track_history[track_id] = cy # 清理很久未出现的轨迹历史(避免内存泄漏) # ...

4.2 多车道与方向过滤

实际路口可能有多个车道,双向车流。我们需要更精细的管理:

  • 多车道:可以为每个车道定义一条计数线。在判断穿越时,还需要判断车辆的中心点cx是否落在车道的水平范围内[lane_left, lane_right]
  • 方向过滤:对于双向车道,我们只统计某个方向的车流。可以通过判断穿越时curr_pointprev_point的位移向量方向来实现。例如,只统计从北向南(y坐标增加)的车流。

提高计数准确性的经验

  • 设置“计数缓冲区”:不要用一条绝对细的线。可以设置一个“缓冲区带”(如line_y -5line_y +5)。当目标进入这个带,标记为“待计数状态”,离开时再根据方向完成计数。这可以避免目标在线附近抖动导致的重复计数。
  • 延迟计数:不要目标一触线就立刻计数。可以等目标完全穿过线(比如中心点从线前10像素移动到线后10像素)再计数,更稳定。
  • 处理停滞车辆:如果车辆在计数线附近长时间停留(比如等红灯),我们的逻辑可能会重复计数。解决方法是在计数后,给该track_id打上一个“已计数”标签,在它离开视野或离开缓冲区之前,不再对其进行计数判断。

5. 违章行为检测:定义规则与实现逻辑

违章检测是更高阶的分析,需要基于目标的连续轨迹和时空关系。这里我们以“闯红灯”和“违停”为例,拆解实现逻辑。

5.1 闯红灯检测:状态机与区域判断

闯红灯检测不能只看车辆是否在红灯时越过了停止线,因为可能存在“黄灯抢行”“刚变红灯时车身已过线”等复杂情况。一个相对鲁棒的简化方案是使用区域判断+状态机

  1. 定义关键区域

    • 停车线区域:一个矩形区域,覆盖停止线及前方一小段距离。
    • 路口冲突区域:停车线后的路口中央区域。
    • 信号灯状态:这是一个外部输入。对于demo,我们可以模拟或手动标注视频中红灯的时间段。实际系统需要接入信号机数据或通过视觉识别信号灯。
  2. 设计车辆状态机

    • 状态1:接近:车辆进入停车线区域前方一定范围。
    • 状态2:在停车线内:车辆的中心点或边界框与停车线区域有重叠。
    • 状态3:进入路口:车辆完全越过停车线,进入路口冲突区域。
  3. 违章判断逻辑

    • 当信号灯为红灯时:
      • 如果车辆从“状态1”进入“状态2”,记录为“在红灯时抵达停止线”。
      • 如果车辆在“状态2”停留极短时间(如小于0.5秒,可能是误判或车身摆动),忽略。
      • 如果车辆从“状态2”进入“状态3”,则判定为“闯红灯”。因为这意味着它在红灯期间越过了停止线并进入了路口。
    • 当信号灯为绿灯黄灯时,重置相关车辆的状态。
# 伪代码逻辑 red_light = False # 实际中应从信号源获取 stop_line_zone = [(100, 300), (500, 320)] # 停车线矩形区域 intersection_zone = [(80, 320), (520, 500)] # 路口区域 vehicle_states = {} # track_id -> {'state': 'approaching/at_line/in_intersection', 'last_state_time': timestamp} for t in online_targets: track_id, cx, cy = ... box = [t[0], t[1], t[2], t[3]] # 判断车辆在哪个区域 in_stop_line = is_point_in_rect((cx, cy), stop_line_zone) in_intersection = is_point_in_rect((cx, cy), intersection_zone) if track_id not in vehicle_states: vehicle_states[track_id] = {'state': 'outside', 'last_state_time': current_time} prev_state = vehicle_states[track_id]['state'] # 状态转移判断 if red_light: if not in_stop_line and not in_intersection: new_state = 'approaching' elif in_stop_line and not in_intersection: new_state = 'at_line' elif in_intersection: new_state = 'in_intersection' # 关键判断:如果上一个状态是‘at_line’,且在当前状态下,则闯红灯 if prev_state == 'at_line': time_at_line = current_time - vehicle_states[track_id]['last_state_time'] if time_at_line > 0.5: # 排除短暂停留的误判 print(f"ALERT: Vehicle ID:{track_id} ran a red light!") # 触发报警、截图、记录轨迹等操作 # 更新状态和时间 if new_state != prev_state: vehicle_states[track_id]['state'] = new_state vehicle_states[track_id]['last_state_time'] = current_time else: # 绿灯或黄灯,重置该车辆的状态(或直接删除记录) if track_id in vehicle_states: del vehicle_states[track_id]

5.2 违停检测:时间阈值与动态ROI

违停检测相对直接:在禁止停车的区域(ROI, Region of Interest),检测是否有车辆静止超过规定时间(如60秒)。

  1. 定义违停区域:用多边形或矩形标出禁止停车的区域,如公交站台、路口黄网格线、消防通道等。
  2. 计算车辆运动速度:对于每个track_id,记录其连续多帧的中心点位置。计算其平均位移速度(像素/秒)。由于摄像头可能不是正射,像素速度与实际速度不成比例,但对于判断“是否静止”足够了。
  3. 判断逻辑
    • 如果车辆的中心点在违停区域内,并且其连续N帧(对应时间T)的平均速度低于一个极小阈值(如每秒5个像素),则触发“疑似违停”警报。
    • 为了避免短暂停车(如上下客)误报,需要持续监测。只有“疑似违停”状态持续超过法规规定的时间(如60秒),才最终判定为“违停”,并记录开始时间、位置和车辆ID(如果车牌清晰,可结合车牌识别)。
  4. 动态ROI管理:违停区域可能随时间段变化(如夜间允许停车)。系统需要支持ROI和判定规则的动态加载。

实现细节

  • 速度计算可以使用简单的移动平均,比如存储最近10帧的位置,计算这10帧内的总位移除以总时间。
  • 对于静止判断,阈值要设得足够低,以过滤掉车辆缓慢蠕动(如堵车)的情况。
  • 需要维护一个violation_records字典,记录每个track_id进入疑似状态的时间点。

6. 工程化思考:从Demo到可用的系统

把上面的模块拼在一起,就能得到一个在视频文件上运行的演示程序。但要让其成为一个“系统”,还需要考虑很多工程问题。

6.1 性能优化:让它在实际场景中跑得快

Python + OpenCV + YOLO 在单路视频上实时(>25 FPS)运行是有挑战的,尤其是使用较大的YOLO模型时。

  • 模型选择与量化:在精度可接受的前提下,选择更小的模型(如YOLOv8n, YOLOv8s)。可以使用PyTorch的量化(Quantization)或导出为TensorRT/OpenVINO等推理引擎格式,能获得数倍的加速。
  • 推理批处理:如果处理多路视频,可以将多帧图片堆叠成一个批次(batch)送入模型推理,能更充分利用GPU计算资源。
  • 跳帧处理:对于非关键实时场景,可以每2帧或3帧做一次目标检测,中间帧只做跟踪。因为跟踪的计算量远小于检测。这是平衡精度和速度的常用技巧。
  • 视频解码:使用OpenCV的cv2.VideoCapture解码可能不是最快的。对于高性能需求,可以探索使用FFmpeg库(如PyAV)或硬件解码(如NVIDIA的Video Codec SDK)。

6.2 鲁棒性提升:应对复杂场景

  • 光照与天气:模型在训练数据未覆盖的夜间、雨雪、强光逆光下可能失效。解决方案包括:使用在多样天气数据上训练过的模型;在图像预处理阶段加入自动白平衡、对比度增强;或者部署红外摄像头应对夜间。
  • 遮挡与密集:严重遮挡下,检测和跟踪都会失效。ByteTrack一定程度上缓解了这个问题。更进一步的方案是使用更强大的检测器(如YOLOv9)或引入注意力机制。对于流量统计,在极度拥挤时,可以切换到基于光流或背景减除的宏观估计方法作为补充。
  • 相机抖动:手持或安装不牢的相机会导致画面抖动,使虚拟检测线“相对移动”,造成误判。需要加入视频稳像(Video Stabilization)模块,或者使用更稳定的轨迹滤波算法。

6.3 数据流与结果输出

一个完整的系统不能只显示在屏幕上。

  • 结构化输出:需要将统计结果(时间、车道、流量、速度)和违章事件(时间、地点、类型、车辆ID/车牌截图、证据视频片段)以结构化的格式(如JSON、CSV)写入数据库或消息队列(如Kafka、RabbitMQ)。
  • 可视化与告警:提供Web界面或大屏看板,实时显示流量热力图、违章事件列表。违章事件可触发声音告警、弹窗,并自动保存前后10秒的视频片段作为证据。
  • 系统集成:通过API与其他系统对接,比如将违章数据推送给交警业务平台,将流量数据推送给交通信号控制系统进行自适应配时。

7. 模型训练与数据:如果预训练模型不够用怎么办?

COCO预训练的YOLOv8模型能检测常见车辆,但如果你的场景有特殊车辆(电瓶车、三轮车、特定工程车)、或者需要更精细的类别(小轿车、SUV、卡车)、或者需要检测车牌(用于违章取证),你就需要定制训练。

  1. 数据收集与标注

    • 来源:从你的目标场景摄像头录制视频,并抽取关键帧。确保覆盖不同时段、天气、光照条件。
    • 标注工具:使用LabelImg、CVAT、Roboflow等工具进行边界框标注。标注的类别要与你关心的行为相关(例如,为了检测“行人闯红灯”,你需要标注‘person’;为了检测“货车禁行”,你需要区分‘car’和‘truck’)。
    • 数据格式:YOLO格式的标签是每个图像对应一个.txt文件,每行内容为class_id center_x center_y width height,坐标是归一化后的(0-1之间)。
  2. 模型训练

    • 环境:最好有GPU。可以使用Google Colab的免费GPU,或者租用云服务器。
    • 步骤
      # 安装Ultralytics pip install ultralytics # 准备数据集,按YOLO格式组织 # dataset/ # ├── images/ # │ ├── train/ # │ └── val/ # └── labels/ # ├── train/ # └── val/ # 创建一个 dataset.yaml 配置文件 # path: /path/to/dataset # train: images/train # val: images/val # nc: 5 # 你的类别数 # names: ['car', 'bus', 'truck', 'motorcycle', 'person'] # 开始训练(从预训练模型yolov8n.pt开始微调) yolo task=detect mode=train model=yolov8n.pt data=dataset.yaml epochs=50 imgsz=640
    • 关键参数epochs(迭代轮数)、imgsz(输入图像大小,越大精度可能越高但越慢)、batch(批大小,根据GPU内存调整)。训练过程会自动验证,并保存最佳模型best.pt
  3. 评估与部署:训练完成后,在独立的测试集上评估模型精度(mAP)。满意后,将模型导出为ONNX或TensorRT格式,以便在部署环境中获得更优性能。

避坑提示:训练数据中,目标大小、角度、遮挡情况的分布要尽量与真实场景一致。如果真实场景中电瓶车很多,但训练数据里很少,模型就很可能漏检。这就是所谓的“数据分布不一致”问题。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 21:44:13

单片机绿色智能风扇毕业设计:PWM调速与低功耗控制详解

做单片机毕业设计的人&#xff0c;很多都会被“绿色”这两个字误导。有人以为绿色风扇就是把扇叶做成绿色&#xff0c;有人以为是在风扇周边加几棵仿真植物&#xff0c;还有人直接把它做成了一个普通调速风扇的换皮版。等到答辩时才发现&#xff0c;评委问的不是“风扇能不能转…

作者头像 李华
网站建设 2026/9/4 21:36:06

道路倒树清障全流程:风险评估、切割顺序与应急系统设计

前几天看到一条让人心里一紧的消息&#xff1a;一棵大树倒在路中间&#xff0c;车辆通行受阻&#xff0c;一位64岁大爷拿着工具冒雨锯树&#xff0c;一点一点把道路清理出来。大爷的勇气和热心确实值得敬佩&#xff0c;但这类工作放到真实应急场景里看&#xff0c;却属于典型的…

作者头像 李华
网站建设 2026/9/4 21:35:04

企业内部 AI 应用怎么证明它有用?

导语&#xff1a;企业内部 AI 应用上线后&#xff0c;真正难的不是证明“模型能回答”&#xff0c;而是证明“业务因为 AI 变好了”。本文从数据分析和埋点设计角度&#xff0c;建立一套“业务目标→AI 行为→过程效率→结果质量→成本风险”的度量体系&#xff0c;并给出可落地…

作者头像 李华
网站建设 2026/9/4 21:31:15

【计算机毕业设计单片机案例】人体红外与光敏复合检测 STM32 智能台灯开发 多档位可调 STM32 双模式智能语音台灯设计(018306)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机&#xff0c;Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/9/4 21:27:32

Python+PL/SQL高光谱图像处理模块:遥感数据与数据库高效集成实践

简介&#xff1a;本资源是面向遥感、环境科学与医学成像等领域科研人员及Python高光谱处理初学者的实用工具包&#xff0c;聚焦解决高光谱数据读取、预处理、特征提取、分类识别与可视化等核心问题。压缩包共92个文件&#xff08;224KB&#xff09;&#xff0c;含58个Python源码…

作者头像 李华
网站建设 2026/9/4 21:27:03

MATLAB实现红外与可见光图像配准:SIFT+RANSAC算法详解与实战

简介&#xff1a;本资源是一套面向图像处理初学者与计算机视觉实践者的MATLAB红外与可见光图像配准实现方案&#xff0c;聚焦多模态图像空间对齐这一关键难题&#xff0c;适用于军事侦察、遥感监测及智能感知等实际场景。压缩包共29个文件&#xff0c;含20个核心MATLAB函数&…

作者头像 李华