☰
2800张YOLO手机检测数据集:构建、标注与训练实战
2026/9/29 22:21:20 网站建设 项目流程

你有没有遇到过这类需求:教室后排想自动统计学生是不是在低头刷手机,办公区想看看下午有多少人摸鱼,停车场出口想提醒司机别在开车时碰屏幕。真动手做的时候你会发现,卡住你的往往不是YOLO怎么调参,也不是模型选v8还是v5,而是手里根本没有一份能直接用来训练的手机检测数据集。我整理的这套2800张YOLO目标检测数据集,就是为这类场景准备的。图片全部完成人工标注,标签统一为phone,格式可以直接接入YOLOv5/YOLOv8训练流程。下面我会把整个数据集的构建逻辑、标注约定、训练实测和踩坑记录都摊开来讲,打算做课堂玩手机检测、工位监察、驾驶分心提醒这类项目的朋友,可以直接照着来。

1. 为什么非要做一套专门的手机检测数据集

1.1 通用数据集里的手机根本不够用

很多人第一反应是“用COCO不就行了”,COCO里面确实有cell phone这个类,但当你单独去检测手机时,就知道它有多不靠谱。COCO是80类的大杂烩,手机在所有标注里占比很小,而且绝大多数是近景、大目标、干净背景的样张。真实场景里的手机是什么样的?可能只有画面里十几个像素,可能握在手里只露出三分之一,可能在夜间被屏幕照得一片惨白。拿通用权重直接去测,最常见的结果是:人倒是框得挺准,手机要么没框出来,要么把平板、笔记本适配器都框成了手机。专门做一套手机检测数据集,就是为了把这些通用数据集留下的坑全部填上。

我印象很深的一次测试是,直接用COCO预训练权重跑办公室摄像头画面,画面上同事手里拿着黑色手机从工位走过,模型全程没有给出一个手机框,反而把桌面上的黑色笔记本电源误检成了手机,置信度还高达0.7。这种结果其实不意外,COCO里的手机样本一般出现在近景的人像照片里,角度正、遮挡少、背景干净,模型学的特征偏理想化。一旦场景变成中远距离的室内监控视角,目标小、角度杂、光照乱,原来那套特征就全对不上了。

1.2 手机小目标的检测难点到底卡在哪

这套数据集设计时,我重点思考的就是“为什么手机检测比想象中难”。我把它拆成四类问题:

  • 小目标问题:监控摄像头位置高,手机在画面里经常只有几十个像素,YOLO默认的640输入下小目标特征很容易被池化层吃掉。
  • 反光与屏幕干扰:屏幕点亮时,整个矩形区域过曝,边缘被光晕糊掉,模型容易把亮斑当特征,换个角度就不认识了。
  • 形变与遮挡:手持、揣兜、贴耳、横屏打游戏,手机的形状变化很大,加上手部的遮挡,一个完整的矩形框经常装不下。
  • 背景混淆:黑色手机放在黑色桌面上,银色手机放在不锈钢设备旁边,边框和背景融为一体,模型很容易漏掉或者把类似色块误检出来。

这些问题直接影响数据采集和标注策略。比如同一个场景我至少要保证三个时间段的样本(白天、黄昏、夜间),同一个目标要覆盖“拿在手里”“放在桌上”“贴在耳边”三种姿态,目的就是让模型在训练阶段就把这些变化都见过。下面这个表是难点和数据集层面对策的对照,后面所有操作基本都围绕着这张表来展开:

难点对检测的影响数据集层面的对策
小目标漏检率高保留大量远景样本,配合Copy-Paste增强
屏幕反光特征漂移覆盖亮屏/息屏两种状态,避免只学亮斑
形态遮挡框不完整标注遮挡可见部分,加入手持、贴耳姿态
背景混淆误检补充黑色桌面、深色衣物等难负样本

2. 2800张图是怎么攒出来的

2.1 数据来源分三路,但每一路都要过脑子

攒数据我用了三条路同时走。

第一条是公开合规来源。像Open Images、AI Challenger这类目标检测数据集里本身含有手机相关图片,我从里面筛出手机占比较高的样张,按许可协议确认可用后拿来作为基础样本。这里提醒一句:从公开数据集筛图时一定要看授权条款,商用项目和实验室项目对版权的要求不一样,别踩了坑。

第二条是自己拍摄。我找了几部不同颜色、不同尺寸的手机当道具,分别在办公室、教室、走廊、户外、夜间街道等环境里拍摄,手机屏幕设置为亮屏、息屏、半亮三种状态。拍摄时不要只拍“好看的构图”,要刻意模拟真实监控视角——俯拍、远拍、隔一个工位侧拍。

