
简介这份资源是面向计算机、人工智能、自动化等专业学生与教师的YOLOv8实战项目包聚焦商场扶梯场景下的逆行行为预警可用于毕业设计、课程设计或大作业。项目包含训练与推理源码、可视化界面、完整数据集及部署说明部署流程简单运行后能生成核心指标曲线、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果与标签分布图便于答辩展示与结果分析。压缩包共8个文件以3个py脚本、3个pt权重和2个txt说明为主整体约15.91MB涵盖模型训练、视频检测与界面交互等模块。已有37人学习下载。读者可直接获得一套可复现的检测方案并在此基础上修改扩展功能适合作为项目初期立项演示或进阶学习参考。1. 扶梯逆行预警这件事为什么值得用 YOLOv8 认真做一遍商场扶梯的逆行行为是那种「平时不出事、出事就是大事」的典型场景。传统做法靠安保盯监控一个监控室十几路画面人眼根本盯不过来等发现有人逆着扶梯往下走往往人已经摔了。我最早接触这个需求是帮一个做智慧商场的团队做行为识别他们一开始想用红外对射加逻辑判断结果发现扶梯上人一多遮挡、并排、抱小孩这些情况全乱套误报率高到安保直接关掉报警。后来换成基于视觉的方案用 YOLOv8 做人体检测加轨迹方向判断才把误报压下来。这套《基于 YOLOv8 的商场扶梯逆行行为预警系统》本质上就是干这件事用 YOLOv8 检测扶梯区域内的人跟踪每个人的运动轨迹判断方向和扶梯运行方向是否相反一旦逆行就触发预警。它包含源码、可视化界面、完整数据集和部署教程简单部署即可运行适合毕设或课程设计。为什么选 YOLOv8 而不是更早的 YOLOv5因为 v8 的 anchor-free 头对小目标和密集人群更友好扶梯场景里人挤人、半身遮挡是常态这一点很关键。下面我按「先立住原理、再动手复现、最后讲坑」的顺序把整套方案拆开讲清楚。2. 逆行预警的技术骨架检测、跟踪、方向判定怎么串起来2.1 为什么是「检测 跟踪 方向」三段式而不是端到端行为分类很多人第一反应是直接上一个行为识别模型比如 SlowFast 或者 ST-GCN输入一段视频直接输出「逆行/正常」。我试过翻车了。原因有三个第一行为识别模型需要大量标注好的视频片段而扶梯逆行是低频事件你很难凑够正样本第二端到端模型的可解释性差安保看到报警不知道为什么报没法信任第三训练成本高毕设或课程设计的机器根本跑不动。所以更稳的路线是拆成三段YOLOv8 负责逐帧检测人体框ByteTrack 或 BoT-SORT 负责把帧间的人框关联成轨迹方向判定模块负责拿轨迹的位移向量和扶梯方向做比较。这样做的好处是每一段都可以单独调试、单独替换。检测不准就换模型或调置信度跟踪丢 ID 就调跟踪器的匹配阈值方向误判就改判定逻辑。整条链路是透明的出问题能定位。具体到方向判定核心逻辑是对每条轨迹取最近 N 帧的中心点坐标拟合出运动方向向量再和预设的扶梯运行方向向量做夹角计算。夹角超过阈值比如 90 度就判定为逆行。这里有个细节扶梯上正常乘客是站着不动的人是被扶梯带着走的所以轨迹方向其实反映的是扶梯方向。逆行的人是主动往下走速度会比扶梯快方向也相反。所以判定时不能只看方向还要看速度——如果一个人静止站在扶梯上他的轨迹位移方向就是扶梯方向这是正常的。2.2 数据集怎么准备标注规范与扶梯场景的特殊处理标题里说包含完整数据集但你要拿自己的商场画面跑还是得会自己标。扶梯场景的数据集有几个特殊点一是视角固定基本都是斜上方俯视人体框会有透视变形二是人群密集框和框之间重叠严重三是光照变化大商场中庭的玻璃顶棚会让画面忽明忽暗。标注用 LabelImg 或 Labelme 都行YOLOv8 要的是 YOLO 格式的 txt。每张图对应一个 txt每行是class_id x_center y_center width height全部归一化到 0-1。扶梯场景我一般只标一个类person因为逆行判定只关心人不需要区分性别年龄。标注时有个血泪经验被扶梯扶手挡住一半的人也要标哪怕只露出上半身因为跟踪器需要连续的检测框才能维持 ID漏标一帧就可能导致轨迹断裂。数据增强方面YOLOv8 内置了 mosaic、mixup、随机缩放这些。扶梯场景我建议额外加一点亮度扰动和运动模糊模拟商场灯光变化和摄像头轻微抖动。但不要用水平翻转因为扶梯方向是固定的翻转后方向就反了会让模型学到错误的左右关系。2.3 从标注到训练一份能直接跑的 YOLOv8 配置数据集目录结构按 YOLOv8 的要求组织dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/ └── data.yamldata.yaml内容path: ./dataset train: images/train val: images/val nc: 1 names: [person]训练命令用官方 CLI 就行不用自己写训练循环yolo detect train \ modelyolov8n.pt \ datadataset/data.yaml \ epochs100 \ imgsz640 \ batch16 \ device0 \ projectruns/escalator \ nameexp1参数说明model选yolov8n.pt是因为扶梯场景类别单一n 版本足够而且推理快适合实时预警imgsz640是精度和速度的平衡点如果你用 RK3588 这类边缘板部署可以降到 416batch16看显存GTX1660Ti 跑 640 大概能到 16显存不够就减半epochs100配合早停一般 60-80 轮就收敛了。训练完看runs/escalator/exp1/results.png里的损失曲线如果 val 损失还在降但 train 已经平了说明还能再训如果 val 开始翘头就是过拟合加 dropout 或减 epochs。2.4 跟踪与方向判定把检测框变成「谁在往哪走」检测只给你每帧的框跟踪才给你 ID 和轨迹。YOLOv8 官方支持 ByteTrack 和 BoT-SORT直接调from ultralytics import YOLO model YOLO(runs/escalator/exp1/weights/best.pt) results model.track( sourceescalator.mp4, trackerbytetrack.yaml, conf0.4, iou0.5, persistTrue, streamTrue )conf0.4是置信度阈值扶梯场景人密集调太低会有一堆误检调太高会漏掉被遮挡的人0.4 是我试下来比较稳的值iou0.5是 NMS 的 IoU 阈值人多的时候可以降到 0.45 减少框重叠persistTrue保证视频流里 ID 连续。拿到轨迹后方向判定我一般这么写import numpy as np from collections import defaultdict, deque track_history defaultdict(lambda: deque(maxlen30)) ESCALATOR_DIR np.array([0, -1]) # 假设扶梯向上画面 y 轴向下为正 def check_reverse(track_id, center): track_history[track_id].append(center) if len(track_history[track_id]) 15: return False pts np.array(track_history[track_id]) vec pts[-1] - pts[0] norm np.linalg.norm(vec) if norm 20: # 位移太小可能是静止站立 return False vec vec / norm cos_angle np.dot(vec, ESCALATOR_DIR) return cos_angle -0.3 # 夹角大于约 107 度判定逆行逻辑说明track_history存每条轨迹最近 30 帧的中心点ESCALATOR_DIR是扶梯运行方向的单位向量需要根据你的摄像头视角标定norm 20是过滤静止的人因为站着不动的人位移接近零方向向量没意义cos_angle -0.3是方向阈值对应夹角约 107 度留了一定容差避免斜着走的人误报。这个阈值要根据实际画面调太松会漏报太紧会误报。3. 可视化界面与部署让安保看得懂、跑得起来3.1 可视化界面要展示什么报警框、轨迹线、状态面板毕设和课程设计里可视化界面是加分项但很多人做成「为了好看而好看」堆一堆图表反而看不清重点。扶梯逆行预警的界面核心就三样实时画面叠加检测框和轨迹线、逆行报警高亮、状态统计面板。检测框用绿色画正常人红色画逆行的人框上标 ID 和速度。轨迹线用半透明的线把最近 30 帧的中心点连起来这样安保能直观看到「这个人是在往上走还是往下走」。报警时画面闪红边同时状态面板里逆行计数加一记录时间戳。用 PyQt5 或 Gradio 都能做。Gradio 更简单适合快速搭import gradio as gr import cv2 import numpy as np def process_frame(frame, model, tracker): results model.track(frame, persistTrue, conf0.4, trackerbytetrack.yaml) annotated results[0].plot() # 这里插入方向判定逻辑逆行的人框改红色 return annotated def run_demo(video_path): cap cv2.VideoCapture(video_path) model YOLO(best.pt) while cap.isOpened(): ret, frame cap.read() if not ret: break yield process_frame(frame, model, None) gr.Interface( fnrun_demo, inputsgr.Video(label上传扶梯监控视频), outputsgr.Image(label实时预警画面), title扶梯逆行行为预警系统 ).launch()逻辑说明model.track带persistTrue保证视频流里 ID 不跳results[0].plot()是 Ultralytics 自带的画框方法返回带框的 numpy 数组方向判定逻辑插在plot之后把逆行的框颜色覆盖成红色。Gradio 的yield让它变成流式输出看起来像实时视频。3.2 部署到边缘设备RK3588 和 CPU 版本的取舍标题说「简单部署即可运行」但实际落地时你得选部署平台。如果只是毕设演示笔记本 CPU 跑就够了yolov8n在 i5 上大概 15-20 FPS够用。如果要真装到商场就得考虑 RK3588 这类边缘计算盒功耗低、能 24 小时跑。RK3588 部署 YOLOv8 的流程是PyTorch 模型 → ONNX → RKNN。转换命令# 先导出 ONNX yolo export modelbest.pt formatonnx imgsz640 # 再用 rknn-toolkit2 转 RKNN python -m rknn.api.rknn_converter \ --onnx best.onnx \ --output best.rknn \ --target rk3588 \ --quantize \ --dataset dataset/images/val参数说明--quantize开启量化RK3588 的 NPU 对 int8 支持最好量化后速度能翻倍但精度会掉 1-2 个点扶梯场景类别单一掉这点精度可以接受--dataset指定量化校准集用验证集的前 100 张图就行不用太多。转完后用rknn-toolkit2的推理接口加载和 ONNX 的用法差不多。CPU 版本部署就简单了直接pip install ultralytics然后model.predict就行。Ubuntu 20.04 上装环境注意 Python 版本别太高3.8-3.10 最稳3.11 以上有些依赖会编译失败。3.3 报警联动从「看到」到「通知到人」预警系统光在界面上闪红没用得让安保收到通知。常见做法是接一个 webhook逆行触发时 POST 一条消息到企业微信或钉钉的机器人。代码很简单import requests import json def send_alert(track_id, timestamp, image_path): webhook 你的机器人webhook地址 payload { msgtype: text, text: { content: f扶梯逆行预警ID: {track_id}时间: {timestamp} } } requests.post(webhook, datajson.dumps(payload))注意别每帧都发会刷屏。我一般加一个冷却时间同一个 ID 30 秒内只报一次不同 ID 之间也做去重。另外报警图片存本地消息里带路径安保点开能看截图。4. 避坑与排查那些让我熬夜的翻车现场4.1 轨迹 ID 频繁跳变同一个人被当成好几个人现象画面里一个人正常走ID 从 1 跳到 5 又跳到 12方向判定模块拿到一堆碎片轨迹误报逆行。原因ByteTrack 的匹配阈值太严或者检测框抖动太大帧间 IoU 不够跟踪器认为是新目标。扶梯场景里人被扶手挡住、弯腰、抱小孩框的形状变化剧烈很容易丢匹配。解决把tracker换成botsort.yamlBoT-SORT 有 ReID 特征对形变更鲁棒同时把检测的conf从 0.4 降到 0.35让更多框进入跟踪器再不行就调track_high_thresh和track_low_thresh在bytetrack.yaml里改把低阈值调低让弱检测也能参与匹配。4.2 逆行判定在扶梯口误报人刚上扶梯就被报警现象人从平地踏上扶梯的瞬间轨迹方向是水平的和扶梯方向夹角接近 90 度被判定为逆行。原因扶梯口是方向过渡区人的运动方向从水平变成沿扶梯方向中间有个夹角。判定模块没做区域过滤把过渡区也算进去了。解决在画面里画一个多边形 ROI只对扶梯中段区域做方向判定扶梯口上下各留一段缓冲区不判。ROI 用cv2.polylines画判定前先cv2.pointPolygonTest检查中心点是否在 ROI 内。这个 ROI 每个摄像头都要单独标因为安装角度不同。4.3 夜间或逆光时检测框大面积丢失现象商场中庭玻璃顶棚下午逆光时画面过曝YOLOv8 检测不到人预警直接失效。原因训练集里逆光样本太少模型没见过这种极端光照。另外摄像头自动曝光在逆光时会压暗主体人变成剪影。解决训练时加亮度扰动增强hsv_v参数调到 0.6如果已经部署了在推理前加一个 CLAHE 自适应直方图均衡把暗部提亮。代码clahe cv2.createCLAHE(clipLimit2.0, tileGridSize(8, 8)) frame_lab cv2.cvtColor(frame, cv2.COLOR_BGR2LAB) frame_lab[:, :, 0] clahe.apply(frame_lab[:, :, 0]) frame cv2.cvtColor(frame_lab, cv2.COLOR_LAB2BGR)clipLimit2.0控制对比度增强幅度太高会放大噪声tileGridSize(8,8)是分块大小画面大就调大。4.4 模型在本地跑得好部署到 RK3588 后精度暴跌现象PyTorch 模型 mAP 0.85转 RKNN 量化后掉到 0.6漏检严重。原因量化校准集选得不好或者量化时用了对称量化而 YOLOv8 的激活值分布不对称。解决校准集要用有代表性的图别只用几张至少 100 张覆盖不同光照和人群密度量化时用quantized_dtypeasymmetric_quantized-8非对称量化如果还不行就只量化卷积层检测头保持 fp16精度能回来不少。4.5 多路视频同时跑帧率掉到个位数现象一个盒子接 4 路摄像头每路都跑 YOLOv8GPU/NPU 跑满帧率从 25 掉到 5。原因没做批处理每路单独推理NPU 利用率低。另外视频解码也占资源。解决把 4 路画面拼成一张大图一次推理再拆开结果。RK3588 的 NPU 支持 batch拼图后 batch4吞吐能翻倍。解码用硬件解码ffmpeg的h264_rkmpp或 OpenCV 的cv2.CAP_GSTREAMER。如果还不行就降分辨率640 降到 416速度能提 40%。5. 把预警做成「可验证」的系统几个我常用的调优技巧5.1 用混淆矩阵反推阈值而不是拍脑袋方向判定的cos_angle阈值和位移norm阈值很多人凭感觉设结果要么误报要么漏报。我一般会标一段测试视频人工标出所有逆行片段然后跑一遍系统统计不同阈值下的 TP、FP、FN画 ROC 曲线选 F1 最高的点。这个流程用 sklearn 几行就能做from sklearn.metrics import precision_recall_curve, f1_score import numpy as np # y_true: 人工标注1 逆行 0 正常 # y_scores: 系统输出的 cos_angle 值 precision, recall, thresholds precision_recall_curve(y_true, -y_scores) f1 2 * precision * recall / (precision recall 1e-6) best_thresh thresholds[np.argmax(f1)] print(f最佳阈值: {-best_thresh:.3f}, F1: {max(f1):.3f})注意y_scores取负因为 cos_angle 越小越可能是逆行而 sklearn 默认分数越大越正。跑完你会得到一个有数据支撑的阈值比拍脑袋靠谱得多。5.2 用「轨迹平滑」压掉抖动误报检测框逐帧抖动会让方向向量乱跳偶尔触发误报。我一般对轨迹中心点做一次滑动平均或卡尔曼滤波再算方向。滑动平均最简单def smooth_track(pts, window5): if len(pts) window: return pts kernel np.ones(window) / window x np.convolve(pts[:, 0], kernel, modevalid) y np.convolve(pts[:, 1], kernel, modevalid) return np.stack([x, y], axis1)window5是平滑窗口太大方向会滞后太小压不住抖动5 帧在 25 FPS 下是 0.2 秒够用。平滑后再算方向向量误报能降一半。5.3 一个我坚持的习惯每次改完参数先跑固定测试集调参最怕「改完感觉好了其实只是换了个视频」。我习惯留一段 5 分钟的固定测试视频包含正常上行、正常下行、逆行、静止站立、人群密集五种情况每次改完参数先跑这段看各项指标有没有退化。这个习惯帮我避免了好几次「调好一个场景、搞坏另一个场景」的翻车。这套方案从检测到跟踪到方向判定链路是完整的源码、界面、数据集、部署教程都齐了拿来跑通不难。难的是把它调到能在真实商场里稳定运行那需要你对着实际画面反复调 ROI、阈值和平滑参数。我踩过的坑上面都写了希望帮到你。本文还有配套的精品资源点击获取