首页 / 资讯中心 / 文章详情

条形码目标检测数据集实战:从YOLOv8训练到部署

条形码目标检测数据集实战:从YOLOv8训练到部署 ★ FEATURED ARTICLE
简介这是一份面向目标检测与计算机视觉学习者的条形码识别数据集涵盖零售、物流、制造等场景下的真实商品条码图像适合用于训练YOLO系列模型或开展算法实验。数据集共684张图片按训练集624张、验证集60张划分采用YOLO格式标注边界框与类别标签齐备可直接接入主流深度学习框架使用能有效降低数据预处理成本。压缩包内包含1434个文件其中716张jpg图像与716个对应txt标注文件一一匹配另附1个yaml配置文件用于定义模型训练参数以及1个docx格式的数据集说明文档方便快速了解数据组织方式。整个资源包约79.72MB文件结构简洁适合直接下载运行。目前已有169人浏览学习适合正在构建商品识别系统、研究目标检测算法的开发者也适用于高校相关课程实验与毕业设计。借助该数据集读者可以快速完成条形码检测模型的训练与验证并在此基础上优化检测精度提升实际场景中的识别效率。1. 条形码目标检测数据集别在扫码枪上浪费钱了快递分拣线、仓储盘点、超市自助结算这些场景里最大的瓶颈不是算法而是数据。工业相机拍出来的条码图片要么背景乱、要么反光、要么是斜着贴在曲面上的OpenCV 的 pyzbar 在干净图片上很神一到现场就翻车。你需要的不是“读码器”而是一个能定位条码区域的检测模型——这就是条形码目标检测数据集要解决的问题。它是把条码图片和标注文件打包好的 zip 压缩包让 YOLOv8、RT-DETR 这类目标检测模型直接拿去训练学会在复杂背景里把条码“框”出来。适合正在做仓储自动化、快递扫码、或想自己训练条码检测器的开发者。入手这份数据集之前先把里面的东西看懂否则训出来的模型上线必翻车。2. 解开 zip 看家底条形码数据集的目录结构、标注格式与类别约定2.1 zip 解压后先看什么VOC/COCO/YOLO 三种格式的判别方法拿到“条形码目标检测数据集.zip”别急着开训先看目录结构。数据集通常打包成三种格式之一VOCxml 文件存标注、COCOjson 文件存标注、YOLOtxt 文件存标注。判断方法很简单——打开解压后的文件夹看两个东西图片后缀和标注文件后缀。最常见的布局是images/和labels/两个平级目录图片和标注文件同名、不同后缀。如果看到Annotations/里有大量.xml那是 VOC 格式如果看到annotations/instances_train.json那就是 COCO 格式如果看到labels/train/下一堆.txt那就是 YOLO 格式直接能被 ultralytics 读取。用命令快速统计一下文件数心里先有个底# 解压并查看目录结构 unzip barcode_detection_dataset.zip -d barcode_ds cd barcode_ds # 统计图片数量和标注数量 ls images/ | wc -l ls labels/ | wc -l # 查看一张标注文件的内容YOLO 格式的话应该是5列数字 cat labels/train/000001.txt输出类似0 0.5234 0.4821 0.1124 0.0512含义是类别 0中心点 x、y 坐标归一化框宽高归一化。看到这个格式说明数据集已经帮你转换好了可以直接训练。如果看到的是 xml 或 json你需要先用脚本转换后面我给了现成的。参数说明上面命令里wc -l统计的是行数一个标注框对应一行。类别序号从 0 开始如果你的数据集里既有条形码又有二维码通常 0 代表一维码、1 代表二维码。先确认类别声明文件通常是data.yaml或classes.txt别把类别对应关系搞错。2.2 条形码数据集该有的样子样本分布、分辨率与标注字段条形码数据集和通用目标检测数据集不一样。通用数据集里物体占了图片的很大区域而条码往往是细长条宽高比极端有的甚至占不到图片面积的 2%。这就导致两个硬指标你需要格外关注。第一个是图像分辨率。真实场景下条码在 640×640 的输入图片里可能只有 20×60 像素检测难度极大。看一眼数据集的图片长宽如果 min(width, height) 小于 400 且条码占面积很大这个数据集的价值就低如果图片是 1280×960 级别、条码是小目标那这个数据集的质量就比较高训练时要配合大输入尺寸。第二个是标注框的宽高比分布。条码的宽高比普遍在 2:1 到 10:1 之间二维码则接近 1:1。如果数据集的标注框里混进了一些方方正正的框有可能把二维码也标进去了。用一段简单 Python 统计宽高比分布import os import numpy as np label_dir barcode_ds/labels/train ratios [] for fname in os.listdir(label_dir): with open(os.path.join(label_dir, fname)) as f: for line in f: parts line.strip().split() w float(parts[3]) h float(parts[4]) ratios.append(w / max(h, 1e-6)) ratios np.array(ratios) print(f样本数: {len(ratios)}) print(f宽高比中位数: {np.median(ratios):.2f}) print(f宽高比 P90: {np.percentile(ratios, 90):.2f})参数说明归一化坐标下 w、h 不需要乘图片尺寸直接算比值。中位数如果小于 1说明你的数据里竖直条码扫码枪竖着扫的那种偏多如果大部分在 2~8 范围说明横躺的条码为主。训练时注意数据增强里的随机旋转旋转 90 度会让竖条条码角度分布均匀否则模型会对朝向敏感。2.3 统一成 YOLO 格式目录重建与标注转换脚本如果你的 zip 里是 VOC 或 COCO 格式不想丢掉这批数据的话写个脚本统一转成 YOLO 格式是必须的一步。这里给出一个把 VOC 的 xml 标注转成 YOLO txt 的脚本我一般会加一段“跳过空标注”的逻辑避免某些图片没有任何条码时产生空的 txt——空标注文件会让训练报错这是常见的坑。import os import xml.etree.ElementTree as ET def voc_to_yolo(xml_path, out_path, img_w, img_h, classes): 将VOC格式的xml标注转为YOLO格式的txt classes: [barcode, qrcode]按数据集实际类别顺序写 tree ET.parse(xml_path) root tree.getroot() lines [] for obj in root.findall(object): name obj.find(name).text if name not in classes: continue # 只保留关心的类别 cls_id classes.index(name) # VOC的box是左上角右下角坐标基于原图尺寸 bbox obj.find(bndbox) xmin float(bbox.find(xmin).text) ymin float(bbox.find(ymin).text) xmax float(bbox.find(xmax).text) ymax float(bbox.find(ymax).text) # 转归一化中心点宽高 cx (xmin xmax) / 2.0 / img_w cy (ymin ymax) / 2.0 / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) if lines: # 没有标注就跳过不生成空文件 with open(out_path, w) as f: f.write(\n.join(lines) \n) # 批量转换示例 img_dir barcode_ds/JPEGImages xml_dir barcode_ds/Annotations yolo_dir barcode_ds/labels/train os.makedirs(yolo_dir, exist_okTrue) classes [barcode, qrcode] # 按实际修改 for xml_name in os.listdir(xml_dir): if not xml_name.endswith(.xml): continue base xml_name[:-4] # 读取对应图片尺寸可用PIL或cv2 from PIL import Image img Image.open(os.path.join(img_dir, base .jpg)) w, h img.size voc_to_yolo( os.path.join(xml_dir, xml_name), os.path.join(yolo_dir, base .txt), w, h, classes )逻辑说明这个脚本核心只有三步解析 xml 拿坐标 → 归一化成 YOLO 五列格式 → 写入同名 txt。需要留意的是VOC 的坐标是像素绝对值而 YOLO 要求 0~1 的归一化值不在转换时除一下图片宽高训练时 loss 会爆炸。参数说明classes列表的顺序就是模型输出的类别编号一旦确定别再改动。如果你中间增删了类别之前转换出来的 txt 全部要重新生成。PIL 读取图片尺寸这一步不要在循环里频繁打开图片文件图片多时改成预先缓存如读入 dict能省掉大量重复 I/O。3. 从数据集到模型在 YOLOv8 上训练条形码检测器的完整流程3.1 环境准备与最小训练命令数据集整理成 YOLO 格式后训练本身反而简单。我一般用 ultralytics 的 YOLOv8因为它对自定义数据集的适配做得最顺不需要手写 DataLoader。环境准备就三步装 torch、装 ultralytics、准备 yaml 文件。创建数据配置文件barcode.yaml# 数据集配置文件path是含train/val子目录的根目录 path: /home/user/barcode_ds train: images/train # train图片相对path的路径 val: images/val # 验证集路径 # 类别个数和名称顺序需和标注文件一致 nc: 2 names: [barcode, qrcode]注意path写的是“图片目录的父目录”而非images/本身。train字段指向的是图片文件夹ultralytics 自动去同级的labels/目录找对应 txt。训练命令开跑yolo detect train \ databarcode.yaml \ modelyolov8n.pt \ imgsz640 \ batch16 \ epochs100 \ projectexperiments \ namebarcode_v8n参数说明yolov8n.pt是 nano 版本预训练权重条码检测这类单类别任务从 nano 起步足够显存不够也敢跑。imgsz640是输入分辨率如果你的条码是小目标后面可以上调到 1280。batch16在 16G 显存下比较稳如果 OOM 降到 8。先跑 50 个 epoch 看 loss 曲线再决定要不要继续。训练完成后验证一下效果看模型在验证集上的表现yolo detect val \ databarcode.yaml \ modelexperiments/barcode_v8n/weights/best.pt \ imgsz6403.2 训练参数怎么调图像尺寸、batch、epoch 与 anchors很多人在数据集这一层就栽了觉得把 zip 解压出来丢给 YOLO 就完事。实际训练时四个参数值得反复调。**图像尺寸imgsz**是最容易见效的旋钮。条形码数据集里如果条码区域小面积占比小于 5%640 的输入会让小条码下采样到只剩几个像素模型根本学不到纹理特征。我一般会先做一次“感受野估算”条码最短边像素数除以 32YOLOv8 的最终下采样倍数如果结果小于 3说明条码在最终特征图上不足 3 个像素必须上调 imgsz 到 960 或 1280。代价是训练速度变慢、显存暴涨但检测精度立竿见影。batch 和显存是互相制约的。16G 显存跑yolov8m在 640 下最多 16 左右跑 1280 就只剩 4。这里有个经验batch 降低后学习率最好跟着降一点例如 0.01 降到 0.005否则梯度波动大loss 容易震荡。epoch 不是越多越好。条码数据集的背景高度相似仓库、收银台、快递面单常见的问题是 80 epoch 后模型就开始过拟合——val loss 上升而 train loss 继续降。我一般用早停patience2020 个 epoch 没有改善就自动停省时间。anchors在 YOLOv8 里是自动学习的不需要手动指定。但条码极端宽高比10:1会让自动聚类产生偏差。如果发现召回率及格率低可以检查一下 anchors 分布如果 anchor 宽高比集中在 1:1 附近说明聚类时被普通目标数据带偏了。这时可以用yolo detect train ...里的auto_anchorTrue重新计算或者干脆在 yaml 里手动给 anchor 比例提示。3.3 训练结果的验证mAP、PR 曲线与漏检图分析训练跑完别只看终端里那个 mAP50 数字。条形码检测场景的验收标准和通用检测不一样比起高精度更怕漏检——扫码枪扫不到码比扫错码更让现场抓狂。所以要额外看两个指标。第一个是 PR 曲线里的召回率Recall拐点。跑一下验证yolo detect val \ databarcode.yaml \ modelexperiments/barcode_v8n/weights/best.pt \ plotsTrue \ imgsz640在runs/detect/val目录下会生成PR_curve.png和confusion_matrix.png。看 PR 曲线时注意召回率在置信度 0.5 附近的值如果 recall 低于 0.9说明有一成以上的条码压根没被框出来。这时候优先调 imgsz 而不是加 epoch。第二个是失败案例的图形化分析。plotsTrue会保存一批验证集的预测图其中带标注但没被框出来的就是漏检样本。我习惯把这类图单独抽出来统计特征是反光条码没有还是条码很小还是背景里有密集纹理这个动作做一遍数据集缺什么一目了然。另一个容易踩的坑是只看 mAP0.5 不看 mAP0.5:0.95。YOLOv8 默认报告后者条码检测对框的精确度要求不如人脸识别严苛条码区域框得稍大一点不影响解码。你真正该关注的是“检测框和条码区域的 IoU 是否大于 0.5”以及“框内条码是否完整”这两点和 mAP 不是完全正相关。4. 条形码数据集训练避坑五条真实的踩坑记录4.1 只有标注框没有类别框全归零现象训练时 loss 能正常下降但 val 时的混淆矩阵显示所有预测都落在“background”一类mAP50 为 0。原因数据集 zip 里的 txt 标注全部是 4 列而不是 YOLO 标准的 5 列。有些自动化标注工具只输出坐标不写类别 ID。读取时 YOLO 把第一列当成了类别 0于是全部框都归零类真正要区分的“二维码”类别永远没有正样本。解决写脚本检查每个 txt 文件的行格式打印列数异常的样本。如果确实只有坐标手动补类别列加一个0前缀如果数据里混有二维码也要确认是否标了 1。不要偷懒这一步错了后面全错。4.2 图像尺寸过小被 resize 成糊图现象imgsz640 训练loss 正常下降但 val 时 mAP50 只有 0.7 上下PR 曲线的召回率在 0.8 后断崖式下跌。看漏检图全是条码占图片面积 3% 的小目标。原因数据集原图是 1024×1024条码只有 30×60 像素。YOLOv8 在 640 输入下原图被缩到 640×640条码区域变成 19×38 像素再经过下采样只剩几个像素参与预测特征完全丢失。解决将 imgsz 上调到 1280 试试。同时把 mosaic 增强关闭mosaic0.0因为 mosaic 会让小目标进一步缩小对条码场景弊大于利。4.3 二维码和条形码混在一起不拆分现象类别设为[barcode]单类训练完模型把二维码也框出来而且置信度极高。原因数据集 zip 里实际包含两类条码一维码和二维码但标注时统一归为一类。模型学到了“有黑白方块纹理的就是目标”把二维码错误归类同一种。解决检查所有标注凡是 square 形状宽高比接近 1:1的框重新标为qrcode粗条状标记为barcode。如果 zip 里没有区分类别自己写脚本按宽高比阈值强制拆类阈值一般设在 1.5:1。4.4 背景噪声让模型学会“找纹理”现象训练后测试干净背景条码效果不错但一放到快递面单或包装盒上模型在文字区域疯狂画框。原因数据增强里的scale和fliplr随机变换让模型把文字、条纹背景当成了正样本。条码和印刷文字的纹理特征本来就相似模型在特征图上难以区分。解决增加 Hard Negative Mining——从训练集中抽 20% 不含任何条码的图片标注为空加入训练集。同时把hsv_h、hsv_s增强幅度调小避免颜色扰动让模型依赖颜色而不是纹理结构。模糊增强blur0.5也要开着让模型学到条码更本质的黑白间隔结构。4.5 验证集和训练集同源导致分数虚高现象val 的 mAP50 高达 0.98但应用到真实手机拍摄的视频流时漏检率超过 30%。原因zip 里如果只有一个大文件夹没有按场景切分 train/val那么训练集和验证集可能来自同一批图片的随机切分。同一场景的光照、角度、背景都高度相似模型只需“记忆”而没学会“泛化”。解决按“采集批次”切分而不是按文件随机切分——同一个批次同一时间、同一设备、同一场景的图片全部进训练集或全部进验证集。如果 zip 里没有批次信息至少要保证图片文件名前缀不重叠否则重做划分。5. 把模型部署到扫码场景推理时的预处理与后处理5.1 预处理降采样、灰度化和透视矫正模型训练好只是完成了第一步。真正上线时手里的输入不是数据集里的干净图片而是工业相机、手机摄像头甚至视频流里的帧。这时的预处理比训练时更重要直接决定检测率。首先是输入尺寸。训练时用 1280 输入部署时为了速度直接降到 640条码检测率会掉一大截。正确做法是保持和训练一致的输入尺寸或者用 TensorRT 做 INT8 量化后再降分辨率。我一般做法是部署环境计算力足够就锁死 1280只有 CPU 推理时才用 640 加一个“两阶段”策略——先用 640 粗检对候选区域再裁出来用 1280 做第二次检测。其次是灰度化。条形码本身的颜色信息几乎不影响检测但彩色背景的纹理反而干扰模型。把输入图像转成灰度图再复制成三通道能有效抑制背景色块干扰提高小条码的召回import cv2 import numpy as np def preprocess_barcode_frame(frame, target_size1280): 转灰度、再复制成三通道保持模型输入格式 target_size: 模型训练时的输入尺寸 gray cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) gray_3c cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR) # 转回三通道 h, w gray_3c.shape[:2] scale target_size / max(h, w) new_w, new_h int(w * scale), int(h * scale) resized cv2.resize(gray_3c, (new_w, new_h), interpolationcv2.INTER_LINEAR) # 直接resize会破坏宽高比这里用letterbox补边 canvas np.full((target_size, target_size, 3), 114, dtypenp.uint8) x_off (target_size - new_w) // 2 y_off (target_size - new_h) // 2 canvas[y_off:y_offnew_h, x_off:x_offnew_w] resized return canvas, (x_off, y_off, scale) # 记录坐标变换参数后处理要用逻辑说明这段代码先把彩色帧压成灰度图再复制成三通道是为了匹配模型输入格式letterbox 补边而不是直接拉伸避免条码宽高比变形否则后面的解码器pyzbar 或 ZXing拿到的框内图像是畸变的解码率会掉。返回值里记录了x_off和scale是为了把检测框坐标映射回原图时用。5.2 后处理从检测框到可读码值的管线检测到条码区域之后还要把框里的图像交给条码解码器pyzbar、ZXing 或 Dynamsoft这一步的坑比训练还多。常见的问题是框内条码只露出一部分解码器读不出码值于是很多人的第一反应是调大检测框反而更糟。我的做法是膨胀检测框。检测框只覆盖了条码的可视部分但条码解码需要左右两侧的静区空白区域尤其是在条码被截断时。默认 IoU 给的框太紧无法满足解码器的静区需求。后处理时把框向外扩 20~30%再做透视矫正。def decode_barcode_region(frame, box, x_off, y_off, scale, expand_ratio0.25): 把检测框映射回原图坐标并扩展交给pyzbar解码 box: [x1, y1, x2, y2] 模型输出的像素坐标已映射到letterbox图 # 还原到原图坐标 x1 int((box[0] - x_off) / scale) y1 int((box[1] - y_off) / scale) x2 int((box[2] - x_off) / scale) y2 int((box[3] - y_off) / scale) # 向外扩展静区是解码的必要条件 w, h x2 - x1, y2 - y1 ex_w, ex_h int(w * expand_ratio), int(h * expand_ratio) x1 max(0, x1 - ex_w) y1 max(0, y1 - ex_h) x2 min(frame.shape[1], x2 ex_w) y2 min(frame.shape[0], y2 ex_h) from pyzbar import pyzbar roi frame[y1:y2, x1:x2] gray cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY) codes pyzbar.decode(gray) # pyzbar为空时试一次二值化再解 if not codes: _, thresh cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU) codes pyzbar.decode(thresh) return codes参数说明expand_ratio0.25是经验值太小静区不足导致解码失败太大把旁边无关纹理框进来又会产生误读。二值化兜底策略解决的是照明不均的问题——条码区域一侧亮一侧暗时Otsu 全局阈值能显著提升解码成功率。如果返回的codes为空不要直接判定失败等下一帧再检测一次视频流下多帧确认比单帧硬解靠谱得多。5.3 性能优化TensorRT 半精度与批处理部署在边缘设备Jetson Nano、RK3588 之类时推理速度是绕不开的问题。YOLOv8 的 PyTorch 模型直接跑大模型在 Jetson 上只有个位数的 FPS完全没法用。做法是转成 TensorRT 引擎配合 FP16 半精度。# 用ultralytics自带的导出命令转成TensorRT yolo export \ modelexperiments/barcode_v8n/weights/best.pt \ formatengine \ device0 \ halfTrue \ imgsz1280参数说明halfTrue是 FP16 精度在大多数场景下对条码检测的精度损失几乎为 0但速度提升明显。device0指定 GPU。如果你不跑 TensorRT还有个更取巧的办法——批处理。视频流场景下不要一帧一帧推理而是攒够 4~8 帧组成一个 batch 再统一推理端到端吞吐量能提升 2~3 倍。代价是每帧延迟略微上升但对扫码枪/传送带这种连续运动场景完全可接受。实测下来同样在 Jetson Orin Nano 上PyTorch 模型跑 1280 分辨率大约 8 FPSTensorRT FP16 直接到 35 FPS效果是实打实的。6. 让数据集发挥余热用合成数据补足长尾训练好的模型在实际部署时最先暴露的问题往往是长尾分布不足——真实场景里某些角度、光线下条码完全读不出来。很多人的第一反应是再去找一批数据但更实用的做法是用 Python 自己生成合成条码数据补进训练集。合成数据的好处是可控你能精确地控制条码类型、宽高比、旋转角度、模糊程度、透视变形和背景干扰。用barcode库生成条码图像再用opencv做变换最后粘贴到任意背景图里配合标注脚本自动生成 txtimport cv2 import numpy as np import barcode from barcode.writer import ImageWriter from PIL import Image import random import os def generate_synthetic_barcode(output_dir, bg_dir, num_samples500): 生成合成条码样本 1. 用python-barcode库生成干净条码图 2. 随机透视变形、模糊、亮度调整 3. 粘贴到背景图上并生成YOLO标注 os.makedirs(f{output_dir}/images, exist_okTrue) os.makedirs(f{output_dir}/labels, exist_okTrue) bg_files [f for f in os.listdir(bg_dir) if f.endswith((.jpg, .png))] for i in range(num_samples): # 生成code128类条码内容随机 code128 barcode.get(code128, str(random.randint(10**11, 10**12 - 1)), writerImageWriter()) barcode_img code128.render(writer_options{module_width: 0.2, module_height: 10}) barcode_img np.array(barcode_img.convert(L)) # 随机透视变换模拟斜贴、曲面 h, w barcode_img.shape pts1 np.float32([[0, 0], [w, 0], [0, h], [w, h]]) dx random.randint(-30, 30) dy random.randint(-20, 20) pts2 np.float32([[dx, dy], [w - dx, dy * 2], [dx * 2, h - dy], [w - dx, h - dy * 2]]) matrix cv2.getPerspectiveTransform(pts1, pts2) warped cv2.warpPerspective(barcode_img, matrix, (w 60, h 60)) # 高斯模糊模拟失焦 if random.random() 0.5: warped cv2.GaussianBlur(warped, (5, 5), 0) # 随机背景 bg cv2.imread(os.path.join(bg_dir, random.choice(bg_files))) bg cv2.resize(bg, (640, 640)) bh, bw bg.shape[:2] ph, pw warped.shape x random.randint(0, bw - pw) y random.randint(0, bh - ph) # 混合时加一点alpha透明度让边界不那么生硬 alpha random.uniform(0.8, 1.0) roi bg[y:yph, x:xpw] warped_3c cv2.cvtColor(warped, cv2.COLOR_GRAY2BGR) blended cv2.addWeighted(warped_3c, alpha, roi, 1 - alpha, 0) bg[y:yph, x:xpw] blended # 保存图片 fname fsyn_{i:05d} cv2.imwrite(f{output_dir}/images/{fname}.jpg, bg) # 保存YOLO格式标注类别0坐标归一化 cx (x pw / 2) / bw cy (y ph / 2) / bh w_norm pw / bw h_norm ph / bh with open(f{output_dir}/labels/{fname}.txt, w) as f: f.write(f0 {cx:.6f} {cy:.6f} {w_norm:.6f} {h_norm:.6f}\n) if __name__ __main__: generate_synthetic_barcode(syn_barcode, background_images, num_samples1000)逻辑说明生成脚本的核心不只是“把条码贴上背景”而是要加入真实场景里出现的退化因素透视变形模拟侧贴模糊模拟运动失焦alpha 混合模拟光照不均匀。每一张合成图都同时生成标注文件不需要人工标注批量化生产。合成数据在条形码检测这件事上效果突出是因为条码本身是结构化纹理合成图的分布和真实分布差异不大。我自己的习惯是合成数据和真实数据按 1:3 混合训练按批次随机混合效果最好。纯用合成数据训练模型会在真实场景翻车纯用真实数据又总是缺长尾。这个度要靠实验来磨合——先训一版纯真实数据的看漏检集中在哪用合成数据定向补那部分。最后的验证技巧是部署之后每天随机抽 100 张现场图片存下来每隔一周用最新模型跑一遍记录召回率的波动。如果某类场景比如强反光连续三天都在漏那就是数据集里缺这类样本回去补。这套“检测→收集→补数据→再训练”的循环走顺了条码检测项目的整体效果才会持续变好而不是训完一次就放在那里吃灰。希望这些经验帮到你少走几趟我走过的弯路。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站