基于YOLO与目标跟踪的交通视频分析系统:从模型训练到工程部署全解析

发布时间:2026/9/4 17:53:05
基于YOLO与目标跟踪的交通视频分析系统:从模型训练到工程部署全解析 简介本资源是一套面向本科毕业设计与人工智能课程实践的YOLO交通智能分析系统聚焦交通流量实时统计与压线、逆行、违停等典型违章行为检测任务适用于深度学习初学者及智慧交通方向项目开发者。压缩包共119个文件含46个Python主程序与工具脚本实现模型推理、视频流处理、GUI界面及结果可视化、53个pyc编译文件、3个PT模型权重文件含yolov4-tiny.pt、2个CFG配置与2个names类别定义文件辅以bat/sh启动脚本和UI界面资源整体64.38MB结构完整、开箱即用。目前已有111人学习下载。读者可直接运行run_app.bat启动图形化应用调用预训练模型完成端到端检测配套README.md说明部署流程coco.names与faces.names体现多类别适配能力1.jpg为示例输入SQL与MD文件隐含数据存储与文档支持逻辑具备工程落地参考价值。1. 项目概述从“压缩包”到“实战系统”的蜕变拿到一个名为“基于YOLO的交通流量统计、违章行为检测.zip”的文件对于很多刚入门的开发者来说可能意味着一个可以直接运行的“黑盒”代码。但作为一名在计算机视觉和智能交通领域摸爬滚打多年的从业者我更愿意把它看作一个“种子项目”或“概念验证”的起点。这个标题背后实际上指向的是一个非常经典且具有巨大商业和社会价值的应用场景利用YOLOYou Only Look Once这一主流的目标检测算法对道路监控视频进行自动化分析实现两大核心功能——交通流量统计与违章行为检测。简单来说这个项目要解决的是“让摄像头看懂交通”的问题。传统的交通管理依赖人工查看监控或简单的车辆计数线圈效率低、成本高、易出错。而基于深度学习的方案可以7x24小时不间断工作不仅能数清楚有多少辆车、多少人经过还能精准识别出闯红灯、违停、逆行、压线、不礼让行人等具体违章行为并自动生成结构化数据报告。这不仅仅是技术Demo更是智慧城市、安防监控、交通规划等领域落地的关键一环。这个项目适合谁呢首先当然是计算机视觉方向的学生和研究者这是一个绝佳的练手项目涵盖了数据准备、模型训练、部署优化、业务逻辑集成等全流程。其次是智慧交通、安防行业的工程师你们可以基于此框架进行二次开发适配具体的路口摄像头和业务规则。最后对于项目经理或产品经理理解这套技术栈的构成、能力边界和实现成本也有助于你们更好地规划产品和评估供应商方案。接下来我将彻底拆解这个“压缩包”背后应有的完整技术体系从设计思路到代码细节从模型选型到工程化部署分享我趟过的坑和积累的经验目标是让你不仅能跑通这个项目更能理解其内在逻辑具备独立开发和优化的能力。2. 核心架构与设计思路拆解一个完整的交通视频分析系统绝非一个YOLO模型就能包打天下。它需要一个清晰、可扩展的架构来支撑。基于我的经验一个稳健的系统通常遵循“视频流接入 - 目标检测 - 目标跟踪 - 业务逻辑判断 - 数据持久化与可视化”的流水线。2.1 为什么是“检测跟踪”的范式单纯使用YOLO进行逐帧检测对于流量统计和违章判断是远远不够的。原因有二一是同一车辆在连续帧中会被重复检测导致计数严重偏大二是违章行为如闯红灯是一个跨越时间序列的动作需要关联同一目标在不同时刻的状态才能做出判断。因此必须在检测之后引入**目标跟踪Multi-Object Tracking, MOT**算法。主流的方案如DeepSORT、ByteTrack或OC-SORT它们通过结合检测框的外观特征Re-ID模型和运动信息卡尔曼滤波为每个检测目标分配一个唯一的、持续的ID。这样系统看到的不再是一帧帧独立的“盒子”而是一条条有始有终的“轨迹”。流量统计就变成了统计轨迹的数量闯红灯判断则变成了分析某条轨迹与红灯信号周期内停止线位置的关系。2.2 业务逻辑层规则引擎的设计检测和跟踪提供了“是什么”和“在哪里运动”的数据而“是否违章”则需要业务规则来判断。这部分需要精心设计区域定义ROI我们需要在视频画面上虚拟地划出关键区域。例如检测区域只在特定的矩形或多边形区域内进行车辆和行人检测减少误检和计算量。停止线一条虚拟的线用于判断车辆是否在红灯时越过。禁停区域多边形区域用于判断是否违章停车。行驶方向判定区域通过设置虚拟的“入口线”和“出口线”结合轨迹方向判断车辆是否逆行。信号灯状态同步对于闯红灯检测这是最大的难点之一。理想情况下系统需要接入交通信号控制机的实时信号数据。但在很多旧路口无法实现。因此常见的替代方案是视频识别信号灯在画面中框定信号灯区域使用一个轻量级的分类模型如MobileNet或基于颜色的规则实时识别当前是红灯、绿灯还是黄灯。这种方法受天气、光照、摄像头角度影响大。间接推断通过观察主流方向车辆的集体运动状态来间接推断信号灯周期但这不精确仅作参考。注意在实际项目中信号灯信息的准确获取往往是项目成败的关键点需要在前期与业主明确技术路线和数据接口。违章判断逻辑以闯红灯为例核心逻辑是当信号灯为红灯时如果某个车辆的跟踪轨迹从停止线后方穿越到了前方则判定为一次闯红灯事件。需要加入“黄灯期间已过线的车辆不算违章”等细节规则。2.3 技术选型考量YOLO版本与后端框架标题中的“YOLO”是一个家族。从YOLOv5到最新的YOLOv11版本迭代很快。选型时需权衡YOLOv5/v8生态最成熟社区资源教程、预训练模型、部署工具最丰富是快速原型开发的首选。v8还统一了检测、分割、分类任务接口。YOLOv9/v10/v11学术上可能有更高的精度或效率但社区生态和部署工具链可能不如前两者完善更适合研究或对性能有极致要求的场景。对于后端框架OpenCV是处理视频流和图像操作的基础。但为了管理复杂的跟踪状态和业务规则建议使用如Python搭配多进程/多线程或异步框架如asyncio来构建应用或者采用更重量级的流处理框架如Apache Kafka 处理单元。3. 数据准备与模型训练实战任何AI项目数据都是基石。一个“.zip”文件里如果包含了代码那它很可能也预设了某种数据格式。3.1 数据集构建与标注交通场景的数据集通常包含小汽车、公交车、卡车、摩托车、自行车、行人等类别。公开数据集如BDD100K、COCO、UA-DETRAC是不错的起点但往往需要针对具体路口场景进行增补和微调。标注格式转换YOLO系列通常使用.txt标注文件每行格式为class_id x_center y_center width height坐标是归一化后的0-1之间。如果你的数据是VOCXML或COCOJSON格式需要编写脚本进行转换。网上有很多现成工具但务必检查转换后的坐标是否正确。# 示例将VOC XML格式转换为YOLO TXT格式的代码片段 import xml.etree.ElementTree as ET import os def convert_voc_to_yolo(xml_path, img_width, img_height, classes_list): tree ET.parse(xml_path) root tree.getroot() yolo_lines [] for obj in root.findall(object): cls_name obj.find(name).text if cls_name not in classes_list: continue cls_id classes_list.index(cls_name) bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 计算中心点和宽高并归一化 x_center (xmin xmax) / 2.0 / img_width y_center (ymin ymax) / 2.0 / img_height width (xmax - xmin) / img_width height (ymax - ymin) / img_height yolo_lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) return yolo_lines数据增强策略交通场景变化多端模型必须具有鲁棒性。在训练时务必使用强力的数据增强。Mosaic、MixUp、随机仿射变换旋转、缩放、平移、剪切、色彩抖动亮度、对比度、饱和度、色调都是非常有效的手段。YOLO官方训练代码通常已集成这些增强你需要做的是根据你的硬件和数据集大小调整增强参数的概率和强度。3.2 模型训练技巧与坑点假设我们选择YOLOv8进行训练。环境配置强烈建议使用Conda创建独立的Python环境。安装PyTorch根据CUDA版本、ultralytics包pip install ultralytics以及其他依赖。训练命令与参数解析yolo taskdetect modetrain modelyolov8n.pt datayour_dataset.yaml epochs100 imgsz640 batch16 workers4modelyolov8n.pt: 从官方预训练模型开始训练这是加速收敛的关键。n/s/m/l/x代表模型大小和精度。datayour_dataset.yaml: 这是数据配置文件是训练的核心。其内容大致如下# your_dataset.yaml path: /path/to/your/dataset # 数据集根目录 train: images/train # 训练集图片路径相对于path val: images/val # 验证集图片路径 # 类别数量和名称 nc: 6 names: [car, bus, truck, motorcycle, bicycle, person]imgsz640: 输入图像尺寸。更大的尺寸如1280可能提升对小目标的检测能力但会显著增加显存消耗和训练时间。batch16: 批大小。在显存允许的情况下尽可能设大有助于训练稳定。workers4: 数据加载的进程数。设置太多可能导致内存错误一般设为CPU核心数左右。训练过程监控训练开始后Ultralytics会启动一个本地Web服务器默认http://localhost:6006你可以实时查看损失曲线、精度指标mAP0.5, mAP0.5:0.95、验证集上的预测效果等。重点观察验证集mAP是否在稳步上升训练损失是否在下降且未出现剧烈震荡。常见训练问题损失为NaN或突然爆炸通常是学习率lr0设置过高。尝试减小lr0如从0.01降到0.001或使用更小的模型yolov8n开始。也可能是数据标注有严重错误如坐标超出0-1范围。mAP一直很低首先检查数据标注质量是否存在大量漏标、错标。其次检查数据集划分是否合理验证集和训练集的数据分布是否一致。可以尝试增加训练轮数epochs或使用更大的模型yolov8m, yolov8l。过拟合训练集精度很高但验证集精度上不去。解决方案是增加数据增强的强度或者使用早停Early Stopping策略在验证集精度不再提升时停止训练。实操心得不要一上来就追求大模型。先用yolov8n在小批量数据上跑通整个训练流程确保代码、数据、环境都没问题。然后再用完整数据集训练yolov8s或yolov8m。这样能节省大量调试时间。4. 系统集成与核心代码实现训练好模型假设得到best.pt只是第一步接下来要将其集成到完整的视频分析流水线中。4.1 视频流处理与目标检测模块我们将使用OpenCV捕获视频流并用训练好的YOLO模型进行推理。import cv2 from ultralytics import YOLO import numpy as np class TrafficAnalyzer: def __init__(self, model_pathbest.pt, conf_thres0.5, iou_thres0.45): 初始化分析器 Args: model_path: 训练好的YOLO模型路径 conf_thres: 置信度阈值低于此值的检测框将被过滤 iou_thres: NMS的IoU阈值 # 加载模型 self.model YOLO(model_path) self.conf_thres conf_thres self.iou_thres iou_thres # 定义类别映射需与训练时一致 self.class_names [car, bus, truck, motorcycle, bicycle, person] # 初始化跟踪器这里以简化示例实际应用DeepSORT等 self.tracker {} # 用于存储跟踪ID和轨迹 self.next_id 0 def process_frame(self, frame): 处理单帧图像 Args: frame: numpy数组BGR格式的图像帧 Returns: annotated_frame: 绘制了检测框和信息的图像 detections: 检测结果列表每个元素为 [x1, y1, x2, y2, conf, cls_id] # YOLO推理 results self.model(frame, confself.conf_thres, iouself.iou_thres, verboseFalse)[0] detections [] if results.boxes is not None: 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) for box, conf, cls_id in zip(boxes, confidences, class_ids): x1, y1, x2, y2 map(int, box) detections.append([x1, y1, x2, y2, conf, cls_id]) # 在帧上绘制检测框和标签 label f{self.class_names[cls_id]} {conf:.2f} cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) # 此处应调用跟踪算法如DeepSORT更新跟踪器self.tracker # track_ids self.update_tracker(detections) # 并将track_id绘制到框上 return frame, detections def run_on_video(self, video_path0, output_pathNone): 运行在视频文件或摄像头上 Args: video_path: 视频文件路径0表示摄像头 output_path: 输出视频路径None则不保存 cap cv2.VideoCapture(video_path) if output_path: fourcc cv2.VideoWriter_fourcc(*mp4v) fps int(cap.get(cv2.CAP_PROP_FPS)) width int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) out cv2.VideoWriter(output_path, fourcc, fps, (width, height)) frame_count 0 while cap.isOpened(): ret, frame cap.read() if not ret: break # 处理帧 annotated_frame, _ self.process_frame(frame) # 显示结果 cv2.imshow(Traffic Analysis, annotated_frame) if output_path: out.write(annotated_frame) # 按q退出 if cv2.waitKey(1) 0xFF ord(q): break frame_count 1 # 可在此处每隔N帧进行流量统计 cap.release() if output_path: out.release() cv2.destroyAllWindows() # 使用示例 if __name__ __main__: analyzer TrafficAnalyzer(model_pathruns/detect/train/weights/best.pt) # 从摄像头运行 # analyzer.run_on_video(0) # 从视频文件运行并保存结果 analyzer.run_on_video(test_video.mp4, output_video.mp4)4.2 目标跟踪集成以DeepSORT为例上面的代码只完成了检测。集成跟踪需要更多步骤。这里概述集成DeepSORT的核心思路安装DeepSORT库通常需要torchreid用于提取外观特征。封装跟踪器在TrafficAnalyzer类中初始化DeepSORT跟踪器。特征提取与关联对每个检测框使用一个Re-ID网络如OSNet提取特征向量。DeepSORT会利用特征相似度和运动信息卡尔曼滤波预测将当前帧的检测框与已有的跟踪轨迹进行关联匹配。更新跟踪状态匹配成功的轨迹更新其状态和位置未匹配的检测框可能初始化为新轨迹未匹配的轨迹则可能被标记为“丢失”持续若干帧后删除。# 伪代码展示在process_frame中集成跟踪的逻辑 def update_tracker(self, detections): 使用DeepSORT更新跟踪器 Args: detections: 当前帧的检测结果列表 [[x1,y1,x2,y2,conf,cls_id], ...] Returns: tracks: 更新后的跟踪列表每个元素包含 track_id, bbox 等信息 # 将检测结果转换为DeepSORT所需的格式 [x1, y1, x2, y2, conf] dets np.array([d[:5] for d in detections]) # 提取外观特征需要预训练的Re-ID模型 features self.extract_features(frame, dets) # 更新跟踪器 tracks self.deepsort.update(dets, features) return tracks4.3 流量统计与违章判断逻辑实现有了稳定的跟踪轨迹业务逻辑的实现就清晰了。流量统计在视频画面中定义一个虚拟的“计数线”。当一条轨迹的中心点从线的一侧运动到另一侧且满足方向条件时计数器加一。需要设置一个“已计数”标志避免同一轨迹重复计数。class TrafficFlowCounter: def __init__(self, line_start, line_end, directionleft_to_right): self.line_start line_start # (x1, y1) self.line_end line_end # (x2, y2) self.direction direction self.count 0 self.counted_ids set() # 记录已计数的轨迹ID def check_and_count(self, track): 检查一条轨迹是否穿过计数线 Args: track: 轨迹对象包含track_id, bbox, history等 if track.track_id in self.counted_ids: return False # 获取轨迹当前帧和上一帧的中心点 curr_center track.centroid prev_center track.history[-2] if len(track.history) 2 else None if prev_center is None: return False # 判断线段相交简化判断两点是否在直线两侧 if self.is_crossing_line(prev_center, curr_center): self.counted_ids.add(track.track_id) self.count 1 return True return False def is_crossing_line(self, point1, point2): # 实现几何判断逻辑判断线段(point1, point2)是否与计数线相交 # 此处省略具体实现 pass闯红灯检测这需要结合信号灯状态。假设我们有一个TrafficLightDetector来获取当前信号灯状态red,green,yellow。class RedLightViolationDetector: def __init__(self, stop_line, traffic_light_detector): self.stop_line stop_line # 停止线定义为[(x1,y1), (x2,y2)] self.tl_detector traffic_light_detector self.violations [] # 记录违章事件 def update(self, tracks, frame_timestamp): 更新检测器状态 Args: tracks: 当前帧的所有跟踪轨迹 frame_timestamp: 当前帧时间戳 light_state self.tl_detector.get_state() # 获取当前信号灯状态 if light_state ! red: return # 非红灯状态不进行闯红灯判断 for track in tracks: if track.track_id in self.violated_ids: continue # 已记录过该车辆违章 # 判断车辆当前位置相对于停止线 vehicle_pos track.centroid if self.is_behind_stop_line(vehicle_pos, track.history[-2]): # 上一帧在停止线后这一帧在停止线前 - 闯红灯 violation_event { track_id: track.track_id, timestamp: frame_timestamp, vehicle_type: track.class_name, bbox: track.bbox } self.violations.append(violation_event) self.violated_ids.add(track.track_id) # 触发告警保存截图、发送消息等 self.trigger_alert(violation_event)5. 工程化部署与性能优化让系统在真实的服务器或边缘设备上稳定、高效地运行是项目从Demo走向应用的关键。5.1 模型部署与加速在PC上开发用的PyTorch模型在生产环境中可能需要转换和加速。模型导出YOLOv8支持一键导出为多种格式。yolo export modelbest.pt formatonnx # 导出为ONNX yolo export modelbest.pt formatengine # 导出为TensorRT engine需要CUDAONNX通用交换格式可以被OpenCV DNN、TensorRT、ONNX Runtime等后端加载。TensorRTNVIDIA GPU上的极致推理加速框架能显著提升FPS。CoreML/OpenVINO分别针对苹果设备和Intel硬件优化。推理后端选择PyTorch开发调试最方便但原生推理速度不是最快。ONNX Runtime支持CPU/GPU性能不错部署简单。TensorRT在NVIDIA Jetson等边缘设备或服务器上追求极致性能的首选但转换和调试稍复杂。OpenCV DNN如果只需要CPU推理且希望依赖简单这是一个好选择。TensorRT部署示例简化import tensorrt as trt import pycuda.driver as cuda import pycuda.autoinit class YOLOTRTInference: def __init__(self, engine_path): # 加载TensorRT引擎 with open(engine_path, rb) as f, trt.Runtime(trt.Logger(trt.Logger.WARNING)) as runtime: self.engine runtime.deserialize_cuda_engine(f.read()) self.context self.engine.create_execution_context() # 分配输入输出内存GPU self.bindings [] self.outputs [] # ... 初始化内存和流 def infer(self, image): # 预处理图像拷贝到GPU执行推理后处理结果 # ... return detections5.2 多路视频流处理与系统架构一个路口可能有多个摄像头一个中心可能需要处理上百路视频。这就需要系统架构的支持。单进程多线程/多进程对于路数不多如16路的情况可以用Python的concurrent.futures创建线程池或进程池每个线程处理一路视频。注意GIL锁对CPU密集型任务的影响多进程能更好利用多核但进程间通信开销大。生产者-消费者模式使用消息队列如Redis, RabbitMQ。视频拉流模块作为生产者将视频帧放入队列多个推理工作进程作为消费者从队列取帧处理再将结果放入另一个结果队列。这种方式解耦性好易于扩展。流处理框架对于大规模应用可以考虑Apache Flink、Apache Storm或更专业的视频分析平台如NVIDIA DeepStream但属于闭源商业生态。DeepStream专门为多路视频流AI分析优化集成了硬件解码、推理、跟踪、渲染等流水线性能极高但学习曲线陡峭。5.3 性能优化技巧降低推理分辨率如果摄像头是1080p可以下采样到640x640再输入模型能大幅提升速度精度损失通常可接受。跳帧处理Frame Skipping对于流量统计不需要每帧都做高精度检测和跟踪。可以每2-3帧做一次全量检测中间帧只做跟踪预测和业务判断。这能成倍提升处理能力。模型剪枝与量化使用模型压缩技术如剪枝移除不重要的神经元、量化将FP32权重转换为INT8可以大幅减少模型体积和提升推理速度尤其适合边缘部署。TensorRT支持INT8量化。硬件解码使用GPUNVIDIA NVDEC或专用芯片进行视频解码比CPU软解快得多。OpenCV的cv2.VideoCapture如果编译了GPU支持可以设置CAP_PROP_HW_ACCELERATION。6. 常见问题排查与实战心得在实际开发和部署中你会遇到各种各样的问题。这里记录一些典型问题和解决思路。6.1 模型相关问题问题现象可能原因排查与解决思路检测框乱飞置信度低1. 训练数据与推理场景差异过大如白天训练晚上推理。2. 模型未收敛或过拟合。3. 输入图像预处理不一致归一化方式不同。1.数据一致性确保训练数据覆盖各种光照、天气、角度。使用数据增强。2.查看训练曲线确认训练loss已收敛验证集mAP达标。3.对齐预处理核对推理代码中的图像归一化如除以255、BGR2RGB转换是否与训练时完全一致。漏检严重特别是小目标1. 训练数据中小目标样本少。2. 模型输入分辨率imgsz太小。3. 置信度阈值conf_thres设得过高。1.增强小目标数据在数据集中增加包含小车辆的图像或使用copy-paste等增强技术。2.提高输入分辨率尝试将imgsz从640提高到1280。3.调整阈值逐步降低conf_thres如从0.5到0.3观察召回率变化。同一目标被重复检测NMS的IoU阈值iou_thres设置不合理。适当提高iou_thres如从0.45到0.6让重叠度高的框合并得更激进。但要注意别把相邻的不同目标合并了。6.2 跟踪相关问题问题现象可能原因排查与解决思路ID切换ID Switch频繁1. 检测器不稳定同一目标框位置抖动大。2. 跟踪器匹配阈值设置不当。3. 目标被遮挡后重现。1.稳定检测对检测框进行平滑滤波如卡尔曼滤波。2.调整跟踪参数如DeepSORT中的最大余弦距离阈值、最大IOU距离阈值。3.使用更强的Re-ID模型提高外观特征的表征能力。跟踪轨迹断裂1. 目标移动过快超出了卡尔曼滤波的预测范围。2. 检测器在该帧漏检。1.调整运动模型增大卡尔曼滤波的过程噪声协方差。2.补全轨迹允许跟踪器在目标短暂丢失如1-2帧后通过预测重新关联。计算资源占用高Re-ID模型特征提取耗时。1. 使用更轻量的Re-ID网络如OSNet-x0.5。2. 降低特征提取的频率如每隔几帧提取一次。3. 对跟踪目标进行裁剪和缩放减少输入Re-ID网络的图像大小。6.3 业务逻辑与系统问题流量统计不准除了ID切换还可能因为计数线位置设置不合理或者车辆在线附近徘徊导致重复计数。解决方案是加入“方向判定”和“防抖”逻辑例如要求轨迹必须从线的特定一侧穿过到另一侧并且在穿过线后一段时间内不再计数该ID。闯红灯误报率高最大的干扰源是“右转车辆”和“绿灯末期过线在路口中央变红灯”的情况。需要在业务逻辑中细化规则例如如果车辆轨迹显示其一直在最右侧车道且运动方向与右转导向线一致则即使红灯也可不判罚需结合当地交规。这需要更精细的轨迹分析和场景理解。系统延迟大从视频输入到结果输出耗时过长。需要系统性地 profiling是解码慢推理慢还是跟踪慢针对瓶颈优化。对于实时性要求高的场景如违章抓拍可以考虑“检测-初步判断-触发-高分辨率复核”的异步流水线降低平均延迟。踩坑心得在项目初期不要追求大而全。先聚焦一个核心功能比如只做车辆检测和流量统计把一条视频流跑通、跑稳。然后逐步引入跟踪、再增加一种违章检测。每增加一个模块都要进行充分的测试和评估。另外日志系统至关重要要在关键节点如检测、跟踪、违章判断输出带时间戳和帧号的日志这样当出现问题时你才能快速定位是哪个环节出了差错。最后永远对模型的性能保持怀疑在真实场景中部署前一定要用大量未见过的数据不同时段、不同天气进行测试评估其泛化能力。本文还有配套的精品资源点击获取