第三条是视频抽帧。自己录几段自然场景的视频,按每3到5帧抽一帧,能得到大量背景略有变化但目标姿态连续的图片。抽帧的好处是后续训练时,模型能看到同一个手机在不同瞬间的位置变化,对小目标跟踪类任务特别友好。

我做了一个简单的配比实验:第一版只有公开筛选样本,测试集漏检率明显偏高;加入自拍和抽帧样本后,漏检率下降很明显。原因是公开样本里“摆拍感”太强,让模型学偏了。

我按下面这个场景清单来控制数据配比,最终凑齐2800张:

场景光线条件手机状态张数
办公室工位日光灯亮屏/息屏/桌面/手持600
教室后排混合光桌面/手持/遮挡500
走廊过道自然光手持/贴耳400
户外街道白天/黄昏手持/揣兜/贴耳500
夜间室内弱光屏幕亮起/息屏400
车内驾驶舱混合光支架/手持400

2.2 清洗筛选:宁缺毋滥

图片攒回来粗算有4000多张,最后只留了2800张,剩下的全删了。删掉的主要是这三类:

  • 手机在画面中占比小于1%的远景图。这种图不是不能学,而是在640分辨率下目标只有十几个像素,对训练YOLO的性价比太低。
  • 严重运动模糊到人眼都认不出的图。手机被快速拿起放下时很容易拍出这种帧,视觉上有个形状但完全没有边缘信息,标注了也是给模型喂噪声。
  • 目标被遮挡超过70%的图。只露出一个角或者只剩耳机线连着手机,这种标注框会给损失函数传递错误信号。

这个筛选过程不要心疼。数据量从来不是第一优先级,数据质量才是。2800张干净样本的训练效果,经常比4000张混入大量低质量样本的效果还要好。我当时把每一张被淘汰的图都记了个原因,回头再看,运动模糊占了四成,小目标占了三成,遮挡占了两成多,真正有价值却不小心删掉的图其实很少。

2.3 划分数据集时的“分层”技巧

训练、验证、测试我按2300/300/200来分,但这一步有个容易被忽略的细节:不要直接随机打乱划分,而是按场景先分层,再在各层里随机抽。也就是说,办公室场景、教室场景、夜间场景、户外场景各占多少比例,在划分时保持一致。如果直接随机划分,很可能验证集全落在白天办公室场景上,测试集却全是夜间场景,最后跑出来的指标虚高,一到真实环境就露馅。

另外还有个数据泄露问题要留意:同一个视频抽帧出来的图片,内容高度相似,如果一部分进了训练集,另一部分进了测试集,测试指标会被大幅高估。我的做法是按“视频片段”而不是按“单帧”来划分,保证同一个视频片段要么全在训练集,要么全在测试集。这个细节做目标检测的人容易忽视,但对于视频抽帧类型的数据它影响非常大。

3. 标注规范:一个框也是有讲究的

3.1 标注工具选择与流程

2800张图如果纯手工框,一个人大概要连续标两天半,很容易标到后面手抖。我的做法是先用X-AnyLabeling做半自动预标注,加载一个通用YOLO权重(比如YOLOv8s)先跑一遍预测,生成一批初始框,然后人工在工具里逐个修正。这样直接把标注时间压到一天以内。小批量数据或者你只是临时补几百张图,用LabelImg手动框也完全够,不用过度工具化。

这里有一个操作上的顺序建议:先把预标注模型调整到一个偏低的置信度,比如0.15,宁可多框出来一些错框,也不要在预标注阶段漏掉目标。漏掉的目标如果你没注意到,就会被直接跳过,比错框更麻烦。错框至少还在画面上,能被你一眼看到然后修正;漏框就彻底隐身了,检查的时候也很难发现。

3.2 标注边界约定:什么时候框,框哪里

拿手机检测这种单类标注来说,最容易出现分歧的就是边界。我定了一套自己的规则,也建议你提前定好,否则两个人标出来的框风格完全不同:

  • 只框肉眼可以明确识别为手机完整轮廓的可见部分,哪怕只有50%可见,有条件判断是手机就框。
  • 屏幕点亮时产生的光晕不算手机边界,按照机身轮廓来框,光晕属于背景。
  • 手机被手握住时,框可见的机身部分,不要把整个拳头框进去。
  • 画面里出现多个手机全部标注,不因为距离远、看不清就不标——除非目标确实小到人眼无法判断。

