恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
YOLOv8智慧校园人脸识别与公路车辆检测实战指南
首页
资讯中心
/
YOLOv8智慧校园人脸识别与公路车辆检测实战指南
YOLOv8智慧校园人脸识别与公路车辆检测实战指南
发布时间:2026/10/10 12:05:44
简介基于YOLOv8的智慧校园人脸识别与公路汽车检测项目面向AI入门及进阶学习者可直接用作毕设、课程设计或工程实训。项目实现校园门口进出人员识别通过yolov8l-face模型检测人脸、track技术持续跟踪再由dlib的resnet模型提取128维特征并与校内人员数据集比对识别成功以绿色标明未知人员显示红色正中实时统计已识别人数另一模块则执行公路车辆检测。压缩包共34个文件涵盖Python源码、yolov8系列与dlib模型文件、演示视频、人脸样本图片、字体及README说明文档整体大小334MB。已有459人学习适合通过源码研读、模型替换和视频实测复现整套流程并可为扩展到其他目标检测场景提供基础。1. 一个模型管两摊事智慧校园人脸识别和公路汽车检测到底在做什么校门口要刷脸才让进公路卡口要数清楚来来往往的汽车型号这两个场景过去是两套系统——一套做识别一套做检测。但这次拿到的“基于YOLOv8的智慧校园人脸识别和公路汽车检测”说白了就是让同一套YOLOv8检测模型同时输出“人脸框”和“汽车框”再在框后面接各自的后处理逻辑。这样做的直接收益是一套推理引擎、一套训练管线、一个模型权重文件就能覆盖校园安全通行和道路车辆统计两块业务。对学校或物业来说省下的不只是显卡钱还有运维和升级模型的精力。作为一线落地过类似项目的人我先说结论YOLOv8做这两件事完全够用但前提是你要分得清“检测”和“识别”的边界。人脸检测只负责把人脸位置框出来身份比对需要再过一道特征提取网络汽车检测则要细致到车型或品牌这通常需要额外属性分类头。本文会从环境搭建、数据准备、训练调参、部署推理和踩坑五个层面把这条路完整走一遍。新手能照着命令把训练跑起来熟手可以重点关注第四章的调参判断和第五章部署到边缘设备的细节。2. 环境搭建与模型选型从裸机到能跑起YOLOv8的完整命令2.1 用conda和pip装出干净环境顺便聊聊显卡和CPU的取舍YOLOv8靠ultralytics这个pip包就能跑不需要自己编译源码。我一般在Linux服务器上先创建独立的conda环境避免把系统Python搞乱。显卡驱动和CUDA要提前装好这步不难但很多人卡在cuDNN版本不匹配上。下面这套命令在Ubuntu 20.04 CUDA 11.8 PyTorch 2.0环境下实测过gtx1660ti都能正常跑。# 创建Python 3.9环境隔离依赖 conda create -n yolov8 python3.9 -y conda activate yolov8 # 安装PyTorch注意根据CUDA版本选对应命令 # CUDA 11.8就用这个别用默认的CPU版 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 安装ultralytics会自动带上opencv、numpy等核心依赖 pip install ultralytics # 验证安装能输出版本号就说明环境没问题 python -c from ultralytics import YOLO; print(YOLO.__version__)这里有一个关键选择如果手上只有gtx1660ti这类6G显存的卡训练小模型yolov8n/s没问题但yolov8l/x很容易爆显存。我的做法是先练n级模型验证流程流程跑通了再考虑要不要上大模型。CPU也能跑但一个1080p视频推理一次要几十秒只适合在无GPU的机器上调试代码真做实验还是得用显卡。2.2 模型规模怎么选从yolov8n到yolov8x按算力和误检接受度定YOLOv8有n/s/m/l/x五个规格参数从320万到6820万递增精度和速度也线性变化。智慧校园和公路汽车检测这两个场景都对实时性敏感门禁机和卡口设备通常用的是边缘盒子算力紧张所以不能盲目选最大的。下表是我自己常用的选型参考注意推理耗时是在gtx1660ti上用OpenVINO加速后的结果和实际部署设备可能略有差异。模型参数量输入640x640 mAP50推理耗时(ms)适合场景yolov8n3.2M0.683-5嵌入式设备、门禁机yolov8s11.2M0.716-8校园低算力服务器yolov8m25.9M0.7512-15公路卡口单路视频yolov8l43.7M0.7818-22服务器多路并发yolov8x68.2M0.8025-30离线圈注精度优先做智慧校园人脸识别时我用的是yolov8n因为人脸框只需要给后端特征提取网络提供裁剪区域框稍微偏一点不影响最终比对结果。公路汽车检测反而建议用yolov8s或m因为车辆在图像里占的面积大但是有大量重叠和遮挡小模型容易漏检尤其是摩托车和三轮车这类目标。另外要注意模型规模越大对标注质量的要求越高数据里错误标注会直接影响大模型的拟合而小模型反而“糊涂”一点泛化有时更好。2.3 “人脸是类别汽车也是类别”——同一套标签体系下如何组织数据集YOLOv8的类别是扁平化的你可以在一个数据集里同时定义“face”和“car”两个类别也可以拆成两个数据集分别训练再合并模型。我强烈建议拆成两个数据集分别训练。原因很简单人脸和汽车的角度分布、尺寸范围、成像特征差异太大放在一起训练会让特征提取器顾此失彼。实际工程里常见的做法是训练一个人脸检测器和一个车辆检测器部署时用两个推理流共享同一套推理框架这样后续单独迭代某一方时不影响另一方。如果你真的有需求要合并到一个模型里那要注意类别名不能重复数据集目录结构要统一。ultralytics的dataset.yaml用下面这种格式# dataset.yaml path: D:/datasets/smart_mix train: images/train val: images/val nc: 2 names: [face, car]然后训练时指定这个yaml。合并模型的坑是数据量失衡比如人脸图片1万张、车辆图片2千张模型会严重偏向人脸。要么对车辆数据做重采样要么给car类加loss权重。但说实话我做了几个项目后还是回到双模型路线维护起来更清晰。3. 数据准备与标注把人脸数据集和车辆数据集喂进YOLOv8的完整流程3.1 自制数据集的收集策略校园和公路的数据从哪来智慧校园场景的人脸数据可以拿门禁摄像头抓拍的录像抽帧注意要覆盖不同角度、光照早晨逆光、晚上低照度、戴眼镜/口罩等遮挡情况。公路汽车数据更简单找一段有车流的公开道路视频或已有的开源车辆检测数据集比如UA-DETRAC如果做的是特定路段最好自己架相机拍两天覆盖白天、黄昏、夜间车灯开启等状态。收集的目标是让每个类别至少有5000个标注实例不能只有背景不同的2000张图否则模型学不到类内变化。如果不想从零标注可以先用预训练权重对收集的图片做初筛只留下置信度高于0.8的检测框当作预标注再手动修正。这个技巧能省掉大概60%的标注时间但只适用于跑过一遍的基础模型。3.2 用LabelImg标注后转成YOLO格式一份可复用的转换脚本YOLOv8训练要求TXT格式的标签每行是“类别 x_center y_center width height”坐标是相对于图片宽高的比例。LabelImg直接能导出YOLO格式但如果你拿到的是VOC格式的XML或COCO的JSON就需要转换。下面这个Python脚本可以把VOC的XML批量转成YOLO的TXT我几乎每个项目都会改一改用。import os import xml.etree.ElementTree as ET from pathlib import Path def convert_voc_to_yolo(xml_dir, txt_dir, classes): 遍历XML文件夹把VOC格式转为YOLO格式。 classes是类别列表顺序决定类别ID。 os.makedirs(txt_dir, exist_okTrue) for xml_file in Path(xml_dir).glob(*.xml): tree ET.parse(xml_file) root tree.getroot() img_width int(root.find(size/width).text) img_height int(root.find(size/height).text) txt_path Path(txt_dir) / (xml_file.stem .txt) with open(txt_path, w) as f: for obj in root.iter(object): name obj.find(name).text if name not in classes: continue # 跳过没在classes里定义的标签 class_id classes.index(name) bbox obj.find(bndbox) x_min int(bbox.find(xmin).text) y_min int(bbox.find(ymin).text) x_max int(bbox.find(xmax).text) y_max int(bbox.find(ymax).text) # 坐标归一化 x_center ((x_min x_max) / 2) / img_width y_center ((y_min y_max) / 2) / img_height width (x_max - x_min) / img_width height (y_max - y_min) / img_height f.write(f{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n) if __name__ __main__: classes [face, car] convert_voc_to_yolo(VOC_xml, YOLO_txt, classes)转换时最容易犯错的是类别顺序。假如你之前用两个数据集分别训练各自定义了类别文件合并时必须保证classes顺序和yaml中的names一致。另外有些没有标注的xml文件会产生空txt训练时会报错建议在脚本里判断一下bbox是否存在或者训练前把空txt删掉。3.3 数据增强和train/val划分别让模型只认识白天和晴天YOLOv8自带的增强策略很激进尤其是随机翻转、HSV扰动、马赛克和MixUp对小数据集特别管用。但默认参数不能照单全收比如人脸检测里水平翻转没问题垂直翻转容易把脸搞变形我在配置文件里会关掉垂直翻转车辆检测更要注意颜色的扰动尺度如果夜间车灯过曝增强强度太大会让模型学得不稳定。ultralytics的设置方式有两种训练命令里的参数覆盖或者在代码里修改默认增强。我习惯用训练命令的覆盖方式清晰直观yolo train datadataset.yaml modelyolov8n.pt epochs100 imgsz640 batch16 hsv_h0.015 hsv_s0.7 hsv_v0.4 flipud0.0 mosaic1.0 mixup0.2参数说明hsv_h是色调扰动幅度0.015已经不小了flipud设为0.0是禁止垂直翻转mosaic和mixup是两种数据增强大数据集上可以适当提高小数据集建议保持默认1.0和0.1左右。数据集划分一般用8:1:1train/val/testultralytics会自动按val的比例切分但前提是images目录下所有图片都不带标签文件否则会在统计时错乱。我通常把划分脚本放在前面转换脚本后面统一处理保证同一图片的jpg和txt文件在同一个子目录下。4. 训练、监控和调参让人脸和车辆同时收敛不是玄学4.1 训练命令和超参数说明epochs、batch、lr、imgsz怎么定训练是门手艺超参数决定模型是收敛到良还是过拟合到渣。拿yolov8n做人脸检测举例我的基线命令长这样yolo train dataface.yaml modelyolov8n.pt epochs150 imgsz640 batch16 optimizerSGD lr00.01 lrf0.01 warmup_epochs3.0 patience30 device0这里几个参数值得细说。epochs设150是因为人脸数据集通常几百到几千张跑50轮往往欠拟合150轮以上loss才会彻底平稳。batch16在6G显存刚好能塞下640分辨率的yolov8n如果改成yolov8s就减到8或4。lr0初始学习率用0.01配SGD是经典做法但用AdamW时我会降到0.002。warmup_epochs是前几轮用低学习率预热能避免模型一上来就冲过头。patience30表示连续30轮val mAP没提升就早停防止周末挂机训练白耗电。还有一个容易忽略的是imgsz。训练时用640推理时想提速可以降到416或320但模型会损失小目标检测能力。公路汽车检测里有远距离的小车我建议训练就保持640千万别为了提速牺牲小目标召回。4.2 画损失函数曲线用train结果里的results.png和命令行日志做判断ultralytics训练完会自动生成runs/detect/trainN/results.png里面画了box_loss、cls_loss、dfl_loss、precision、recall、mAP50等一连串曲线。很多人只瞄一眼loss有没有降其实这里头信息量很大。我一般会先看cls_loss它反映分类分支学得好不好。人脸和汽车类别差异明显cls_loss应该直线下降并趋于平缓。如果cls_loss还在波浪起伏说明类别混淆严重要么是标注错误要么是两类目标太像比如人脸和圆形的汽车标志。再看box_loss它衡量框的回归精度。如果box_loss降到一个平台后还在缓慢下降说明模型在抠边界可以多跑点epochs如果box_loss突然反弹大概率是学习率过大了需要回调一下。命令行日志里每一行末尾有P、R、mAP50这些指标。我习惯在训练到一半时比如50轮暂停看一下val指标如果mAP50还不超过30%说明数据或模型有问题继续跑也白搭。需要自己画更细的损失曲线时可以写个脚本解析runs目录下的results.csv用matplotlib画出来。不过大多数时候内置的图已经够了我只会在论文或汇报时才导出原始数据重画。4.3 评估指标怎么看用mAP和PR曲线决定要不要加难例训练完有best.pt和last.pt用best.pt在val集上验证才靠谱。评估命令yolo val modelruns/detect/trainN/weights/best.pt dataface.yaml输出里有一张PR曲线图pr_curve.png和混淆矩阵confusion_matrix.png。PR曲线的横轴是Recall召回率纵轴是Precision精确率。曲线越靠近右上角越好。我关注的重点是曲线上“膝盖”的位置。如果P和R能同时到0.8以上说明这个模型在业务阈值比如confidence0.5下有很好的表现。如果R很高但P低说明误检多门禁机上会把路人甲框成人脸这时候就需要提高confidence阈值或者增加难负样本重新训练。如果P高但R低漏检多在公路车辆检测里更致命因为漏掉一辆车可能就漏掉一次违规记录。混淆矩阵能直接看出哪两类最容易互相认错。比如把车灯误检成人脸那就要检查是不是人脸和车灯在特征层有相似的圆形纹理。我会针对这些混淆对从训练集里挑出典型的负样本单独建一个难例数据集补训练效果比盲目加所有数据好得多。5. 部署与推理从PyTorch到RK3588和门禁机中间要走通这几步5.1 导出ONNX和TensorRT部署到RK3588前必须做的模型转换训练好的PyTorch模型是不能直接跑在边缘设备上的尤其RK3588这类集成了NPU的开发板需要先把模型转成ONNX开放神经网络交换格式再转成RKNN瑞芯微NPU的专用格式。转换过程用ultralytics自带的方法即可from ultralytics import YOLO # 加载训练好的模型 model YOLO(runs/detect/trainN/weights/best.pt) # 导出为ONNX动态输入宽高方便后续处理不同分辨率图片 model.export(formatonnx, dynamicTrue, imgsz640)导出的ONNX文件可以用onnxruntime跑一下验证输出是否正常。注意dynamic参数会让模型输入维度可变但有些NPU工具链不支持动态shape如果RK3588报错就把它改成固定640x640或416x416再导出。转换成RKNN的官方工具是rknn-toolkit2命令通常是在PC上模拟运行然后生成.rknn文件这一步根据瑞芯微官方文档走就行常见坑是ONNX算子不兼容比如某些激活函数版本太新。我通常的做法是先在PC上把模型导出为ONNX再用rknn-toolkit2自带的onnx2rknn脚本转换遇到不支持的算子就把模型里的这些层替换成基本运算。5.2 用摄像头实时推理read、infer、draw、write一条标准流水线不管是校园卡口还是公路摄像头推理代码的结构都是同一套读取帧、预处理、推理、后处理、画框、输出。下面这个Python片段演示了用yolov8封装好的predict方法直接跑实时流import cv2 from ultralytics import YOLO # 加载模型device0表示用GPURK3588上可以改成devicecpu配合RKNN runtime model YOLO(runs/detect/trainN/weights/best.pt) cap cv2.VideoCapture(0) # 0代表内置摄像头RTSP流就放“rtsp://...”地址 while True: ret, frame cap.read() if not ret: break # 推理conf是置信度阈值iou是NMS的IoU阈值 results model(frame, conf0.5, iou0.45, verboseFalse) # 拿到检测框和类别 boxes results[0].boxes.xyxy.cpu().numpy() # 左上右下坐标 classes results[0].boxes.cls.cpu().numpy().astype(int) confs results[0].boxes.conf.cpu().numpy() # 原图直接可视化 annotated results[0].plot() cv2.imshow(YOLOv8, annotated) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()关于参数conf和iou需要现场调。门禁机上人脸检测conf设0.5够了但如果有大量误检就调高到0.7公路车辆检测漏检率高时反而要降低conf到0.4宁可多框几个虚框也不能漏掉目标。iou主要影响重叠目标的保留车辆密集路段建议0.4以下避免两个紧挨着的大车被nms合并成一个框。另外代码里results[0].plot()已经帮我们画好框实际生产环境建议自己用OpenCV画可以更灵活地控制颜色和标签。5.3 从检测到识别人脸门禁机的身份比对和车辆属性分类思路人脸检测只是第一步真正的人脸识别还要提取高维特征向量。门禁机里常见流程是检测到人脸框后用一个MobileFaceNet或ArcFace网络把框内人脸变成512维向量再和库里注册的向量做余弦相似度。YOLOv8在这里的角色是人脸框裁剪器它的输出质量直接决定后续特征的稳定性。我通常会做一个质量控制模块只保留置信度高、框大小适中、人脸角度正面的检测结果去提取特征不然一个侧面脸提出来也会被拒识。公路车辆检测也类似如果要识别车型或品牌需要在检测框基础上再挂一个分类头。常见做法是训练一个单独的车型分类器输入是裁剪出的车辆图片输出是“轿车、SUV、货车”等类别。也可以用YOLOv8直接训练多类别把不同车型当作不同类。两种方式的取舍是多类别训练简单但需要重新标数据分类头方式可以复用检测模型且分类模型可以随时替换。我在做卡口车辆统计时通常只检测“car”一类属性统计用一个预训练的ImageNet模型直接跑裁剪图省时还准确。6. 避坑与进阶验证训练到上线后最常翻车的五个细节坑1人脸框在门禁机上乱跳时有时无。现象是同一张脸隔几帧框位置抖动置信度忽高忽低。原因多半是模型在边缘设备上用了INT8量化精度下降导致输出不稳定。解决方法是先看RKNN量化校准集是否覆盖了真实场景图片加入现场拍摄的帧做校准数据再把检测阈值提高一点同时在后处理里加一个基于时间的低通滤波框位置用最近5帧的平均值。坑2公路汽车检测漏掉摩托车和行人。现象是轿车和货车都检得很好摩托车、三轮车经常漏。原因是训练数据里摩托车实例太少模型没学到这个类。解决方法是回到数据侧单独收集摩托车和行人的样本做难例迁移学习而不是继续提高epochs。坑3夜间识别率骤降车灯糊成一片。现象是白天mAP能到0.75晚上直接掉到0.2。原因是原图在低光照下对比度太低以及车灯高光部分干扰检测。我一般会在推理前加一个自动曝光校正比如用OpenCV的CLAHE对亮度通道做自适应直方图均衡再把增亮后的图传入模型。训练时也可以在数据增强里模拟夜间亮度降低。坑4gtx1660ti训练yolov8m爆显存训练中断。现象是跑到10个epochs就报CUDA out of memory。原因自然就是batch太大。解决方法是把batch降到4或者用梯度累积ultralytics里有accumulate参数相当于每N个batch更新一次梯度能变相加大batch而不爆显存。坑5验证时精度高但现场视频里表现差。现象是val集mAP很高部署之后误检漏检频出。原因通常是现场数据分布和训练集差太多比如摄像头角度是斜俯视而你训练数据全是正视角。解决方法是在部署现场重新挑一段视频抽帧标注成测试集把现场指标低的那部分帧加到训练集里重训一遍。最后我习惯的做法是搭一个“自检金字塔”先跑通训练命令再画loss曲线再做val评估再导出一版ONNX丢到x86板子上跑最后上RK3588和现场摄像头联调。每一层走通了再往上爬别一次性把所有坑都踩完。这些流程跑下来你自然会发现模型和数据才是真正的核心工具只是帮你把它们变成生产力的桥梁。希望帮到你。本文还有配套的精品资源点击获取