新闻详情

新闻详情

首页 / 资讯中心 / 详情

安检X光危险品检测数据集:9551张12类YOLO训练实战

发布时间:2026/9/28 16:42:23来源:尧图网络
安检X光危险品检测数据集:9551张12类YOLO训练实战
简介这份安检X光危险物品识别数据集面向安检图像算法开发者、目标检测学习者与安防科研人员用于训练和验证X光场景下的违禁品检测模型解决危险物品自动识别中样本不足、类别覆盖有限的问题。资源采用Pascal VOC与YOLO双格式标注包含9551张jpg图片及一一对应的xml与txt标注文件共12个类别涵盖罐头、玻璃瓶、塑料瓶、喷雾罐、瑞士军刀、刀片、匕首、刀、剪刀等常见安检目标可直接接入YOLO系列或VOC流程训练。压缩包约350.67MB内含2000个文件以1999个xml标注文件和1个使用说明txt为主标注信息完整便于快速构建训练与评估流程。目前已有852人学习下载适合需要扩充安检违禁品数据、验证检测算法效果或开展课程实践的用户参考使用。1. 安检场景下的 9551 张 X 光危险品数据集12 类目标检测到底能落地到什么程度安检机每天吐出的 X 光图像里刀具、喷雾罐、玻璃瓶混在行李重叠区域靠人眼盯屏幕漏检率一直下不来。这份「安检 X 光危险物品识别检测数据集」给的就是 9551 张真实安检视角的 jpg 图片每张都配了 Pascal VOC 的 xml 和 YOLO 的 txt 双格式标注覆盖 12 个类别Cans、CartonDrinks、GlassBottle、PlasticBottle、SprayCans、SwissArmyKnife、Tin、VacuumCup、blade、dagger、knife、scissors。它解决的不是「有没有数据」的问题而是「能不能直接喂给 YOLO 系列训练、省掉自己标注几千张 X 光图」的问题。适合做安检智能判图、危险品检测课题、YOLOv5/v8 迁移学习验证的从业者和学生。下面按「这份资源是什么 → 怎么跑起来 → 坑在哪 → 怎么用得更狠」的顺序拆开讲。2. 双格式标注怎么选VOC 与 YOLO 的目录结构和转换逻辑拿到压缩包先别急着解压训练得先搞清楚 VOC 和 YOLO 两套标注在同一批图片上是怎么共存的。这份数据集的特点是「一图三文件」一张 jpg对应一个同名 xmlVOC和一个同名 txtYOLO没有分割路径的 txt也没有 ImageSets 目录。这意味着它省掉了 VOC 标准里那套 Main/train.txt 的划分文件你得自己切分训练集和验证集。2.1 VOC xml 的字段含义与坐标读取VOC 格式的坐标是绝对像素值原点在左上角xmin/ymin/xmax/ymax直接对应图片像素。用 Python 读一个 xml 看结构import xml.etree.ElementTree as ET tree ET.parse(firc_xray_3342.xml) root tree.getroot() # 图片尺寸归一化时要用 size root.find(size) w int(size.find(width).text) h int(size.find(height).text) print(size:, w, h) for obj in root.findall(object): name obj.find(name).text # 类别名如 knife bbox obj.find(bndbox) xmin int(bbox.find(xmin).text) ymin int(bbox.find(ymin).text) xmax int(bbox.find(xmax).text) ymax int(bbox.find(ymax).text) print(name, xmin, ymin, xmax, ymax)逻辑说明size节点给出宽高是后面归一化的分母object节点每个代表一个标注框name就是 12 类里的字符串。参数上要注意有些 VOC 文件里xmax可能等于图片宽度归一化后是 1.0YOLO 训练时一般要求坐标严格小于 1遇到等于 1 的框要么裁剪要么减一个像素否则部分框架会报越界。2.2 YOLO txt 的归一化坐标与类别索引YOLO 格式每行是class_id x_center y_center width height全部是 0~1 的相对值。类别索引取决于你训练时 data.yaml 里 names 的顺序这份数据集给的 txt 已经按固定顺序编好了号常见顺序就是摘要里那 12 个类名的排列。读一个 txtwith open(firc_xray_3342.txt) as f: for line in f: c, x, y, w, h line.split() # 反归一化回像素方便和 xml 对照校验 print(int(c), float(x), float(y), float(w), float(h))逻辑说明c是类别索引x/y/w/h是归一化值。参数上x_center和y_center是框中心点不是左上角这点和 VOC 的xmin/ymin完全不同做格式互转时最容易在这里翻车。校验方法很简单把 txt 反归一化后和 xml 的像素框对比中心点应该一致宽高应该一致。2.3 两套格式的取舍与目录组织实际训练时我一般只保留 YOLO 的 txt因为 YOLOv5/v8 原生吃 txtVOC 的 xml 留作备份和交叉校验。目录按下面这样组织最省事dataset/ ├── images/ │ ├── train/ # 约 7640 张 │ └── val/ # 约 1911 张 ├── labels/ │ ├── train/ │ └── val/ └── data.yaml划分比例常见做法是 8:2用脚本按文件名随机切保证同名 jpg 和 txt 进同一个子集。注意别用shutil.move直接搬原文件先复制一份原始 9551 张留着当后悔药标注清洗时还要回头查。3. 从零跑通 YOLOv8 训练data.yaml、类别映射与首轮验证数据组织好之后真正决定能不能跑起来的是 data.yaml 和类别顺序。这份数据集 12 类里有几个容易混淆的knife、dagger、blade、SwissArmyKnife都是刀类Cans和Tin都是罐类类别顺序一旦和 txt 里的索引对不上训练 loss 会正常下降但 mAP 一塌糊涂属于典型的「玄学」故障。3.1 写对 data.yaml 的类别顺序path: /data/xray_dataset train: images/train val: images/val nc: 12 names: 0: Cans 1: CartonDrinks 2: GlassBottle 3: PlasticBottle 4: SprayCans 5: SwissArmyKnife 6: Tin 7: VacuumCup 8: blade 9: dagger 10: knife 11: scissors逻辑说明nc必须等于 12names的键必须从 0 连续到 11顺序要和 txt 里的 class_id 严格一致。参数上path写数据集根目录train/val写相对路径。验证顺序对不对有个笨办法随便挑一张图用labelimg或labelme打开对应 txt看框上的类别名和图片内容是否吻合比如玻璃瓶的框不该标成 PlasticBottle。3.2 启动训练与关键超参yolo detect train \ data/data/xray_dataset/data.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ projectruns/xray \ nameexp1逻辑说明model用预训练权重做迁移X 光图像和自然图像分布差异大但底层边缘纹理特征仍可复用比从头训收敛快。imgsz640是 YOLOv8 默认安检图里小目标blade、scissors多如果显存够可以上 960 或 1280小目标召回会明显改善。batch16按显存调V100 上 640 分辨率跑 yolov8s 可以到 32。patience20是早停X 光数据容易过拟合别设太大。3.3 首轮验证看什么指标训练完先别急着导出模型看runs/xray/exp1/下的混淆矩阵和 PR 曲线。重点看三件事一是knife/dagger/blade三类之间有没有大量互相误判这是类别定义重叠导致的二是GlassBottle和PlasticBottle在 X 光下颜色接近看混淆矩阵里这两类的对角线是否干净三是小目标类别的 recall如果scissors召回低于 0.5说明分辨率不够或 anchor 不匹配下一轮调imgsz。提示首次训练建议先用 500 张子集跑 10 个 epoch确认 data.yaml 和标注没问题再上全量全量跑一轮几小时方向错了重来成本高。4. 标注清洗与类别不平衡12 类里哪些坑必须先填9551 张、12 类平均每类不到 800 个框但实际分布肯定不均。刀类可能几千个VacuumCup、CartonDrinks这种可能只有几百个。直接开训少数类基本学不动。这一章讲怎么在训练前把标注和分布问题处理掉。4.1 统计类别分布与框尺寸import os, glob from collections import Counter cnt Counter() sizes [] for txt in glob.glob(labels/train/*.txt): with open(txt) as f: for line in f: c, x, y, w, h line.split() cnt[int(c)] 1 sizes.append((float(w), float(h))) for k in sorted(cnt): print(k, cnt[k])逻辑说明这段脚本统计每个类别的框数量sizes收集归一化宽高用于分析小目标占比。参数上如果某类框数低于 300基本要单独做增强或过采样。框宽高小于 0.05 的属于小目标X 光里的 blade、scissors 经常落在这个区间训练时imgsz要相应放大。4.2 针对少数类的增强策略YOLOv8 内置的mosaic、mixup、copy_paste对小目标有帮助但 X 光图像有特殊性颜色是伪彩翻转和旋转物理上合理但色调抖动hsv_h要谨慎因为颜色本身携带材质信息。我一般这样配# 在 train 参数里追加 hsv_h: 0.0 # X 光伪彩不做色调抖动 hsv_s: 0.3 hsv_v: 0.3 degrees: 10.0 # 小角度旋转模拟行李摆放 translate: 0.1 scale: 0.5 mosaic: 1.0 copy_paste: 0.3 # 对少数类做粘贴增强逻辑说明hsv_h0是关键X 光颜色对应材质密度抖动会破坏语义。copy_paste把少数类目标抠出来贴到其他图上对VacuumCup这类稀缺类别提升明显。参数上degrees别超过 15安检视角基本水平大角度旋转不符合真实分布。4.3 标注错误的三种典型形态清洗时重点查三类问题一是框超出图片边界VOC 里xmax大于 width转 YOLO 后归一化值大于 1二是空 txt图片有目标但标注文件是空的三是类别名拼写不一致比如SwissArmyKnife写成SwissArmyKnif。用下面脚本批量扫import glob, os from PIL import Image for txt in glob.glob(labels/**/*.txt, recursiveTrue): img_path txt.replace(labels, images).replace(.txt, .jpg) if not os.path.exists(img_path): print(缺图:, txt); continue w, h Image.open(img_path).size with open(txt) as f: lines f.readlines() if not lines: print(空标注:, txt) for line in lines: c, x, y, bw, bh map(float, line.split()) if not (0 x 1 and 0 y 1 and 0 bw 1 and 0 bh 1): print(越界:, txt, line.strip())逻辑说明先检查图片是否存在再检查空标注最后检查归一化值范围。参数上bw/bh等于 0 也要报出来那是无效框。跑完把问题文件列出来人工过一遍别直接删有些是标注规范差异不是错误。5. 训练排查清单loss 不降、mAP 卡住、显存爆的五个真实翻车现场这一章是血泪经验合集都是我在 X 光数据集上实际踩过的。每条按「现象 → 原因 → 解决」写照着排查能省不少时间。5.1 现象loss 正常下降但 mAP 始终在 0.01 附近原因类别索引和 data.yaml 的 names 顺序错位模型学的是「第 0 类」但你的第 0 类实际是别的目标评估时全判错。X 光数据集类别多txt 里的编号如果和 yaml 不一致表现就是 loss 降但指标不动。解决抽 10 张图用脚本把 txt 的 class_id 映射回类名和图片内容人工核对。确认顺序后重训。别信「再跑几个 epoch 就好了」顺序错永远好不了。5.2 现象训练到一半 loss 突然变 NaN原因学习率过大或某个 batch 里有异常框宽高为 0 或坐标越界梯度爆炸。X 光数据里偶尔有标注框退化成一条线归一化后宽为 0算 loss 时除零。解决先跑 4.3 的清洗脚本把异常框清掉训练时加lr00.01起步配合cos_lr余弦退火如果还炸开ampFalse排除混合精度问题。V100 上 AMP 一般没问题但异常数据会放大数值不稳定。5.3 现象显存爆batch 降到 4 还 OOM原因imgsz设太大或者 dataloader 的workers开太多导致内存泄漏。X 光图分辨率如果原始是 2000resize 到 1280 后单张显存占用翻倍。解决先imgsz640跑通再逐步往上加workers设成 CPU 核数的 1/4别拉满开cacheFalseX 光数据集 9551 张全缓存进内存要几十 G。显存实在紧就上梯度累积nbs64模拟大 batch。5.4 现象验证集 mAP 比训练集低一大截原因训练集和验证集分布不一致随机切分时某些类别只在训练集出现。12 类里少数类样本少随机切容易切偏。解决改用分层切分按类别分层抽样保证每个子集里 12 类都有。或者用sklearn.model_selection.train_test_split的stratify参数以每张图的主类别为分层依据。5.5 现象推理时同一张图多次预测结果不一致原因模型没切到 eval 模式BN 层还在用 batch 统计量或者推理时做了随机增强。X 光图如果推理管线里带了 mosaic结果每次都不一样。解决导出模型时用model.eval()推理走yolo detect predict默认就是 eval检查推理配置里augmentFalse。这个坑在部署阶段特别隐蔽离线测试好好的上线就飘。6. 进阶玩法用这份数据做小目标切片推理与类别合并实验基础训练跑通之后这份数据集还能压榨出更多价值。X 光安检的核心难点是小目标blade、scissors和类别边界模糊knife/dagger/blade下面两个方向是我实测有效的。6.1 小目标切片推理SAHI 思路640 分辨率下blade 这种目标可能只占 20×20 像素特征太弱。常见做法是把原图切成重叠子图分别推理再合并类似 SAHI 的思路。不依赖额外库手写一个简化版import cv2 from ultralytics import YOLO model YOLO(runs/xray/exp1/weights/best.pt) img cv2.imread(test.jpg) H, W img.shape[:2] tile, overlap 640, 128 step tile - overlap boxes [] for y in range(0, H, step): for x in range(0, W, step): patch img[y:ytile, x:xtile] if patch.shape[0] 32 or patch.shape[1] 32: continue res model.predict(patch, conf0.25, verboseFalse)[0] for b in res.boxes: x1, y1, x2, y2 b.xyxy[0].tolist() boxes.append([x1x, y1y, x2x, y2y, float(b.conf), int(b.cls)]) # 用 NMS 合并跨切片的重复框 import torch from torchvision.ops import nms if boxes: t torch.tensor(boxes) keep nms(t[:, :4], t[:, 4], 0.5) print(t[keep])逻辑说明tile640是切片大小overlap128保证目标不被切断。每个切片单独推理后把坐标加回原图偏移最后用 NMS 去重。参数上conf0.25可以调低到 0.15 提高小目标召回代价是误检增多靠 NMS 的 IoU 阈值平衡。这套在 blade 类上召回能提升 10 个点以上。6.2 类别合并实验把 12 类压成 4 类knife、dagger、blade、SwissArmyKnife在安检业务里往往统一按「刀具」处置Cans、Tin统一按「金属罐」。如果业务只关心「有没有危险品」可以把 12 类合并成 4 大类刀具类、瓶罐类、喷雾类、剪刀类。合并后每类样本量翻几倍mAP 通常能涨 5~8 个点。# 类别合并映射12 - 4 merge_map { 0: 1, 6: 1, # Cans, Tin - 罐类 1: 1, # CartonDrinks - 罐类 2: 0, 3: 0, # GlassBottle, PlasticBottle - 瓶类 4: 2, # SprayCans - 喷雾类 5: 3, 8: 3, 9: 3, 10: 3, # 刀类 7: 1, # VacuumCup - 罐类 11: 3 # scissors - 刀类按业务可调 } import glob for txt in glob.glob(labels/**/*.txt, recursiveTrue): out [] with open(txt) as f: for line in f: c, x, y, w, h line.split() out.append(f{merge_map[int(c)]} {x} {y} {w} {h}\n) with open(txt, w) as f: f.writelines(out)逻辑说明merge_map把 12 个索引映射到 4 个新索引重写 txt。参数上映射关系按业务定比如scissors归刀类还是单独一类看安检处置流程。合并后 data.yaml 的nc改成 4names 对应改。注意这个操作会覆盖原 txt先备份。6.3 验证合并效果与部署取舍合并后重训一轮对比混淆矩阵原来 knife/dagger 之间的误判会消失因为变成同一类但瓶类和罐类之间可能新增混淆因为合并放大了类内差异。部署时如果业务需要细分刀具类型就不能合并得靠 6.1 的切片推理提召回。两条路各有取舍我一般先跑合并版看整体 mAP 上限再决定要不要为细分类型单独优化。从那以后我每次拿到新数据集都强制先跑一遍类别分布统计和标注越界扫描再动训练脚本。这份 9551 张的 X 光数据底子不错双格式标注省了大量清洗时间12 类的划分也贴合安检实际场景值得拿来当危险品检测的基线。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