这些规则看着琐碎,但直接影响模型学到的边界回归能力。我第一版标注时没管光晕问题,结果模型把屏幕上的一片白光学成了手机特征,亮屏手机大量误检,后来花了一整天把亮屏图片重新过了一遍标注,再训练才恢复正常。

3.3 两轮校验机制

全部标注完成后,我做两轮检查。第一轮是脚本检查:框坐标是否越界、是否出现负值、同一目标是否有重复框、类别ID是否越界。第二轮是人工抽检:按场景各抽10%到20%,重点看难例标注是否一致。抽检不合规的标注比例超过5%,就让标注者统一重看一遍规则再修。这一步建议不要省,标注质量差一个等级,训练出来的模型就差一个等级,后面再去调loss曲线浪费时间,不如老老实实把框标好。

脚本检查我有几个可以直接用的规则:x_center、y_center必须在0到1之间,width、height必须在0到1之间且不为0,单个框面积不能超过全图面积的0.9,同一张图里两个框的IoU超过0.8时人工复查。这些规则写成一个几十行的Python脚本就行,跑一遍输出可疑样本列表,比肉眼扫几千张图靠谱得多。

4. YOLO训练实录:参数和坑

4.1 为什么先用YOLOv8n打底

选型我建议从YOLOv8n开始,而不是一上来就上YOLOv9或YOLOv10。原因有三:第一,手机检测属于单类目标检测,任务本身不复杂,n级的容量已经足够学出一个不错的baseline;第二,n参数量小,训练和推理都快,方便快速迭代数据质量;第三,后续如果用TensorRT部署到边缘设备,n级模型在Jetson这类平台上跑起来更现实。如果你想追求更高精度,可以在同一套数据集上直接升到YOLOv8s或m,数据不需要重新标注。

4.2 一份可以直接抄的训练配置

我用的是Ultralytics的YOLOv8训练流程,数据文件按YOLO格式写好,标签是txt文件,每行“class x_center y_center width height”,目标类别只有phone一类。数据集YAML长这样:

# phone_dataset.yaml path: /data/phone_dataset train: images/train val: images/val test: images/test names: 0: phone

下面这组参数是我实验下来比较稳的起点配置:

参数取值说明
modelyolov8n.pt用预训练权重做初始化,不是从零训
imgsz640后续可以试1280看小目标增益
batch16单卡显存16G以内建议别超过16
epochs300配合早停,实际跑不到300
optimizerSGD配合warmup,稳定性和精度都还行
lr00.01学习率,bn异常时降到0.005
mosaic1.0前200轮开启,后期可以关闭
hsv_h/hsv_s/hsv_v0.015/0.7/0.4色彩增强,对暗光场景很有用

训练命令大概是这样:

yolo train data=/path/to/phone_dataset.yaml \ model=yolov8n.pt \ epochs=300 \ imgsz=640 \ batch=16 \ optimizer=SGD \ lr0=0.01 \ patience=60

这里说下mosaic这个参数。mosaic增强对小目标检测很有帮助,因为它把小图拼接成大图,让模型在训练时更多看到相对小尺寸的目标。但它有个副作用:如果目标跨拼接边界被切断,标签框其实是不准的。所以我通常让mosaic一直开着跑到最后几十轮再关掉,让模型最后在干净分布里稳定一下。

4.3 训练中我踩过的两个坑

第一个坑是BN崩溃。这个词看起来吓人,其实就是训练没跑几步,loss突然飙升到几十上百,然后输出全是NaN。我在实际训练中遇到过两次:一次是显存不够把batch调成8之后出现的,一次是手滑把lr0设成了0.05。原因无非是学习率在warmup阶段之后设置得太激进,或者batch过小导致BN统计量不稳定。解决办法很简单:把lr0从0.01降到0.005,或者把batch从8提到16,重新跑一次基本就正常了。如果你用了自动找到的lr,也要人工看一眼曲线再往下训。

第二个坑是验证集loss在200个epoch附近开始回升,训练集loss还在往下降。这是典型的过拟合信号,说明模型开始背训练样本了。我的处理方式不是调模型,而是回数据:把HSV增强拉大一点,加入平移和轻微旋转增强;同时把早停patience设为60,让它自己在指标不再涨的时候停下来。手机检测本身类内差异很大,如果数据增强到位,300轮epoch通常到150到200轮就收敛了。

