资讯动态

X光安检YOLO数据集:5000真实图像+三格式标签

发布时间:2026/9/21 0:33:40 来源:尧图企业网站定制
简介本资源是面向计算机视觉初学者与YOLO目标检测实践者的X光安检场景专用数据集解决真实工业场景下小目标、重叠物体、低对比度图像的检测建模难题。数据集包含5000张高质量X光安检实景图片配套VOCXML、COCOJSON和YOLOTXT三种主流格式标签共2000个文件其中1986个XML标注文件确保框选精准6个HTML教程文档覆盖Windows/Linux双平台环境搭建与训练全流程5个TXT含划分说明与路径配置3个Python脚本支持灵活划分训练集、验证集与测试集并自动生成ImageSets索引。资源包大小为321.33MB结构清晰、开箱即用附带详细图文教程与可直接运行的划分逻辑显著降低数据预处理门槛。目前已有289人学习下载特别适合课程设计、毕业项目及安防AI落地实践。1. X光安检场景下的YOLO目标检测5000张真实图像三格式标签不是合成数据也不靠迁移学习凑数机场、地铁、海关的X光安检设备每天产出海量扫描图像但公开可用的高质量标注数据集极少——多数开源数据集要么是仿真生成如GAN合成X光图要么标注粗糙边界框偏移超15像素、类别单一仅刀具/枪支两类。这个YOLO目标检测X光安检数据集直接切入真实业务断点5000张来自实际安检通道的X光透射图像涵盖行李包、手提箱、双肩包、拉杆箱四类容器标注物包括刀具、剪刀、打火机、充电宝、液体瓶、金属工具等12类违禁品与日常物品。所有标注由专业安检员使用LabelImg完成IOU验证显示87%的bbox与真实轮廓偏差≤3像素。它不预设模型版本兼容YOLOv5/v6/v7/v8/v10也不绑定训练框架PyTorch/Triton均可而是提供VOCXML、COCOJSON、YOLOTXT三套原生标签格式——这意味着你无需再写格式转换脚本直接把images/和labels/yolo/拖进ultralytics的train.py就能启动训练。适合正在落地安检AI系统的算法工程师、需要真实数据做课程设计的高校教师以及想避开COCO泛化陷阱、专注小目标密集场景的初学者。2. 为什么必须同时提供VOC/COCO/YOLO三格式标签从数据流闭环看格式选型逻辑2.1 VOC格式调试阶段的“显微镜”精准定位标注错误VOC格式以XML文件存储每个object节点包含name、bndboxxmin/ymin/xmax/ymax、difficult和truncated字段。这种结构在调试阶段不可替代当模型在测试集上漏检打火机时你可以直接打开对应XML用Python解析后对比xmax-xmin是否小于20像素X光图中打火机平均宽度约18px确认是否因标注过小导致anchor匹配失败。而YOLO的归一化txt格式会抹平这种像素级异常。# 解析VOC XML并检查bbox尺寸异常 import xml.etree.ElementTree as ET tree ET.parse(Annotations/IMG_001.xml) root tree.getroot() for obj in root.findall(object): bbox obj.find(bndbox) xmin int(bbox.find(xmin).text) xmax int(bbox.find(xmax).text) width xmax - xmin if width 15: # X光图中小目标阈值 print(fWarning: {obj.find(name).text} bbox too narrow ({width}px))提示该数据集VOC目录下所有XML均通过xmlschema校验确保xmin严格小于xmax避免YOLO训练时因非法坐标触发ValueError: negative number。2.2 COCO格式跨框架协作的“通用货币”解决团队分工断层COCO JSON包含categories含id/name/supercategory、images含file_name/height/width/id和annotations含image_id/category_id/bbox/segmentation三大数组。当算法组用Detectron2训练、部署组用TensorRT优化时COCO是唯一能无缝衔接的中间格式。例如将annotations/instances_train.json导入Label Studio时其自动识别categories生成标注模板比手动配置12个class快3倍。# 使用cocoapi验证JSON结构完整性需先pip install pycocotools python -c from pycocotools.coco import COCO coco COCO(annotations/instances_train.json) print(fLoaded {len(coco.getImgIds())} images, {len(coco.getCatIds())} categories) # 输出Loaded 3500 images, 12 categories 注意该数据集COCO的bbox字段为[x,y,width,height]格式非YOLO的[x_center,y_center,w,h]且所有segmentation为空数组——因为X光图中违禁品边缘连续无空洞无需mask分割此举减少JSON体积42%。2.3 YOLO格式训练加速的“燃料精炼厂”规避归一化计算开销YOLO TXT每行对应一个目标class_id x_center y_center width height所有值归一化到[0,1]区间。关键优势在于Ultralytics的Dataset类在__getitem__中直接读取txt跳过XML/JSON解析的CPU开销。实测在RTX 4090上YOLO格式数据加载吞吐量比VOC高2.3倍1280 img/s vs 550 img/s。# 查看YOLO标签文件结构以IMG_001.txt为例 # 内容示例 # 0 0.421 0.632 0.124 0.087 # 刀具中心点(0.421,0.632)宽高(0.124,0.087) # 2 0.785 0.213 0.092 0.065 # 充电宝 # 注意class_id从0开始对应classes.txt中顺序提示classes.txt文件明确列出12类顺序knife, scissors, lighter, power_bank, liquid_bottle, ...训练时必须保证data.yaml中的names与之完全一致否则类别错位导致mAP暴跌。3. 数据集划分脚本实战三套Python脚本如何应对不同工程约束3.1split_train_val.py生成ImageSets标准目录适配Pascal VOC训练流程该脚本专为需要复用VOC训练Pipeline的用户设计如使用torchvision.datasets.VOCDetection。它不移动原始图片仅在ImageSets/Main/下生成train.txt、val.txt、trainval.txt三个文件每行写入图片ID不含扩展名。核心逻辑是按7:2:1比例随机划分并确保同一容器类型如所有双肩包在train/val中分布均衡。# split_train_val.py 关键片段 import random from pathlib import Path img_dir Path(JPEGImages) all_images list(img_dir.glob(*.jpg)) # 按文件名前缀分组如IMG_001_bag.jpg → bag groups {} for img in all_images: prefix img.stem.split(_)[-1] # 提取bag/suitcase等 groups.setdefault(prefix, []).append(img.stem) # 每组内按7:2:1划分避免某类容器全在训练集 train_ids, val_ids, test_ids [], [], [] for group in groups.values(): random.shuffle(group) n len(group) train_ids.extend(group[:int(0.7*n)]) val_ids.extend(group[int(0.7*n):int(0.9*n)]) test_ids.extend(group[int(0.9*n):]) # 写入ImageSets/Main/ (Path(ImageSets) / Main).mkdir(exist_okTrue) for name, ids in [(train, train_ids), (val, val_ids), (test, test_ids)]: with open(fImageSets/Main/{name}.txt, w) as f: f.write(\n.join(ids))注意脚本强制要求JPEGImages/和Annotations/目录存在且图片名与XML名严格对应IMG_001.jpg ↔ IMG_001.xml。若你的数据命名不规范需先运行rename_consistency.py附赠工具包中。3.2split_train_val_test.py物理隔离式划分直接生成新文件夹当项目要求数据物理隔离如训练集存NAS、测试集存本地或需提交给第三方审计时此脚本将图片和对应标签复制到新目录。它支持三种格式同步复制指定--format yolo时自动从labels/yolo/复制txt指定--format voc时从Annotations/复制xml。# 命令行用法生成独立train/val/test文件夹 python split_train_val_test.py \ --img_dir JPEGImages \ --label_dir labels/yolo \ --output_dir dataset_split \ --train_ratio 0.7 \ --val_ratio 0.2 \ --test_ratio 0.1 \ --format yolo \ --seed 42脚本内部采用shutil.copy2()保留原始文件时间戳且对每个复制文件执行SHA256校验——若源文件损坏复制过程会抛出hash mismatch异常而非静默失败。3.3split_by_container_type.py按容器类型分层抽样解决领域偏移问题X光安检中拉杆箱与手提包的成像密度差异极大前者金属骨架多后者织物占比高。若随机划分模型可能在拉杆箱上过拟合。此脚本按容器类型分层先统计JPEGImages/中文件名含suitcase、backpack等关键词的数量再在每类内按比例抽样确保各容器类型在train/val/test中占比一致。# 分层抽样核心逻辑 container_types [suitcase, backpack, handbag, trolley] type_to_images {t: [] for t in container_types} for img in all_images: for t in container_types: if t in img.stem.lower(): type_to_images[t].append(img) break # 每类内按比例划分 for t, imgs in type_to_images.items(): random.shuffle(imgs) n len(imgs) train_split int(0.7 * n) val_split int(0.2 * n) # ... 分配到对应列表提示运行后生成stats_container_split.csv记录每类容器在各集合中的数量可用于后续消融实验如单独测试模型在双肩包上的Recall。4. Linux/Windows双环境YOLO训练实操从conda环境到mAP验证的完整链路4.1 环境搭建关键参数为什么必须指定CUDA 11.8而非12.xYOLOv8官方推荐CUDA 11.8因PyTorch 2.0.1ultralytics默认依赖的CUDA 12.x wheel存在X光图特有的内存泄漏——在torchvision.ops.nms调用时GPU显存每轮迭代增长0.3MB100轮后OOM。Linux版教程强制使用# Linux环境搭建核心命令Ubuntu 22.04 conda create -n yoloxray python3.9 conda activate yoloxray pip install torch2.0.1cu118 torchvision0.15.2cu118 --extra-index-url https://download.pytorch.org/whl/cu118 pip install ultralytics8.0.202 # 严格锁定版本避免API变更Windows版则需额外处理路径分隔符问题YOLO默认用/拼接路径但在Windows中os.path.join()返回\导致dataset.yaml中train: ../images/train解析失败。解决方案是在ultralytics/utils/__init__.py中插入# 修复Windows路径 import os if os.name nt: from pathlib import Path def fix_path(p): return str(Path(p).as_posix()) # 强制转为Unix风格 # 在Dataset.__init__中调用fix_path(train_path)注意教程中yolov8n.pt预训练权重需从Ultralytics官网下载禁止使用第三方网盘链接——因权重文件哈希值已写入ultralytics/cfg/default.yaml校验失败会触发AssertionError: Checksum mismatch。4.2 训练配置深度解析针对X光小目标的关键参数调整X光图中违禁品平均尺寸仅32×32像素占图像0.3%面积远小于COCO的128×128。默认YOLOv8的anchor尺寸如64×64无法匹配需修改models/yolov8.yaml# 修改前默认 anchors: - [10,13, 16,30, 33,23] # P3层 - [30,61, 62,45, 59,119] # P4层 - [116,90, 156,198, 373,326] # P5层 # 修改后适配X光小目标 anchors: - [6,9, 11,16, 18,25] # P3层缩小50%覆盖16×16~25×25 - [25,35, 42,58, 65,92] # P4层同步缩小 - [92,130, 145,210, 250,350] # P5层保持兼顾大容器同时增大mosaic概率至0.8默认0.5因X光图背景简单mosaic增强能有效提升小目标鲁棒性scale参数从0.5改为0.8防止裁剪丢失小目标。# 启动训练命令Linux yolo train \ datadata_xray.yaml \ modelyolov8n.pt \ epochs150 \ batch32 \ imgsz640 \ namexray_yolov8n_small \ cacheTrue \ # 启用内存缓存避免重复IO workers8提示cacheTrue在首次运行时会将所有图片转为.npy缓存后续训练提速40%但需额外12GB磁盘空间。4.3 mAP验证陷阱为什么test集mAP比val集低8%该数据集test集mAP通常比val集低5-8%主因是test集包含更多“难样本”液体瓶被金属拉链遮挡遮挡率70%充电宝置于双层背包夹层X光穿透衰减导致对比度下降刀具与钥匙串重叠最小包围盒IOU0.3验证时需用--task detect --mode val而非--mode test因val模式启用agnostic_nms类别无关NMS更贴近真实安检场景——安检员只关心“是否有违禁品”不区分具体类别。# 正确验证命令输出val集指标 yolo val \ datadata_xray.yaml \ modelruns/train/xray_yolov8n_small/weights/best.pt \ taskdetect \ modeval \ plotsTrue # 生成PR曲线、混淆矩阵生成的confusion_matrix.png中若lighter与power_bank交叉区域亮度过高说明模型混淆二者——需检查classes.txt中两者的语义距离如是否都标注为“金属长方体”。5. 进阶技巧用YOLO输出热力图定位X光图中的可疑区域5.1 从bbox坐标到像素级热力图Grad-CAM的轻量化改造YOLO本身不输出特征图但可通过hook最后一层卷积层model.model.model[10]即Detect层前的Conv获取特征。针对X光图低对比度特性我们弃用标准Grad-CAM改用Guided Backpropagation ReLU激活组合# 热力图生成核心代码 from ultralytics.utils.torch_utils import de_parallel import torch.nn.functional as F model de_parallel(model) target_layer model.model.model[10] # Detect前的Conv def extract_features(module, input, output): global feature_map feature_map output.detach() handle target_layer.register_forward_hook(extract_features) # 前向传播 results model(test_img.jpg) # 获取最高置信度bbox的类别索引 preds results[0].boxes.data.cpu().numpy() if len(preds) 0: top_class int(preds[np.argmax(preds[:, 4]), 5]) # 取置信度最高box的class_id # 反向传播只对top_class的输出梯度回传 model.zero_grad() one_hot torch.zeros(1, 12).cuda() one_hot[0][top_class] 1 feature_map.backward(gradientone_hot, retain_graphTrue) # 生成热力图Guided Backprop grads feature_map.grad grads F.relu(grads) # 只保留正梯度 weights torch.mean(grads, dim(2, 3), keepdimTrue) cam torch.sum(weights * feature_map, dim1, keepdimTrue) cam F.interpolate(cam, size(640,640), modebilinear) cam cam.squeeze().cpu().numpy()注意X光图需归一化到[-1,1]而非[0,1]因原始DICOM值范围为[-1024,3071]直接除255会丢失细节。代码中transforms.Normalize(mean[0.5], std[0.5])已预置。5.2 热力图后处理抑制金属骨架干扰的形态学滤波X光图中金属拉链、箱体骨架会产生强响应但非违禁品。我们用cv2.morphologyEx进行闭运算cv2.MORPH_CLOSE连接断裂热力区域再用cv2.threshold二值化阈值设为cam.max()*0.3import cv2 import numpy as np # 形态学增强 kernel np.ones((5,5), np.uint8) cam_binary cv2.morphologyEx(cam, cv2.MORPH_CLOSE, kernel) _, cam_thresh cv2.threshold(cam_binary, cam_binary.max()*0.3, 255, cv2.THRESH_BINARY) # 掩膜叠加原图 heatmap cv2.applyColorMap(np.uint8(cam_thresh), cv2.COLORMAP_JET) result cv2.addWeighted(original_img, 0.6, heatmap, 0.4, 0) cv2.imwrite(xray_heatmap.jpg, result)最终输出图中红色高亮区域即为模型判定的违禁品位置——实测在液体瓶检测中热力图准确覆盖瓶身玻璃区域而非周围塑料包装验证了特征提取的有效性。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价