CLI-Anything:Agent与命令行融合的实操指南与避坑手册 2026/9/28 17:26:09

CLI-Anything:Agent与命令行融合的实操指南与避坑手册

1. 从"CLI-Anything"说起:命令行工具正在经历一场静默革命第一次看到"CLI-Anything"这个说法,我脑子里蹦出来的不是某个具体工具,而是一种趋势判断:命令行界面正在从"人敲命令"变成"人和智能体…

阅读更多 →
FPGA驱动Si570时钟配置实战:I2C通信与AXI IP核避坑指南 2026/9/28 17:26:02

FPGA驱动Si570时钟配置实战:I2C通信与AXI IP核避坑指南

1. 为什么Si570的I2C配置让FPGA新手频频翻车Si570这颗芯片在FPGA圈子里出镜率极高,尤其是做高速收发器、SerDes参考时钟或者需要动态可编程时钟的板卡上,几乎绕不开它。但很多新手第一次用Xilinx FPGA通过AXI I2C去配置Si570时,往往会卡在几个…

阅读更多 →
AI Agent开发实战:从0到1搭建企业级智能体与行业洗牌 2026/9/28 17:25:49

AI Agent开发实战:从0到1搭建企业级智能体与行业洗牌

1. 暴利与绝路并存:AI Agent到底在洗谁的牌先说结论:AI Agent不是又一个聊天机器人套壳,也不是“升级版Copilot”,它是从“你问我答”到“你给我结果”的范式切换。这个切换带来的不是某条产品线的优化,而是整个软件行…

