
简介本资源是面向计算机视觉初学者与目标检测实践者的X光安检图像专用数据集聚焦包内违禁/常见物品识别任务可直接用于YOLOv5等主流框架的模型训练与验证。数据集严格遵循YOLOv5目录结构组织含2880张训练图像与720张验证图像均为300–500分辨率RGB图每图配对应txt标签文件共1999个标注文件另附类别索引txt字典及可视化脚本show.py支持一键加载任意图像并绘制带类别标签的边界框结果自动保存开箱即用。压缩包总计2000个文件大小377.08MB以txt标注文件为主辅以Python工具脚本无需额外格式转换或路径调整。目前已有386人学习下载特别适合开展安检场景下的小样本目标检测实验、模型迁移训练或课程设计项目。 做安检X光图像的目标检测最头疼的问题之一就是数据集。自己采集、标注成本高得离谱网上公开的要么分辨率太低要么类别跟实际业务对不上。我最近把手头一个实际项目的数据集整理成了标准YOLOV5目录格式类别覆盖安检机场景下常见的10种随身物品这里把整个数据集的设计思路、标注规范、目录组织方式以及基于它训练的全过程都拆开讲清楚包括我踩过的坑和实测有效的调优手段给准备做安检场景目标检测、或者想用YOLOV5训练自定义数据集的同学一份可复现的参考。1. 数据集定位与场景难点拆解1.1 安检X光图像为什么比普通图像难做先说结论安检机X光图像下的目标检测难度远高于日常生活中的RGB图像检测。很多人第一次拿到X光图片会下意识觉得这不就是灰度图吗跟普通照片做检测差不多实际跑一轮训练就会发现完全不是一回事。X光成像的原理是不同密度的物体对射线吸收程度不同穿透后在探测器上形成明暗差异的图像。金属、玻璃、塑料、液体、有机物密度不同在图像上呈现的灰度区间差异很大。这就带来第一个问题同一个物品在不同角度、不同材质干扰下外观差异极大。一个不锈钢保温杯和一个玻璃杯在X光下可能看起来很接近一块巧克力有机物和一块肥皂形状相似时几乎分不出来。第二个难点是物品重叠。行李箱和背包里物品是三维堆叠的X光是透射成像所有层的物品都叠加在同一张二维图像上。这意味着一个检测框里往往混着两三个物品边缘信息严重缺失。这对标注和模型训练都是巨大挑战。第三个问题是图像风格不统一。不同品牌、不同型号的安检机射线源能量、探测器灵敏度不一样出来的图像灰度分布差异明显。同一台机器在正常使用过程中随着设备老化、温度变化图像亮度和对比度也会漂移。如果数据集来源单一训练出的模型很容易过拟合到某台机器的成像风格上换个环境就废。第四个问题是样本不均衡和长尾分布。像手机、充电宝、钱包这类常见物品出现频率高而刀具、打火机这类违禁品出现频率低。但后者的检测召回率恰恰是安检业务最看重的指标。单纯的常规目标检测训练方式在这种长尾分布下表现往往不理想。1.2 为什么选择YOLOV5目录格式很多做算法的人会纠结用YOLOV5还是YOLOv8、YOLOv10或者要不要上anchor-free。我的建议是如果应用场景是落地部署且需要快速迭代YOLOV5目录格式仍然是目前兼容性最好、生态最成熟的选择。YOLOV5目录格式本质上指的是数据集的目录组织方式images和labels两个大目录各自按train/val划分标签文件为同名的txt文件每一行对应一个目标框格式是class_id cx cy w h归一化到0到1之间。这个格式本身已经是目标检测领域事实上的通用标准了。选它有几个非常现实的理由。第一几乎所有现代目标检测框架YOLOv5、YOLOv8、YOLOv9、YOLOv10、YOLO11、MMDetection都支持直接读取或通过简单转换读取这种格式数据集的复用价值很高。我现在这个数据集如果将来要迁移到YOLOv8上训练几乎零成本。第二这种txt标签格式纯文本、体积小单张图片内即使有几十个目标也才几KB处理起来非常轻量。第三它对数据增强的兼容性极好无论是mosaic、mixup还是随机仿射变换都能方便地同步变换标签坐标。相比之下COCO格式虽然是JSON包含的信息更丰富如segmentation多边形但在YOLO系列训练时的读取效率、随机操作时的标签同步复杂度都不如txt格式。不是说COCO不好而是在当前场景下YOLOV5目录格式就是那个性价比最高的方案。2. 数据集整体设计与标注细节2.1 10个类别的选取逻辑这个数据集的类别定为10类是我从实际安检场景里筛选出来的高频物品类别。既要覆盖常见随身物品又不能让类别太细导致标注难度爆炸。我用的具体类别是类别ID中文名称英文名称0手机phone1充电宝power_bank2笔记本电脑laptop3瓶装液体bottle4金属罐can5刀具knife6剪刀scissors7打火机lighter8雨伞umbrella9钥匙串keys选这10类有几个考量角度。首先是辨识度的可行性比如刀具这类在X光下轮廓特征比较明显形状和密度都有特点标注的框一致性较高。其次是业务关联性刀具、打火机本身就属于敏感物品瓶装液体在部分场景也需要关注。最后是类别之间的区分度这10个类别在X光图像里形状和密度分布有差异不会出现类别间特征完全混淆、连人都标不准的问题。这里也踩过坑。最初我把水杯和瓶装液体分成两个独立类别结果标注员在重叠场景下经常分不清训练出来的模型两个类的mAP都在50%以下。后来合为一个瓶装液体类效果一下子起来了。所以在设计类别时一定要考虑到X光成像特性下同类物品的视觉一致性宁可粗一些也不要为了看起来精细而分出实际无法稳定区分的类别。2.2 标注规则与边界框处理标注规范是数据集质量的生命线。如果只定一个用矩形框框住目标的规则标注出来的数据一定让人崩溃。我在标注规范上重点约束了以下几点。第一边界框的贴合度。X光图像中物品边缘通常有灰度过渡带标注时框需要贴合到物体中灰度明显变化的位置预留过渡带会降低定位精度。对于重叠物体如果能区分出前景应完整框出最上面物品被遮挡部分不用管如果两个物体融合在一起无法分辨边界则合并标注为一个框并把类别标为体积更大、特征更明显的那个。第二最小标注面积的处理。在YOLOV5的标签规范中框的宽高不能为0否则训练时会直接报错或忽略该目标。我设的标注阈值是像素面积不小于36像素约6x6小于阈值的极小目标不标注避免产生过多低质量小框。在X光图像里钥匙串上的单个钥匙极小通常不会单独标注而是把整串钥匙作为一个目标框。第三多角度覆盖要求。同一个物品在行李箱中平放、竖放、侧放、被其他物品部分遮挡都是有效的训练样本。标注时我会确保每个类别都包含至少20%的遮挡样本和15%的小尺寸样本防止模型过拟合单一姿态。第四类别不确定性处理。有些物品在X光下确实无法从形状和密度判断类别比如同为方形的充电宝和硬盘标注规则规定凡是标注员无法置信判断的实例一律不标注而不是猜测一个类别。猜测出来的标签比漏标危害更大因为标签错误的样本会直接给模型传递错误信息。2.3 数据集规模与划分策略这个数据集整个包含大约9000张图像其中目标框总数为41237个平均每张图像约4.6个目标。我用一个随机种子将数据按8:1:1划分为训练集、验证集和测试集但不只是简单随机而是对类别分布做了约束。具体做法是保证在每个划分中所有10个类别都至少出现一定比例并且测试集中每一类都有足够样本不低于200个框。我写了一个脚本检查每个类别在每个划分中的框数量如果某一类在训练集中不足就用分层抽样补充直到满足条件。这个步骤在多人项目里尤其重要因为标注进度和质量参差不齐随机划分很容易让冷门类别在某个集合里几乎不出现。从实测效果看9000张图像、4万多个目标框在YOLOV5s模型下训练mAP50可以到78%左右。如果数据量降到3000张mAP50会掉到65%以下。X光图像的复杂度决定了它对数据量的需求比普通场景高很多条件允许的话我建议直接朝着2万张以上努力。3. YOLOV5目录结构与配置文件详解3.1 标准的目录组织方式拿到这批数据之后先按YOLOV5的标准目录格式整理。下面是最终的项目目录结构xray_dataset/ ├── images/ │ ├── train/ │ │ ├── 000001.jpg │ │ ├── 000002.jpg │ │ └── ... │ └── val/ │ ├── 000101.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── 000001.txt │ │ ├── 000002.txt │ │ └── ... │ └── val/ │ ├── 000101.txt │ └── ... ├── data.yaml ├── classes.txt └── README.mdimages和labels下的同名文件一一对应。比如images/train/000001.jpg对应labels/train/000001.txt。每一行txt内容示例0 0.453125 0.617188 0.098958 0.156250 5 0.781250 0.328125 0.145833 0.083333第一个数字是类别ID后面依次是归一化的中心点x坐标、中心点y坐标、归一化宽度、归一化高度全部为0到1之间的小数。注意是中心点坐标不是左上角坐标。这个细节容易写错写错后训练不会报错但目标框会整体偏移甚至跑到图像外面去。images/train里图像的格式我统一转成了JPG分辨率统一缩放到不低于640x640的尺寸宽或高的短边不低于640。X光原始图像通常是1536x1024或者1280x960直接训练也行但会显著增加显存占用。如果原始分辨率是1280x960而训练尺寸设置成640x640YOLOV5会在加载时自动做letterbox缩放不会破坏标签坐标。但我仍然建议先将图像统一缩放好再放进目录这样数据预处理阶段的变量更少排查问题更方便。3.2 data.yaml与超参数配置data.yaml是YOLOV5训练的核心配置文件它告诉模型去哪里找数据、有多少个类别。我的data.yaml长这样train: /data/xray_dataset/images/train val: /data/xray_dataset/images/val nc: 10 names: [phone, power_bank, laptop, bottle, can, knife, scissors, lighter, umbrella, keys]这里有个值得注意的细节train和val路径既可以写绝对路径也可以写相对于yaml文件的路径。我建议在多人协作时使用完整绝对路径避免因为工作目录不同而找不到图片。另外val目录不一定非要单独准备可以直接指向train但强烈不建议这会导致训练时看不到真实分布外样本的评估效果。如果是从零开始训练超参数的初始配置可以从YOLOV5自带的默认值位于data/hyps/hyp.scratch-low.yaml开始。针对X光图像场景我会把mosaic增强的概率调到1.0默认是1.0所以不用动同时把copy_paste增强打开因为X光图像中物品的重叠现象本身非常常见模拟重叠训练有助于模型理解真实场景。数据增强方面YOLOV5默认开启的HSV变换对X光灰度图像基本没有意义因为灰度图像没有颜色信息。如果训练时保留HSV增强虽然能正常跑但会白白增加计算开销。不过我发现保留一定的饱和度扰动saturation参数在0到0.2之间对伪彩色的X光图像还是有效的因为部分安检机会输出类似橙黄色的伪彩色图像保留饱和度增强能让模型对这些图像保持鲁棒。4. 训练实操与关键参数选择4.1 灰度单通道图的通道适配问题X光图像有相当一部分是单通道灰度图而YOLOV5默认接收3通道RGB输入。直接用opencv读取灰度图后喂给模型会发现维度不匹配报错。YOLOV5的LoadImages类在读图时使用cv2.imread如果原图是单通道cv2默认返回shape为(h,w)而不是(h,w,3)在进入模型时就会挂掉。处理办法是写一个预处理函数在数据加载前把所有灰度图统一复制到三个通道变成伪RGB。我用的代码如下import cv2 import numpy as np def ensure_three_channel(image_path): img cv2.imread(image_path, cv2.IMREAD_UNCHANGED) if img is None: raise ValueError(f无法读取图像: {image_path}) # 如果图像是单通道则复制为3通道 if len(img.shape) 2: img cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) # 如果图像是4通道RGBA则丢弃alpha通道 elif img.shape[2] 4: img cv2.cvtColor(img, cv2.COLOR_RGBA2BGR) return img更推荐的做法是在生成数据集的过程中就把全部图像统一转成3通道JPG而不是在训练时动态转换。这样中间环节少报错也更容易定位。我在实际项目里就是这么干的一条命令批量处理所有图像顺带做一次坏图检查一举两得。4.2 训练参数选择与收敛调整我用YOLOV5s作为基线模型输入尺寸640x640batch size设置为32在24GB显存上轻松跑初始学习率lr00.01epochs设为200。训练过程使用AMP混合精度加速。下面是我实测的一次完整训练曲线总结。前50个epochloss从0.06左右快速下降到0.02附近mAP50从0快速上升到0.6左右。50到120个epochloss下降变缓mAP稳步爬升到0.73。120到200个epoch训练进入平台区mAP50最终收敛在0.78左右mAP50-95大概在0.52。这个表现对X光复杂场景来说已经算不错了。有一个参数组合对X光场景的影响最大图像分辨率和NMS阈值。训练输入尺寸从640提升到1280对小物体的mAP提升非常明显特别是打火机、钥匙串这类小目标。但推理速度会慢很多。实测在NVIDIA 3090上640输入推理一张图大约5ms1280输入要16ms左右。如果你的场景对小目标灵敏度要求高比如违禁品检测强烈建议至少用960输入尺寸训练和推理。NMS的置信度阈值我训练时设置为0.5推理时设为0.25IOU阈值用0.45。训练时的置信度阈值影响候选框的保留推理时的阈值决定最终输出。X光图像中重叠严重如果推理时IOU阈值调得太高比如0.7重叠物品会被合并成同一框漏检率上升调得太低又会出现同一个物品被框多次。0.45是经过多组对比后效果比较平衡的值。4.3 预训练模型vs从零训练X光图像和ImageNet自然图像在特征分布上差异巨大一个常见的问题是用YOLOV5官方提供的COCO预训练权重做迁移还是完全从零训练我的实测结论是即使特征差异大预训练权重仍然有正迁移效果。我分别跑了两组实验一组使用yolov5s.pt预训练权重另一组随机初始化权重。同样是200个epoch预训练组的最终mAP50约为0.78从零训练组约为0.71。预训练权重前期收敛明显更快大约在70个epoch时就超过了从零训练组150个epoch的水平。原因也不难理解。YOLOV5在COCO上预训练学到的基础特征能力比如边缘检测、纹理感知、空间结构归纳对X光图像也是通用的只是最后的语义类别完全不同。迁移学习在这种场景下的瓶颈并不是特征差异太大不能用而是需要在微调时给足时间让高层语义特征充分调整。5. 常见问题与避坑技巧5.1 训练loss不下降的常见原因我在这个数据集上就遇到过loss一直卡在0.05不往下走的时期。排查下来原因是标注框里面混入了大量空框——也就是标注了类别ID但框坐标全是0的无效标签。这些空框来自一个批量处理脚本的bug坐标列表为空时生成了全零数值。YOLOV5在训练时遇到全零的标签文件并不会报错而是会把标签当作空目标直接跳过。但如果这个txt文件里第一行是全零数据模型会尝试学习一个中心点坐标在左上角、宽度高度为0的框轻则干扰训练重则loss不收敛。排查方法是写一个脚本统计所有标签中宽度或高度为0的样本一条命令揪出来。find /data/xray_dataset/labels -name *.txt -exec awk {if ($40 || $50) print FILENAME, $0} {} \;第二类常见的loss不收敛原因是类别ID越界。比如data.yaml中nc设置为10但某个txt文件中出现了类别ID为10、11的记录训练时会直接报index out of range。这个错误日志会比较明确按图索骥即可。还有一个不太容易想到的原因图像文件名和标签文件名大小写不一致。Linux系统对文件名大小写敏感如果图片是image_001.JPG而标签是image_001.txtYOLOV5在找对应标签时会找不到这条样本就变成纯背景图参与训练无端增加负样本比例。5.2 小目标与重叠目标的调优思路X光安检场景里打火机通常只有几十个像素、钥匙串上的单个钥匙、以及多层叠放的物品后面露出的一角都是典型的小目标和重叠目标问题。针对小目标我做了三件事效果比较明显。第一把训练输入尺寸从640提高到960甚至1280这是收益最大的一步。第二把anchors重新聚类YOLOV5默认的anchors是根据COCO数据集生成的对X光图像不是最优。用train脚本自带的autoanchor功能会自动根据标签分布重新计算anchors我在训练时保留了这个功能默认开启实测对小目标AP有约2-3个百分点的提升。第三单独对小目标样本进行过采样。写了个脚本把所有包含至少一个面积占图像不足1%的目标框采样出来在每轮epoch中额外重复喂给训练器几次。这个操作在数据量不够大的时候非常有效。我的做法是把小目标样本复制了一份放到训练目录中同时对应修改标签文件相当于从数据层面提高了小目标的权重。重叠目标的处理思路略有不同。YOLOV5默认的NMS在重叠框大于0.45时会抑制其中一个这在X光重叠场景里会丢掉大量正确框。我把推理时的NMS的IOU阈值从默认的0.45调低到0.3实测召回率有提升。还有一个参数值得一提obj_loss_gain目标损失权重默认值是1.0我把这个权重提升到1.5后模型对漏检的惩罚变大直观感觉就是更愿意去检测了代价是有可能会多出一些假阳性。5.3 类别不平衡时的处理策略这个数据集中手机和充电宝的样本量可能占到了总量的一半刀具和打火机每个类别可能只有几百个样本。这种不均衡在安检场景中非常典型因为违禁品天然是少数派。我实验过几类常用方法效果如下方法mAP50主要类别违禁品类mAP50不处理直接训练基线0.800.55对少数类做随机过采样0.790.63使用Focal Loss0.780.60过采样 类别权重调整0.780.67综合来看最简单有效的还是过采样。在数据层面把少数类样本复制3-5倍后训练集规模变大模型不再忽视它们。Focal Loss虽然从损失函数层面解决了难易样本不均衡但调参比较敏感alpha和gamma需要反复试对项目周期不友好。直接过采样是零额外调参成本的选择。还有一个很实用的小技巧对少数类做简单的水平翻转、小角度旋转、轻微模糊增强。这个增强不仅让模型看到更多变体而且由于X光图像中物品的纹理和材质特征在不同角度下差异极大人为创造更多角度观察样本能明显提升模型对违禁品这类罕见但在实际场景中形态多变的物体的泛化能力。6. 从数据到部署的余下环节数据集的迭代基本跑通之后训练模型只是第一步。在安检场景实际部署时还有一个容易忽视的问题推理速度与检测率之间的平衡是需要和业务方对齐的。X光安检图像通常是视频流形式每秒钟通过几百张图像实际落地中不可能每张图都用1280尺寸跑我们要用多尺度推理策略先用640尺寸快速做一次初筛对置信度较高的区域再裁剪放大到1280做二次确认或者对连续多帧的结果做时序融合来兼顾速度与精度。另外我把所有标签文件都放在公开目录配合一个简单的可视化脚本用随机颜色把检测框画在图像上可以快速核查每一张图的标注质量。这个步骤听起来基础但在数据量超过一万张以后不要相信任何人已经标注好的说辞实际抽查半小时就能发现一批需要返工的问题框这些问题在训练阶段可能只是几个百分点的精度差距在部署阶段就是误检漏检的事故。最后再分享一个我自己的习惯新建数据集时先对随机20张图片做一次完整的标注到训练到推理的闭环确认流程通畅后再批量扩充数据。这个动作每次都能帮我提前发现目录格式、配置文件、类别ID对应关系之类的问题。等到9000张图全部标注完再统一调试返工成本就太大了。你自己的项目如果也是从零做数据集一定不要跳过这一步。本文还有配套的精品资源点击获取