
简介面向目标检测与图像识别任务的罐装饮料图像数据集包含一千多张图片覆盖可乐、雪碧、红牛、芬达、养乐多、王老吉、东鹏特饮、AD钙奶、金典、特仑苏、蒙牛、伊利、旺仔牛奶及薯片等常见零售商品适合用于货架识别、无人售货或包装检测等场景。数据包共包含1681个文件其中1676张jpg原图3个json标注文件采用COCO格式2个txt文件提供类别对应信息整体压缩约45.57MB轻量易用。所有标注已完成整理可直接载入MMDetection、Detectron2、YOLO等主流框架进行训练或微调省去自行采集与标注的繁琐过程。目前已有824人学习下载适用于学生课程设计、算法工程师算法验证以及零售AI产品原型开发。利用该数据集可快速训练出能区分十余种饮料品牌的检测模型也可作为数据扩充或迁移学习的基准数据。1. 罐装饮料识别一千多张COCO标注图够不够撑起一个能用的检测模型做零售场景的视觉识别很多人接到的第一个需求就是“把货架上的饮料罐认出来”。罐装饮料识别这个数据集把薯片、东鹏特饮、红牛、芬达、养乐多、可乐、雪碧、王老吉九类商品用COCO格式标注好共一千多张图片解压后就能直接喂给目标检测框架。对刚入门的视觉工程师它最大的价值是拿到了一个标准标注集有图、有框、有类别不用从零造数据。一千张不算多但配合预训练权重和合理的数据增强足以训练出能演示、能评估、能往边缘设备部署的检测模型。这篇文章按我实际做这类项目的顺序来先读懂COCO标注再转格式、选模型、调参数、记录常见坑最后落到验证与部署上。2. 先读懂COCO标注JSON结构、类别统计与YOLO格式转换2.1 COCO的JSON里到底有哪些字段拿到压缩包之后第一步不是急着解压看图片而是把标注文件结构摸清楚。标题里写的“支持coco格式的标记”说的就是目标检测里最常见的标注形式。解压后通常有一个类似annotations/的目录里面放着以.json结尾的标注文件常见文件名是instances_train.json或instances_val.json。COCO格式的核心是三个顶层数组images、annotations、categories。images记录每张图片的宽高和文件名annotations记录每个检测框属于哪张图、框的坐标和类别categories记录类别ID与类别名的对应关系。{ images: [ { id: 1, file_name: img_0001.jpg, width: 640, height: 480 } ], annotations: [ { id: 1, image_id: 1, category_id: 3, bbox: [210, 120, 95, 180], area: 17100, iscrowd: 0 } ], categories: [ {id: 1, name: red_bull}, {id: 2, name: cola}, {id: 3, name: sprite} ] }这里关键的字段是bbox它表示[x, y, width, height]其中x和y是检测框左上角的像素坐标width和height是框的宽高。area是框面积训练时用不上转格式时忽略即可。iscrowd为 0 表示这个框是一个独立实例为 1 表示密集人群或一堆目标只给一个框罐装饮料数据集里基本都用 0。image_id把标注和图片关联起来转换格式时要靠它把框归到具体的图片名下。另外一个容易踩的细节是字段名大小写。COCO 规范里是file_name而不是filename写脚本之前最好先打印一个元素确认。categories里的id不一定是连续的有的标注工具会从 0 开始有的从 1 开始甚至可能跳号。后续转 YOLO 格式时必须把category_id重映射成从 0 开始的连续索引否则训练时类别就会错乱。拿这个数据集做训练前先花五分钟看明白 JSON 结构比直接开训省下的排错时间多得多。2.2 写脚本统计类别分布一千多张图里到底谁多谁少训练之前先统计类别分布这一步最容易跳过但也最值得做。罐装饮料数据集的常见问题是类别不平衡红牛和东鹏特饮这类货架主力可能有几百个框而养乐多、薯片这类只有几十个框。如果不统计等模型训练完才发现某个类别一个都检不出来再回头查数据就已经晚了。统计脚本不复杂用 Python 的json模块读入标注文件再用collections.Counter按类别计数。import json from collections import Counter with open(annotations/instances_train.json, r, encodingutf-8) as f: coco json.load(f) # 建立 category_id 到类别名的映射 id2name {cat[id]: cat[name] for cat in coco[categories]} # 统计每个类别有多少个标注框 box_counter Counter() # 统计每张图里有多少个目标判断图片是单商品还是货架全景 per_image_counter Counter() for ann in coco[annotations]: box_counter[id2name[ann[category_id]]] 1 for img in coco[images]: n sum(1 for ann in coco[annotations] if ann[image_id] img[id]) per_image_counter[n] 1 print(类别 - 框数量) for name, cnt in box_counter.most_common(): print(f{name}: {cnt}) print(\n每张图目标数量分布) for n in sorted(per_image_counter): print(f{n}个目标: {per_image_counter[n]}张图)逻辑说明第一个Counter统计每类框的总数第二个Counter统计每张图片的实例数量分布。如果发现某些图里有 30 个目标而多数图只有两三个说明数据集中存在货架全景图训练时小目标和密集场景会占主导这直接影响后面输入分辨率的选择。脚本本身不修改标注文件只是把分布打印出来可以当成训练前的体检工具每次扩数据都跑一遍。参数说明encodingutf-8不能省标注文件里如果包含中文类别名Windows 下默认 GBK 编码会直接抛UnicodeDecodeError。另外most_common()返回的是按数量从大到小的列表一眼就能看出哪些类别是少数类。如果最少类别的框只有几十个我的做法是先抽几张图出来人工看一眼确认不是标注工具漏标再决定要不要做复制粘贴增强或给该类补数据。2.3 把COCO转成YOLO格式归一化坐标与两个边界坑大多数目标检测框架不直接吃 COCO JSONYOLO 系列要求每张图片对应一个同名.txt文件每行内容为class_id x_center y_center width height四个坐标都归一化到 0 到 1 之间。转换脚本本身不难难的是坐标换算的边界条件。COCO 的bbox是左上角坐标加宽高而 YOLO 要的是中心点坐标加宽高换算公式必须写对。import json import os def coco_to_yolo(coco_path, output_dir): with open(coco_path, r, encodingutf-8) as f: coco json.load(f) # 把 COCO 的 category_id 映射为从 0 开始的连续索引 cat_ids [cat[id] for cat in coco[categories]] cat_id2idx {old_id: i for i, old_id in enumerate(cat_ids)} img_id2info {img[id]: img for img in coco[images]} anns_by_img {} for ann in coco[annotations]: anns_by_img.setdefault(ann[image_id], []).append(ann) for img_id, anns in anns_by_img.items(): img img_id2info[img_id] base os.path.splitext(img[file_name])[0] txt_path os.path.join(output_dir, base .txt) with open(txt_path, w, encodingutf-8) as f: for ann in anns: x, y, w, h ann[bbox] # 左上角 宽高 - 中心点 宽高再归一化 cx (x w / 2) / img[width] cy (y h / 2) / img[height] nw w / img[width] nh h / img[height] cls_idx cat_id2idx[ann[category_id]] f.write(f{cls_idx} {cx:.6f} {cy:.6f} {nw:.6f} {nh:.6f}\n) coco_to_yolo(annotations/instances_train.json, labels/train)逻辑说明这里有两个最典型的坑。第一COCO 的bbox是左上角坐标YOLO 要的是中心点坐标必须先加w / 2、h / 2再归一化直接除以图片宽高是错的。第二COCO 的category_id不一定从 0 开始YOLO 的类别索引必须从 0 开始连续编号所以要用cat_id2idx做一次重映射。我曾经见过有人直接把categories里的id写进.txt结果训练时类别错乱得一塌糊涂光排查就花了一个下午。参数说明output_dir要提前建好并且生成的.txt文件名必须和图片文件名保持同名。YOLO 训练时会在数据配置文件的路径里找图片和标签标签的.txt必须与对应.jpg同名。这个转换脚本只处理了训练集验证集用同一套函数换路径就能完成。转完之后的验证方式也很简单随机挑五张图用 OpenCV 把txt里的框画回原图肉眼看一遍。转格式这种机械化操作最容易出问题的就是“看起来没报错实际上全偏了”可视化是唯一的后悔药。3. 模型选型与训练用YOLOv8把千图数据集跑出可用模型3.1 为什么选YOLOv8而不是Faster R-CNN一千多张图的数据量在深度学习里属于小型数据集。选模型的第一原则不是精度最高而是迁移学习收益最大、训练成本可控。Faster R-CNN 这种两阶段检测器在小数据集上确实能出不错的精度但训练速度慢、调参敏感对刚接触目标检测的工程师不友好。相比之下YOLOv8 在相同数据量下能用预训练权重快速收敛而且内置一组效果不错的数据增强属于开箱即用的典型。有人会问这种罐装饮料识别能不能直接用 OpenCV 识别物体那套办法靠颜色阈值和轮廓来找单独一个可乐罐可以但货架上多种饮料互相遮挡、光照不一颜色阈值立刻失效。类似的OCR 识别只能读到罐身印刷的文字但东鹏特饮和红牛的字样都可能被遮挡拍摄角度一偏文字就变形。这类场景的本质是视觉识别里的目标对象识别靠数据驱动比靠手工特征稳定得多。再加上货架盘点、自动售货机视觉结算这类场景对推理速度有天然要求YOLOv8 的 n/s/m/l 四个尺寸可以按设备选先用最小的yolov8n把流程跑通再根据速度和精度的权衡换大模型。如果用 MMDetection 或 PaddleDetection 当然也能训但配置文件的复杂度会高一个量级。在这个数据量下我更愿意把时间花在数据质量和验证手段上而不是折腾框架配置。简单说模型之争还没开始框架选型已经决定了下限。3.2 训练前的数据划分与目录整理YOLOv8 训练需要的数据目录结构很固定一个总的data.yaml指向 train 和 val 两个目录每个目录下又分images和labels。转换脚本生成的标签文件要先放进去。这里有一个顺序问题先划分数据集再转标签还是先转完再按文件列表划分我推荐前者先划分图片再对着划分结果生成标签避免同一个文件被两边重复引用。import random import shutil from pathlib import Path src Path(raw_images) dst_train Path(dataset/images/train) dst_val Path(dataset/images/val) # 固定随机种子保证每次划分结果一致 random.seed(42) imgs sorted(src.glob(*.jpg)) random.shuffle(imgs) val_n int(len(imgs) * 0.2) for img in imgs[:val_n]: shutil.copy(img, dst_val / img.name) for img in imgs[val_n:]: shutil.copy(img, dst_train / img.name)逻辑说明随机抽样时固定random.seed(42)保证结果可复现否则每次划分不同模型之间没法公平对比。划分的关键是按图片文件名来而不是按目录来。罐装饮料数据集的图片可能来自多个拍摄批次如果按目录划分会造成领域偏移模型在验证集上表现好换一批真实图片就崩。划分完图片之后再用第二章的转换脚本只对 train 和 val 各自生成对应标签。参数说明val_n按 0.2 比例计算一千多张图大概保留 200 到 300 张做验证。验证集太少则 mAP 波动大太多则训练数据不够。划分完之后还要做一次一致性检查遍历dataset/images/train下的每张图确认dataset/labels/train里有同名的.txt。有图无标签的文件会被 YOLO 当作无目标背景图参与训练漏得多了会学出“货架就是背景”的偏见。我一般写一个三行的校验脚本把有图无标签和有标签无图都列出来有标签无图的直接删掉。3.3 训练命令、关键参数与结果文件解读数据准备好之后训练命令其实很短。以 YOLOv8 为例一条命令就能启动yolo train \ modelyolov8n.pt \ datadataset/data.yaml \ epochs100 \ imgsz640 \ batch16 \ patience20 \ workers4 \ projectruns/train \ namedrink_v1参数说明modelyolov8n.pt表示从 COCO 预训练权重开始这是小数据集能收敛的关键不建议从随机权重开始训练。epochs先给 100配合patience20做早停实际可能在 60 轮附近就停了。imgsz640是速度和精度的折中如果后面发现小目标漏检可以提到 768 或 960代价是显存占用增加。batch16在多数 16G 显卡上够用显存不足就降到 8。workers4是读取图片的子进程数Windows 上如果报错可以先改成 0。训练过程中的三个关注点。第一看 loss 曲线box_loss和cls_loss是否平滑下降如果有明显回升可能是学习率过大或数据里有脏标注。第二看 P、R、mAP50 这几个指标在验证集上的变化它们每个 epoch 都会打印。第三看训练集和验证集指标差距如果训练指标一直涨而验证指标上不去就是过拟合的信号早停会自动触发但也可以主动加大增强。首轮训练结束后runs/train/drink_v1/weights/下会生成best.pt和last.pt。best.pt是验证集上 mAP 最好的权重部署用这个last.pt是最后一个 epoch 的权重后续想继续训练时用这个。很多新手把两者搞混拿last.pt去部署结果发现效果不如训练时测试得好。这个细节在之后的部署章节还会再强调。4. 罐装饮料识别的五个常见坑训练日志背后的真实翻车记录4.1 COCO转YOLO后框全部偏移可视化才发现错了一整轮现象训练 loss 下降正常但推理时所有框都跑到目标的右下角或者框的尺寸明显不对。训练日志看不出问题把框画回原图才发现每个框都在原始位置的右下方。原因COCO 的bbox是左上角坐标但有些标注工具导出的 COCO 变体用的是中心点坐标。如果直接复制网上的转换脚本没看原标注格式就按左上角加一半宽高的公式算结果等于把中心点又偏移了一次。这个数据集如果标注文件里带segmentation字段说明标注工具导出过多边形bbox可能是多边形外接矩形坐标仍然是左上角问题多半出在转换脚本本身。解决转格式之前随机打印三条 annotation 的原始值人工核对bbox里的坐标是否小于图片宽高。再写一个绘制脚本把转换后的.txt框画到原图上不要只看一张看十张。坐标这种错训练多久都是白训越早发现越省时间。4.2 类别不平衡红牛框的数量是养乐多的十倍现象训练完成后红牛、可乐这类样本多的类别识别率很高养乐多、薯片这种数量少的常被漏检或者只检出大目标小目标全丢。看混淆矩阵时发现少数类大量被预测成背景。原因一千多张图里每类框数量不均衡是常态。货架场景中红牛和东鹏特饮往往摆满一整层而养乐多是瘦长的小瓶身薯片是袋装拍摄时不会特意给它们均匀补拍。模型本质是在最小化平均损失多数类的梯度会主导权重更新少数类学不到足够特征。解决做法分三层。第一层是数据层给少数类做复制粘贴增强把养乐多的检测框裁出来随机粘贴到其它图片的空白区域同时更新标注。第二层是训练层给少数类复制几份样本或者提高采样频率让每个 epoch 里少数类出现的次数更接近多数类。第三层是评估层不要只看总 mAP单独看每类 AP如果养乐多 AP 只有 20 而红牛有 90先补数据再调参顺序不要反。4.3 相似外观误检可乐、雪碧、芬达的罐身颜色太接近现象雪碧的绿色罐身被识别成可乐红色罐身的王老吉被识别成红牛这种误检在货架照片上特别集中。原因罐装饮料的辨识信息集中在罐身颜色和 logo 图案。如果数据集的图片都在类似光照下拍摄模型会把颜色当作最强特征而不是 logo 纹理。芬达的橙色和可乐的红色在 RGB 空间里距离不大加上货架灯光偏暖色差进一步缩小。解决数据层面把 YOLOv8 默认的hsv_h、hsv_s增强保留必要时调大逼迫模型去学 logo 和文字结构。其次是输入分辨率把imgsz从 640 提到 960让罐身 logo 区域的像素更多特征更明显。最后是后处理层面看到模型对某两类特别容易混淆就在输出端做一个规则过滤根据检测框的长宽比和平均颜色做二次判断这个技巧在最后一章展开。4.4 小目标漏检货架深处和俯拍边缘的罐子总是检不出来现象近处的大罐子识别率很高货架深处的小罐子几乎没有检出。验证集 mAP50 不低但实际部署时业务方指着一张货架全景问这个角落为什么没识别出来。原因mAP 的计算天然偏向容易的目标一千多张图里大多数标注框占的面积不小少量小目标对总指标的贡献很低。训练时下采样倍数固定小目标的特征在深层特征图里已经丢失这是一个结构性问题不是简单加 epoch 能解决的。解决最直接的办法是提高输入分辨率imgsz960会让小目标保留更多像素。如果显存不够还有一种更省显存的方案把原图切成若干子图分别推理后再合并结果这就是切片推理对货架这种目标分布不均匀的场景很有效。另一个思路是检查标注里是否真的有大量小框如果小框数量本来就不多单纯调模型不如先补标注。4.5 训练集mAP接近0.9验证集却忽高忽低现象训练过程指标一路走高best.pt在验证集上第一次跑 mAP50 有 0.85第二次用同一个权重只有 0.6差异大得反常。原因验证集图片数量太少或者分布太偏。验证集如果只有几十张其中恰好有几张拍摄角度、光照极为特殊它们的预测结果会显著影响整体 mAP。还有一种情况是验证集里混入了标注错误的数据某个框画偏了模型恰好漏检或误检单张 AP 变成 0 拉低整体。解决验证集至少保留 80 到 100 张按拍摄批次分层抽样不要让同一批图片全部进了验证集。对验证集的标注再做一次人工抽检重点看那些角度刁钻的图。另外把验证集固定下来每次训练完都在同一批图上评估不要每次重新抽样否则模型之间没法对比迭代效果。5. 验证与部署从best.pt到能被业务方试用的识别服务5.1 用mAP50、mAP50-95和混淆矩阵判断模型真实水平训练结束不是看 loss 顺眼就算成功要跑正式的验证命令并记录三个数字mAP50、mAP50-95、每类 AP。mAP50 是 IoU 阈值 0.5 下的平均精度适合判断“框大致对不对”mAP50-95 是多个 IoU 阈值下的平均对框的定位精度更敏感。罐装饮料识别如果 mAP50 在 0.85 以上说明“认得出大类”已经做到如果 mAP50-95 还不到 0.5说明框的边界不准确后续做数量统计或尺寸估计时会吃亏。yolo val \ modelruns/train/drink_v1/weights/best.pt \ datadataset/data.yaml \ imgsz640 \ batch16 \ projectruns/val \ namedrink_v1_eval逻辑说明这条命令会输出一个confusion_matrix.png我每次都会打开看。混淆矩阵能告诉你错误集中在哪一对类别之间比看 loss 和 mAP 直观得多。如果王老吉和红牛横竖混在一起就回到第四章的相似外观处理思路。val 结束后还会生成results.csv里面有每类 AP直接用表格软件打开就能对比少数类和多数类的差距。参数说明imgsz要和训练时一致否则推理分辨率变化会影响结果稳定性。batch在验证时影响不大但保持默认即可。如果验证集图片数量很少可以加batch1避免内存波动。这一步做扎实后面部署时的效果才不会和训练时的承诺对不上。5.2 部署成HTTP服务给业务方一个能上传图片的接口业务方通常不关心训练过程他们只想知道给我一张图你能不能返回这罐是什么。最快的方式是用 FastAPI 包一个推理接口把模型文件加载进内存接收图片后返回检测结果。from fastapi import FastAPI, UploadFile from ultralytics import YOLO import cv2 import numpy as np app FastAPI() model YOLO(runs/train/drink_v1/weights/best.pt) # 类别名顺序必须与训练时的类别索引一一对应 CLASS_NAMES [chips, dongpeng, redbull, fanta, yakult, cola, sprite, wanglaoji] app.post(/predict) async def predict(file: UploadFile): data await file.read() img cv2.imdecode(np.frombuffer(data, np.uint8), cv2.IMREAD_COLOR) results model(img, conf0.25, imgsz640)[0] boxes [] for box in results.boxes: cls_idx int(box.cls[0]) x1, y1, x2, y2 [float(v) for v in box.xyxy[0]] boxes.append({ class: CLASS_NAMES[cls_idx], confidence: round(float(box.conf[0]), 4), bbox: [x1, y1, x2, y2] }) return {count: len(boxes), boxes: boxes}逻辑说明把请求图片解码成 OpenCV 的 BGR 格式直接交给模型推理。conf0.25是置信度阈值低于这个值的预测不返回。这里显式传了imgsz640避免后续换成大模型后分辨率不一致。接口返回的bbox是像素坐标业务方可以直接在图片上画框也可以用来计算目标间距。参数说明CLASS_NAMES的顺序必须严格对应训练时的类别索引。如果在转换 COCO 时做过 ID 重映射这里很容易写错顺序导致接口返回的类别名张冠李戴。我一般会把训练时的data.yaml内容打印出来从这里复制类别列表而不是凭记忆写。另外 FastAPI 默认是单进程模型并发量上来之后建议换成带队列的推理服务或者用 Triton 这类专用推理框架但原型演示阶段这个接口已经够用。5.3 数据闭环用模型辅助标注来扩数据集一千多张图训练出的模型不是终点。实际试用时它会在真实环境里遇到更多拍摄角度、更多光照、更多堆叠方式。这个时候与其从头整理新数据不如让模型先跑一遍未标注图片把置信度低的检测结果交给标注员修正这就是预标注流程。from ultralytics import YOLO import cv2 model YOLO(runs/train/drink_v1/weights/best.pt) img cv2.imread(new_shop_shelf.jpg) results model(img, conf0.1, imgsz640)[0] # 把置信度低于0.4的预测保存为待确认框标注员只需要校正位置 for box in results.boxes: conf float(box.conf[0]) if conf 0.4: x1, y1, x2, y2 [int(v) for v in box.xyxy[0]] cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.putText(img, f{conf:.2f}, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) cv2.imwrite(pending_check.jpg, img)逻辑说明策略是把置信度阈值降到 0.1让模型尽可能输出候选框再把低于 0.4 的框标红保存。标注员只需要把这些红色框拖到正确位置或者删除明显误检就能完成新数据的标注。标注完成后转回 COCO 格式合并进原数据集重新训练。这个循环每跑一轮模型在真实场景的适应性都会提升一截。参数说明0.1 和 0.4 这两个阈值要根据当前模型的表现调整。如果模型整体欠拟合置信度普遍偏低预标注结果参考价值有限如果过拟合置信度虚高反而会漏掉该查的框。另外给标注员写清楚类别清单特别是王老吉和红牛、可乐和芬达这种容易混淆的能减少大量返工。6. 让识别更稳的最后一招用尺寸先验和颜色约束压掉误报6.1 从训练集统计每类的长宽比和颜色区间模型部署到真实货架后最常见的问题是把红罐饮料认成红牛或者把绿罐雪碧和蓝色芬达搞混。单靠训练很难彻底解决因为颜色太接近光照一变RGB 值就重叠。我的处理思路不是换更大的模型而是在推理输出后加一个轻量后处理层先统计训练集里每一类标注框的长宽比和 HSV 颜色分布再用统计结果过滤明显不符合先验的检测框。统计方法不复杂遍历训练集所有标注框对每类计算height / width的均值、最小值、最大值同时对框内像素做 HSV 转换统计色相均值。红牛罐身比王老吉高可乐罐比雪碧粗这些差异在数据里都能体现出来。把统计结果写成一个字典后续过滤直接查表。6.2 把规则过滤接在模型输出后面并做回归测试以长宽比和色相为例过滤逻辑写出来很轻量VALID_RATIO { redbull: (1.8, 2.4), wanglaoji: (1.4, 1.9), cola: (1.7, 2.3), # 其它类别按训练集统计结果填入 } def filter_by_prior(boxes, img): filtered [] for box in boxes: x1, y1, x2, y2 [int(v) for v in box[bbox]] w, h x2 - x1, y2 - y1 ratio h / max(w, 1e-6) low, high VALID_RATIO.get(box[class], (1.0, 5.0)) if not (low ratio high): continue roi img[y1:y2, x1:x2] hsv cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) mean_h hsv[:, :, 0].mean() # 红牛、王老吉、可乐的罐身主色不应落在蓝色区域 if 110 mean_h 170: continue filtered.append(box) return filtered逻辑说明VALID_RATIO的取值不是硬编码而是从训练集标注里统计出来的。判断条件是先看长宽比是否落在该类合理区间再看框内像素的平均色相是否落在蓝色区域。红色罐体的色相集中在 0 到 10 附近蓝色罐体在 110 到 170 附近如果模型把一个蓝色区域的框判成红牛大概率是误检。参数说明这个过滤逻辑必须放在模型输出之后并且不能影响对低置信度框的判断。我踩过的坑是凭经验写死 ratio结果模型没问题后处理先翻了车。正确做法是先用验证集统计每类标注框的长宽比和颜色分布再用统计结果做规则过滤最后拿一批真实货架图回归测试。把这条规则写进推理服务后我这边误报率从每张平均 3.2 个降到 1.1 个代价是少数被遮挡的罐子被过滤掉了。这也是我常用的工作习惯先信指标再信自己的眼睛最后才信后处理规则。希望帮到你。本文还有配套的精品资源点击获取