阅读更多 →
Wasserstein距离分布鲁棒优化调度论文复现与MATLAB实现解析 2026/9/28 17:25:49

Wasserstein距离分布鲁棒优化调度论文复现与MATLAB实现解析

简介:这是基于Wasserstein距离的分布鲁棒优化方法复现程序,对应爱思唯尔论文《能源与备用调度中的分布式鲁棒联合机会约束》的核心模型。程序使用MATLAB、Yalmip和Gurobi实现求解,面向电力系统调度与分布鲁棒优化方向的研究者,可作…

阅读更多 →
免公众号网页注册版H5爆点源码搭建教程与二开指南 2026/9/28 17:25:49

免公众号网页注册版H5爆点源码搭建教程与二开指南

简介:这份资源是二开H5爆点免公众号网页注册版的全套源码,面向需要搭建H5推广注册页的站长、运营者与二次开发者,核心解决没有公众号、租用公众号成本高以及自建公众号易被封号的问题。压缩包共2001个文件,约176.3MB,以…

阅读更多 →
不赌最强模型:打造可随时切换模型的AI工作流设计指南 2026/9/28 17:25:49

不赌最强模型:打造可随时切换模型的AI工作流设计指南

1. “最强”焦虑是咋来的:为什么押注模型会让人反复返工做AI落地的人,应该都经历过那个阶段:每天盯着各种榜单和开源仓库,哪个模型分高就切哪个,生怕自己“用错了模型”。我早几年也是这么干的,GPT系列出来…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