
简介面向眼镜佩戴检测的YOLO系列目标检测数据集适配YOLOv5、YOLOv7、YOLOv8、YOLOv9、YOLOv10与YOLO11等主流算法解决训练数据难获取、标注格式不统一的问题。压缩包约127.93MB共2000个文件主体标注为XML文件配合图像可完成从训练到测试的完整流程。数据已按训练集与验证集划分并附带data.yaml配置能直接沿用常规YOLO训练命令标注同时提供YOLO格式TXT与VOC格式XML两种版本分别存在独立文件夹方便对比学习两种标注规范及其坐标系换算关系。已有128人学习下载适合需要快速落地眼镜识别、智能穿戴检查等场景的算法工程师、学生及研究者拿到后可省去人工标注和数据整理的重复工作专注于模型调优与效果验证。1. 眼镜检测数据集为什么我要拆这份双格式标注的YOLO资源做目标检测的同行应该都有过这种经历好不容易找到一个场景匹配的数据集结果只有VOC格式的xml还得自己写脚本转成YOLO的txt中间坐标换算错一位训练出来的模型框全是歪的。这两天我拆了一份眼镜检测数据集2948张图像、双格式标签齐全、已经划分好训练集和验证集、连data.yaml都配好了拿来就能直接跑yolov8训练。眼镜检测这个场景比想象中常用——安防闸机的穿戴合规检查、驾驶员疲劳监测里的眼镜佩戴识别、眼镜电商的SKU自动归类都绕不开这个细分类目。这篇笔记我把解压、格式校验、训练、验证到踩坑的完整过程写透新手能跟着出结果老手直接看边界参数。2. 数据集结构与双格式标注YOLO坐标和VOC坐标必须搞懂的换算关系2.1 压缩包解压后的目录布局与文件清单这份数据集解压之后根目录下不是一锅粥它分了三层图像文件、两个标签目录、一个配置文件。我实际操作时习惯先执行tree命令看全貌避免后面训练时报路径错误。# 解压后先看目录结构 unzip yolo眼镜检测数据集_2948张.zip -d glasses_dataset cd glasses_dataset find . -maxdepth 2 -type d | sort执行完能看到类似下面的结构glasses_dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── yolo/ │ │ ├── train/ │ │ ├── val/ │ │ └── test/ │ └── voc/ │ ├── train/ │ ├── val/ │ └── test/ ├── data.yaml └── 说明文档.txt这里的核心信息是训练集、验证集、测试集已经按比例分好不需要自己再写脚本去随机划分。images里的jpg和labels里的标签文件一一对应文件名前缀相同。data.yaml放在根目录稍后训练时直接用它指定数据集路径。2.2 YOLO格式txt的归一化坐标解析YOLO格式的标签文件是纯文本txt每一行描述一个目标框格式是class x_center y_center width height。这里容易翻车的点是这四个数值全部是归一化比例值范围0到1不是像素坐标。我随机挑了一个训练集标签文件拆解。# 读取任意一个yolo标签文件解析每一行的含义 with open(labels/yolo/train/img_0564_1092.txt, r) as f: for line in f.readlines(): parts line.strip().split() class_id int(parts[0]) # 类别索引0代表唯一类别眼镜 x_center float(parts[1]) # 目标框中心点x坐标相对图像宽度 y_center float(parts[2]) # 目标框中心点y坐标相对图像高度 width float(parts[3]) # 目标框宽度相对图像宽度 height float(parts[4]) # 目标框高度相对图像高度 # 反算像素坐标便于人工核验 img_w, img_h 640, 640 # 需要从对应jpg的实际尺寸读取 px int(x_center * img_w) py int(y_center * img_h) pw int(width * img_w) ph int(height * img_h) print(f类别{class_id}: 中心点({px},{py}) 宽{pw} 高{ph})这段代码做的事情是从归一化坐标反推像素坐标方便你拿画框工具或者OpenCV去验证标签是否贴合目标。我一般建议在训练前抽查20到30个标签确认标注框确实框住了眼镜而不是只跑一遍训练流程就完事。注意这里的class_id是从0开始的因为这份数据集只有眼镜一个类别所以所有txt里的class_id都是0。如果未来你想扩展到无框眼镜墨镜普通眼镜这样的多分类就需要手动修改标签的类别索引而且data.yaml里的names列表也要同步改。2.3 VOC格式xml的坐标体系与转换逻辑VOC格式的xml用的是绝对像素坐标。根节点annotation下有size节点记录图像宽高object节点里的bndbox记录xmin、ymin、xmax、ymax四个值。和YOLO的归一化中心点坐标是完全不同的两套体系。!-- labels/voc/train/img_0564_1092.xml 片段 -- annotation filenameimg_0564_1092.jpg/filename size width640/width height640/height depth3/depth /size object nameglasses/name bndbox xmin124/xmin ymin256/ymin xmax482/xmax ymax410/ymax /bndbox /object /annotation如果你从网上找来的数据集只有VOC标注又想跑YOLO系列就必须做格式转换。我个人总结的最稳转换公式是x_center (xmin xmax) / 2 / image_width y_center (ymin ymax) / 2 / image_height width (xmax - xmin) / image_width height (ymax - ymin) / image_height这个公式是硬编码在转换脚本里的一旦分子分母写反训练出来mAP会惨不忍睹。这份数据集已经帮你把转换做了两种格式分别放在两个目录里省掉了自己造轮子的时间。2.4 data.yaml配置文件的正确写法data.yaml是YOLO系列训练时的数据集描述文件它的作用是告诉ultralytics框架去哪里找图、去哪里找标签、类别有几个、类别叫什么。我打开这份数据集自带的data.yaml看了内容基本是这样的# data.yaml 内容 path: /absolute/path/to/glasses_dataset # 数据集根目录的绝对路径 train: images/train # 训练图像目录相对path val: images/val # 验证图像目录 test: images/test # 测试图像目录 # 类别定义 nc: 1 # 类别数量 names: 0: glasses # 类别名称注意train、val、test这三个字段指向的是图像目录YOLO框架会自动在images同级目录下找labels目录并且自动匹配txt标签。如果你的目录结构是images和labels平级就不要在yaml里写labels路径否则反而会报错。path字段建议改成自己机器上的绝对路径相对路径在某些版本的ultralytics里会识别失败。3. 环境搭建与YOLOv8训练实操从零开始跑通眼镜检测模型3.1 创建Python环境与安装ultralytics库先说一下我推荐的运行环境Python 3.9或3.10、CUDA 11.8以上、NVIDIA显卡驱动适配。如果你只有CPU机器训练速度会慢很多但也不是完全不能跑就是把epochs调大、模型选最小的nano版本。# 创建虚拟环境并安装ultralytics conda create -n yolo_env python3.10 -y conda activate yolo_env pip install ultralytics pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118安装完验证一下CUDA是否可用import torch print(torch.cuda.is_available()) # True表示GPU可用 print(torch.cuda.get_device_name(0))如果输出False大概率是PyTorch版本和CUDA版本不匹配。常见做法是去PyTorch官网换对应CUDA版本的whl安装命令而不是在ultralytics层面去排查因为ultralytics只是个上层框架底层计算全走PyTorch。3.2 训练命令与关键参数说明环境就绪后直接把data.yaml里的path改成你本机实际路径然后执行训练命令。我一般习惯用yolov8n作为起始模型因为它体量小、训练快先跑通流程再换大模型提精度。# 在glasses_dataset上级目录执行 yolo train modelyolov8n.pt dataglasses_dataset/data.yaml epochs100 batch16 imgsz640 device0这条命令的关键参数拆解如下modelyolov8n.pt从预训练权重开始训练收敛速度比随机初始化快很多。如果想从零训练改成modelyolov8n.yaml。epochs100训练轮数。100轮对于2948张图的单类检测任务来说是够的loss曲线通常在一个小时后趋于平缓。batch16批大小。显存不够时报OOM可以降为8或4。16G显存跑yolov8n是绰绰有余的。imgsz640输入图像统一缩放到640x640。这份数据集原始图像尺寸可能不一致ultralytics内部会自动做letterbox处理不会因为尺寸问题报错。device0指定用第一张GPU。如果是CPU机器改成devicecpu。训练开始后会打印一个进度条每个epoch末尾显示box_loss、cls_loss、dfl_loss以及mAP50、mAP50-95等指标。我一般重点关注mAP50这个指标在单类检测任务里能到0.92以上说明模型效果就很好了。3.3 训练权重的产物说明训练结束后runs/detect/train目录下会生成weights/best.pt和weights/last.pt两个权重文件。best.pt是在验证集上表现最好的那一轮权重last.pt是最后一轮权重。实际部署或继续训练时都用best.ptlast.pt只用于中断后resume。# 查看训练产物 ls -lh runs/detect/train/weights/ ls runs/detect/train/ | head -20训练目录下还会生成confusion_matrix.png、results.png、val_batch0_pred.jpg等可视化文件。results.png里画了三张曲线loss曲线、mAP曲线、precision和recall曲线。训练完第一件事不是看mAP数字而是看val_batch0_pred.jpg这个图确认预测框确实框在了眼镜上而不是框在鼻梁或额头上。4. 验证与推理用独立测试集检验模型真实泛化能力4.1 验证集评估val命令与指标解读训练完的模型必须在没参与训练的测试集上验证才能判断它的泛化能力。这份数据集已经分好了test目录直接用val命令指向test图像目录即可。# 用测试集验证模型效果 yolo val modelruns/detect/train/weights/best.pt dataglasses_dataset/data.yaml splittest执行结果会输出一份指标汇总重点看这五个值指标含义合理范围mAP50IoU阈值0.5时的平均精度单类检测0.90以上为优mAP50-95IoU从0.5到0.95取平均0.75以上为优precision预测框是正样本的比例0.9以上较好recall真实目标被召回的比例0.9以上较好fitness综合评分auto train时用它选优越大越好如果测试集mAP50比验证集低超过5个百分点说明模型过拟合了训练集需要加数据增强或换更小的模型。4.2 单张图像推理predict命令实战验证完指标再挑几张测试集之外的真实场景图做推理确认模型在不是数据集风格的图上也能工作。# 对本地图像做推理并保存结果 yolo predict modelruns/detect/train/weights/best.pt source./real_test_images/ conf0.25 saveTruesource参数可以指向图片、视频、目录甚至是摄像头ID。conf0.25表示置信度阈值低于这个值的预测结果会被过滤掉。如果推理结果显示很多框说明阈值设太低如果漏检多说明阈值设太高。我一般是先跑一遍conf默认值0.25看结果再调整。4.3 F1曲线和置信度阈值的配合使用ultralytics在val阶段会生成F1_curve.png它展示了不同置信度阈值下F1分数的变化。F1是precision和recall的调和平均用来找最佳阈值。我看这个图的习惯是找到F1最高点对应的置信度然后在predict时用那个阈值。比如F1曲线峰值在conf0.32说明模型在这个阈值下兼顾了误检和漏检那么predict时用conf0.32比默认的0.25更合理。这个细节对后续部署很关键——安防闸机场景宁可漏检也不愿意误报而电商分类场景则相反。5. 实操避坑眼镜检测数据集训练中我踩过的五个大坑5.1 路径问题导致Dataset not found现象执行yolo train命令后立刻报错Dataset xxx/data.yaml images not found或者提示找不到标签文件。原因data.yaml里path字段写的是解压前的临时路径或者train字段写的是相对路径但相对基准不对。我遇到过最常见的情况是yaml文件放在A目录数据集实际在B目录计算机找不到。解决把data.yaml里的path改成绝对路径并确认train、val的值是相对这个path的路径。修改后重新执行训练命令先加cacheTrue参数让框架加载一遍数据能过说明路径问题解决了。5.2 标签类别索引错位导致训练mAP异常低现象训练正常跑完loss掉下来了但mAP50始终在0.3以下徘徊预测框全打在图片角落。原因标签txt里的class_id大于nc定义的数量或者names顺序和标注时的类别顺序不一致。这份数据集只有class 0但如果你自己改过多分类很容易把VOC格式里的name和数字索引对不上。解决写一个小脚本扫描所有txt确认max(class_id) nc同时抽查几张图的标签内容。我一般会在训练前强制走一遍标签校验而不是训练完才发现。5.3 图像尺寸不统一导致训练效率低下现象训练日志里每个epoch耗时波动大有的epoch只要2分钟有的要5分钟。原因数据集里图像分辨率差距大有的图是1920x1080有的图是800x600。虽然ultralytics会自动resize到imgsz但resize计算耗时和内存占用不一样导致每个step耗时不稳定。解决训练前用脚本把所有图像统一缩放到1280x1280以内然后训练时imgsz640。统一尺寸后每个epoch耗时稳定而且模型收敛速度更快。5.4 显存不足OOM中断训练现象训练跑到第10个epoch左右直接报CUDA out of memory。原因batch_size设置过大或者图像尺寸太大。我踩过的一次是batch设为32imgsz设为1280两张卡都扛不住。解决batch直接降到8或4imgsz降到640。如果还需要更高精度用梯度累积——ultralytics里设置batch8同时accumulate4等效于batch32的效果但显存压力小很多。5.5 验证集指标高但实际场景表现差现象测试集mAP50有0.95但拿到真实监控画面里去推理漏检率很高。原因数据集图像和真实场景差异大——训练集全是正面拍摄的清晰眼镜图真实场景有侧脸、遮挡、光线暗、运动模糊。解决这种情况不是调参能解决的需要补充贴近业务场景的数据。常见做法是采集真实场景视频用训练好的模型做伪标注人工修正后加进训练集再迭代一版。这属于数据闭环工程比在现有数据上调参有效得多。6. 进阶数据增强参数调优与多分类扩展的真实经验眼镜检测这种单类目标模型容量不是瓶颈数据多样性才是。我自己的使用习惯是在ultralytics默认增强基础上适度增强但不要开太狠——增强过头会让模型学到的目标形态失真反而掉点。# 训练时在命令行内联增强参数 yolo train modelyolov8n.pt dataglasses_dataset/data.yaml \ epochs150 batch16 imgsz640 \ hsv_h0.015 hsv_s0.7 hsv_v0.4 \ translate0.1 scale0.5 fliplr0.5 mosaic1.0这几个增强参数我解释一下hsv_h是色调扰动幅度0.015不能太大不然眼镜颜色会偏到不自然hsv_s和hsv_v是饱和度和亮度扰动0.7和0.4在光照变化大的场景有效translate是平移扰动0.1表示最多平移图像宽高的10%scale是缩放扰动0.5表示尺度可以在0.5倍到1.5倍之间变化mosaic是四图拼接增强训练早期开启能显著提升泛化能力但最后10个epoch建议关掉。上述增强参数我跑过多次对比实验是稳定不掉点的区间。如果你想把是否戴眼镜扩展成三分类——无眼镜、普通眼镜、墨镜这个数据集的基础结构可以复用。操作上分两步第一步把现有单一类别标签先按图像内容重新标注出细分类别第二步修改data.yaml里的nc为3names列表改成对应类别名。类别不平衡的时候要注意比如墨镜样本只有200张、其他两类各1300张训练时模型会倾向预测样本多的类别这时候可以在loss里调整class weights或者在增强时对少数类做多倍采样。部署导出环节我习惯训练完直接把best.pt导出成ONNX格式yolo export modelruns/detect/train/weights/best.pt formatonnx imgsz640导出后配合ONNX Runtime推理不需要完整PyTorch环境适合放到边缘设备或服务端。TensorRT或OpenVINO的导出流程类似只是format参数不同。眼镜检测的推理延时在1080P输入、单张GPU上一般能压到10毫秒以内这个性能足够应对闸机或监控流的实时判断。最后说个习惯从那以后我做数据集训练前都会强制走一遍标签内容校验把每个类别的样本数、标签框宽高分布打印出来看一眼再动手。眼镜数据集这份资源我拆完最大的感受是好东西不用重做但基线流程一定要走完整——数据校验、路径修正、baseline训练、测试集验证四步到位后调参和加数据才有意义。希望这篇笔记能帮你在眼镜检测任务上少走几轮弯路。本文还有配套的精品资源点击获取