训练过程中我还会盯着三个曲线:box_loss稳步下降说明定位在学;cls_loss有波动是正常的,但整体趋势必须向下;如果val曲线出现“掉下去又拉上来”的锯齿状,大概率是学习率太大,把lr减少一半再看。

5. 实测效果和边界分析

5.1 测试集表现和真实场景感受

在这套2800张数据集的测试集上,我跑了几组实验,最终YOLOv8n的mAP50能稳定在0.94到0.96附近,mAP50-95在0.75到0.8之间。这个指标对单类检测任务来说属于正常偏好的水平。不同场景的表现也有差异,我简单记录了一下:

场景类别表现情况
室内日光灯很稳定,误检少
夜间屏幕亮起置信度很高,特征明显
黑色手机配黑色桌面容易漏检,对比度不够
隔着玻璃反射面偶尔出现重影框
快速拿起手机瞬间拖影导致模糊漏检

不过指标只能说明一部分问题。真正部署到实际场景后,我感受到的是“场景变了效果变化很大”:夜间屏幕亮起的帧,检测置信度很高,因为屏幕亮斑特征太明显了;但黑色手机放在黑色桌面上的背影,经常被漏掉。这说明测试集里没有完全覆盖极端低对比场景,后面要补的正是这类难负样本。

5.2 最容易漏检和误检的三种情况

  • 黑色手机加黑色桌面加俯拍:目标和背景几乎同色,模型很难区分边线。
  • 隔着玻璃或反光面拍摄:手机轮廓被倒影干扰,容易出现重影框。
  • 运动过程中的短时拖影:比如快速拿起手机时,画面边缘模糊到只剩一个虚影。

误检方面,最常见的是把黑色钱包、充电宝、手机壳色块、书脊误检成手机。这些误检来源都有一个共同点:尺寸和长宽比跟手机相似,纹理又被模糊掉了。想压制这种误检,最好的办法不是调NMS,而是把这些负样本收集起来,单独作为背景图混进训练集,让模型见过“长得像手机但不是手机”的东西。

5.3 提升真实场景召回率的三招

第一招:把Copy-Paste增强打开。将小目标手机随机粘贴到其他背景图中,可以在不增加人工标注的前提下,让模型看到更多小尺寸样本。这个增强对手机检测尤其有效,因为手机是刚性物体,粘贴后不会像猫狗那样变形失真。

第二招:测试时用TTA。把图片做水平和轻微旋转增强后多次推理再融合结果,模糊、低光场景的召回能提升,代价是推理时间翻倍。如果你做的是离线视频分析,TTA完全可以用;做实时检测的话就要慎重。

第三招:后处理阶段把置信度阈值调到0.2到0.25,配合更高IoU的NMS保留更多候选框;对误检较高的场景再单独调回来。这里要说明的是,阈值调低会带来更多误检框,所以一定要结合具体场景试验,没有一劳永逸的设定。

6. 后续迭代:从2800张到一个闭环

数据集的真正价值不在于一次性训练,而在于能不能滚起来。我现在用的迭代方式是半自动标注闭环:先用第一版模型对海量未标注视频抽帧做预测,产生一堆“预标注”,人工只修正那些置信度低于0.5的框,一天时间就能把数据集从2800张扩到5000张以上。扩完后再训练一版,新模型又能在更难的数据上工作,就这样滚雪球。

想把这个数据集往产品方向推的朋友,我建议下一步把“手机”拆成“手机普通状态”和“手机屏幕点亮”两类。这一点在实际项目中很重要,比如课堂玩手机检测,屏幕亮起时抓拍更有说服力,也可以减少误报。再加一个“耳机”类也不错,很多场景下戴耳机本身就是需要重点关注的行为特征。

部署层面的经验是:不要拿着nano模型直接上线,先在服务器上用高精度模型做离线评测,确认好误检率可接受,再导出ONNX用TensorRT或OpenVINO加速。精度和速度之间怎么权衡,一定要拿真实监控视频测,别拿测试集指标自嗨。我见过不少项目死在“测试集很漂亮、现场一塌糊涂”这一步,根源多半是数据场景覆盖不够,而不是模型结构不行。

这套数据集我自己迭代过程中最大的体会是:真正花时间的不是标注本身,而是定标准、筛数据、按场景分层、反复测边界。数据干净了,YOLO训练反而很快。你如果也在做类似的手机检测项目,建议先把这套流程走一遍,哪怕只凑几百张图,把数据和标注规范立住,后面所有调参和模型迭代都会顺手很多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询