☰
基于YOLOv11的煤块识别数据集构建与训练实战指南
2026/10/2 3:22:57 网站建设 项目流程

简介:这是一份面向煤堆与大块煤识别场景的目标检测数据集,素材取自煤矿现场真实拍摄,全部一千七百六十七张图片已完成YOLOv11格式标注。适合从事计算机视觉、深度学习或煤矿智能化开发的算法工程师、科研人员及学生,可直接用于目标检测模型的训练、验证与参数调优。压缩包内共2000个文件,包含232张JPG原始图像、1767个TXT标签文件以及1个YAML配置文件;TXT与JPG一一对应,保存YOLO格式的类别和边界框坐标,YAML定义了类别名称及训练配置,可无缝接入YOLOv11训练流程。整个压缩包大小仅三十九点一五兆字节,轻量便捷,已有六百九十二人浏览学习,数据规模适中。利用该数据集可省去从零标注的时间,直接获得真实的煤矿现场样本,便于进行算法对比、模型优化、小样本迁移学习或教学实训,为煤炭行业中的块煤检测、煤堆监测等细分任务提供可靠数据支撑。

1. 1767 张煤矿现场图,为什么说这个煤块识别数据集能少走三个月弯路

夜晚的输煤皮带最怕的不是断煤,而是夹着一块 300mm 以上的大块煤直奔破碎机入口。矸石或大块煤一旦卡进格筛,轻则断煤停机,重则损坏齿辊。最稳的落地路径是:在皮带或落料口上方装一台防尘相机,用目标检测模型实时把“大块煤”框出来,联动破碎机或报警。而这类模型好不好用,七成不取决于网络结构,取决于底下的数据集。1767 张煤矿现场采集图片、用 YOLOv11 格式标注,这正是这类项目最常见的起步原材料:单类别、目标大、背景单一,但照度不均匀、粉尘遮挡、煤块叠压严重。别小看这 1767 张图,标注格式摆正、切分合理,足够把 YOLOv11 的 s 或 m 版本推到可上线水平。这篇笔记就按“格式怎么看、标注怎么做、模型怎么训、现场怎么验”的顺序把它讲透,给准备自己攒煤块检测数据的从业者一条能照抄的路径。

2. YOLOv11 标注格式与目录组织:一张图片配一个 txt 是怎么写的

YOLOv11 沿用了 Ultralytics 生态默认的标注格式:一张图片对应一个同名的 txt 文件,txt 里的每一行描述一个目标对象。这种格式的好处是纯文本、体积小、不依赖数据库,无论你是用 LabelImg 手工标注,还是从 COCO、VOC 这类旧项目迁移,最终都要落到这个格式上。标题里说“使用 yolov11 格式对 1767 张煤矿现场采集图片进行标注”,实际操作时就是指:为每张现场图片生成一个 txt,再按训练、验证目录摆好,写一个 data.yaml。这一步做完,数据集才算真正“能用”,而不是一堆 jpg 加一摞 XML。

2.1 一个 txt 标注文件里到底存了什么:类别号加四个归一化坐标

打开任意一个标注好的 txt,里面通常是这样的:

0 0.4821 0.3654 0.1235 0.0987 0 0.6132 0.5220 0.0871 0.0744 0 0.2555 0.6112 0.1540 0.1210

每行五个数字,空格分隔。第一个数字是类别 ID,在只有一个“大块煤”类别的项目里永远是 0;后面四个数字分别是目标的中心点 x 坐标、中心点 y 坐标、目标框宽度、目标框高度,全部做归一化处理——除以图片本身的宽度和高度,取值范围在 0 到 1 之间。要注意,txt 里不写置信度,置信度是模型推理时的输出,标注文件里只有位置信息和类别。

从像素坐标转换到归一化坐标,常见做法是写一个转换函数。下面是我在煤块数据集上用的版本:

def pixel_box_to_yolo(pixel_box, img_w, img_h): """ 将像素坐标系下的 [xmin, ymin, xmax, ymax] 转为 YOLO 归一化坐标 pixel_box: 标注框左上角和右下角的像素坐标 img_w, img_h: 图片原始宽高 """ x_min, y_min, x_max, y_max = pixel_box # 中心点坐标除以图片宽高,得到相对值 center_x = ((x_min + x_max) / 2) / img_w center_y = ((y_min + y_max) / 2) / img_h # 框宽高同样除以图片宽高 width = (x_max - x_min) / img_w height = (y_max - y_min) / img_h # 煤块经常被皮带边缘裁切,画框时容易越界,这里强制钳制到合法区间 center_x = min(max(center_x, 0.0), 1.0) center_y = min(max(center_y, 0.0), 1.0) width = min(width, 1.0) height = min(height, 1.0) return center_x, center_y, width, height

这段代码的逻辑很简单:先算出目标框中心点像素坐标,再分别除以图片宽度和高度。最后那四行钳制非常关键,煤矿现场的图片经常出现煤块在画面边缘被裁掉一半的情况,标注人员很容易把框画出图片边界,如果不钳制,训练时 Ultralytics 的 mosaic 增强再一裁剪,标注坐标可能落到图外,产生一堆无效负样本。实际转换时如果发现钳制次数很多,说明这批图该做边缘填充或重新构图,而不是靠钳制硬扛。

2.2 数据集的目录结构和 data.yaml:1767 张图怎么摆不会乱

拿到 1767 张煤矿现场图片,最忌讳的做法是把所有图片和 txt 平铺在一个文件夹里直接开训。YOLOv11 训练要求图片和标注文件分离,我的习惯是搭成下面这种结构:

coal_block_dataset/ ├── images/ │ ├── train/ # 1414 张 │ └── val/ # 353 张 ├── labels/ │ ├── train/ │ └── val/ └── data.yaml

其中 images 和 labels 下面的子目录必须一一对应,train 里的每一张 jpg 都要在 labels/train 里有一个同名 txt。这里有个容易踩的坑:如果 images/train 里有一张图在 labels/train 里找不到同名文件,Ultralytics 不会报错,只会把这张图当背景样本跳过,导致训练数据量悄悄缩水。我处理煤块数据集时,会专门写个核查脚本,保证每个文件名在两边同时存在,比对完才进训练流程。

划分比例上,1767 张图按 8:2 切分,train 放 1414 张、val 放 353 张是够用的。但切分不能按文件名随机 shuffle,要按拍摄视频片段和拍摄日期分组切。煤矿现场采集大多是抽帧得到的连续帧,同一段视频里相邻两张几乎一模一样,如果随机切,训练集和验证集会同时出现同一段画面,验证集的 mAP 会虚高到 0.98,一到现场就露馅。按场景切分这件事在第 5 章还会展开讲。

接着是 data.yaml:

# 数据集根目录,这里最好写绝对路径,避免训练时相对路径解析错 path: /data/coal_block_dataset # train 和 val 都是相对 path 的目录 train: images/train val: images/val # 类别名,单类别场景用 0 号即可 names: 0: large_coal

data.yaml 是训练时唯一要手动写的配置文件。path 字段建议写绝对路径,尤其当数据集不在当前工作目录下时,相对路径经常解析出问题。names 里 0 号对应 large_coal,意思是“大块煤”。如果现场还需要区分“煤矸石”和“大块煤”,就把 names 配成两行,0 和 1 分别命名,但前提是标注阶段就把这两类分开画框。

注意:如果现场还有煤矸石需要识别,不要一开始就把矸石和大块煤合并成一个类别。合并后模型很难学到两者的边界特征,后期再拆分类别,所有标注都要返工,这个后悔药代价很高。

3. 用标注工具把现场照片变成 YOLOv11 数据集:LabelImg 与转换脚本

这一章解决的是“标注怎么做”的问题。很多人以为标注就是打开工具画框,其实画框只占一半工作量,另一半是导出的格式能不能正确转成 YOLOv11 的 txt。1767 张图的规模不算大,一个人全职标大概两天到三天能完成,但前提是工具选对、转换脚本没有边界 bug。下面按选型、转格式、验标注三步走。

3.1 标注工具选型:LabelImg 手标还是 CVAT 协作

目标检测常用的标注工具无非 LabelImg、Labelme、CVAT 这几类。针对煤堆和大块煤这种单类别、矩形框就够用的场景,我的建议是单机用 LabelImg,多人协作再上 CVAT。

工具默认输出格式适合场景这套数据集里的评价
LabelImgPascal VOC XML单机一人标注,几千张以内画矩形框最快,连续标 1767 张最省事
LabelmeJSON 多边形需要分割掩码或斜框重叠煤块想精分割时可用,但转 YOLO 框要多一步
CVATCOCO JSON / YOLO txt多人同时标注、带审核流程适合让外包或班组同事分批标注,需要部署服务
X-AnyLabeling可直接导出 YOLO txt半自动预标注先用现成模型预标再人工修正,能省不少时间

我在处理煤矿现场图时通常用 LabelImg,原因是这类图目标单一、边界相对清楚,矩形框完全够用。LabelImg 的快捷键 W 画框、D 切下一张、Ctrl+S 保存,练熟以后一张图标 40 秒到 1 分钟,1767 张一天半就能完成。如果是多人分头标,用 CVAT 更合适,标注结果统一导出成 COCO JSON,再到本地转 YOLO 格式。不管哪种工具,最后都要过一遍转换脚本。

3.2 LabelImg 的 VOC XML 转 YOLO txt:转换脚本与参数说明

LabelImg 默认保存的是 Pascal VOC 格式的 XML 文件,里面存着图片尺寸、目标名称和 bndbox 四个像素坐标。YOLOv11 训练只认归一化的 txt,所以必须写转换脚本。下面这段代码可直接复用:

import os import glob import xml.etree.ElementTree as ET def convert_voc_to_yolo(xml_path, out_txt_path, class_name_to_id): """ VOC XML 转 YOLO txt class_name_to_id: 类别名到 ID 的映射字典,例如 {"large_coal": 0} """ tree = ET.parse(xml_path) root = tree.getroot() # 图片尺寸在 XML 的 size 节点里,用于归一化 size = root.find("size") img_w = int(size.find("width").text) img_h = int(size.find("height").text) lines = [] # 遍历该 XML 里的所有目标框 for obj in root.iter("object"): name = obj.find("name").text if name not in class_name_to_id: print(f"[跳过] {xml_path} 里出现未定义类别: {name}") continue box = obj.find("bndbox") x_min = float(box.find("xmin").text) y_min = float(box.find("ymin").text) x_max = float(box.find("xmax").text) y_max = float(box.find("ymax").text) # 算中心点和宽高,再归一化 cx = ((x_min + x_max) / 2) / img_w cy = ((y_min + y_max) / 2) / img_h w = (x_max - x_min) / img_w h = (y_max - y_min) / img_h # 防止边缘目标框写出图片范围 cx = min(max(cx, 0.0), 1.0) cy = min(max(cy, 0.0), 1.0) w = min(w, 1.0) h = min(h, 1.0) lines.append(f"{class_name_to_id[name]} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}") with open(out_txt_path, "w", encoding="utf-8") as f: f.write("\n".join(lines)) if __name__ == "__main__": # 单类别映射,类别名必须和你在标注工具里写的一致 class_map = {"large_coal": 0} xml_list = glob.glob("/data/coal_block_dataset/xml/*.xml") for xml_path in xml_list: txt_path = xml_path.replace("/xml/", "/text_labels/").replace(".xml", ".txt") os.makedirs(os.path.dirname(txt_path), exist_ok=True) convert_voc_to_yolo(xml_path, txt_path, class_map)

这里有几个参数值得留意。img_w和img_h取自 XML 里的 size 节点,转换前最好抽查几张图,确认 XML 里的尺寸和实际 jpg 尺寸一致,否则归一化坐标会整体偏移。class_name_to_id的键必须和你在标注工具里输入的 name 完全一致,大小写都不能差,我见过把 Large_coal 和 large_coal 混用导致转换后类别 ID 全乱的案例。另外float()转换对整数坐标和字符串坐标都兼容,但如果 XML 里出现空值或非数字字符会直接抛异常,跑之前先用命令查一下有多少 XML 是残缺的。

3.3 1767 张标注的验收检查:把框画回图上抽查

标注完成不代表数据能用,最常见的坑是画框时鼠标手抖导致框偏了半个煤块,或者漏标了角落里的小煤块。我习惯训练前做一个“可视化回读”操作——把 txt 里的坐标画回原图,逐张看一眼效果。这一步可以用 OpenCV 写个小脚本:

import cv2 def draw_yolo_boxes(img_path, txt_path, out_path): """ 把 YOLO txt 标注框画回到原图上,用于人工抽查 """ img = cv2.imread(img_path) if img is None: print(f"[错误] 图片读取失败: {img_path}") return False h, w = img.shape[:2] with open(txt_path, "r", encoding="utf-8") as f: for line in f: parts = line.strip().split() # 合法行必须有 5 个字段,字段数不对说明转换有问题 if len(parts) != 5: print(f"[非法行] {txt_path}: {line.strip()}") continue _, cx, cy, bw, bh = map(float, parts) # 归一化坐标换算回像素坐标 x1 = int((cx - bw / 2) * w) y1 = int((cy - bh / 2) * h) x2 = int((cx + bw / 2) * w) y2 = int((cy + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.imwrite(out_path, img) return True

这段代码会读入 txt 逐行画框,框越界时画出的矩形会超出图片边界,一眼就能看出来。用这个脚本把 1767 张图全部生成预览图,再按 10% 左右的比例抽检,重点看三类问题:框是不是正好包住煤块的可见部分、有没有把皮带托辊或背景误标成煤、有没有漏掉堆叠在下层的煤块边缘。抽检发现问题集中的,直接回标注工具改对应图片,不要全部推倒重来。

4. 用 1767 张图训练 YOLOv11:最小能复现的命令与四组关键参数

数据集和标注就绪之后,训练本身反而是最不费脑子的环节。Ultralytics 把训练流程封装得很干净,一条命令能跑通,难点在于参数怎么定。煤堆场景目标大、类别少、背景变化有限,用 yolo11s 或 yolo11m 就够,不需要一上来就上 yolo11x 把显存吃满。下面给出最小可复现的训练方案。

4.1 装环境与最小训练命令

先装 Ultralytics 环境,Python 3.9 以上即可:

# 安装 ultralytics 库,会自动带起 torch 等依赖 pip install ultralytics

训练命令用 yolo CLI 最直接:

yolo detect train \ data=/data/coal_block_dataset/data.yaml \ model=yolo11s.pt \ epochs=150 \ imgsz=640 \ batch=16 \ patience=40 \ device=0

每条参数都有讲究。model=yolo11s.pt是从官方预训练权重继续训练,比从零训练收敛快得多,1767 张图的数据量完全够做微调。epochs=150是上限,煤块这种单类别任务通常 80 到 100 个 epoch 就收敛。patience=40是早停的容忍轮数,验证集指标连续 40 个 epoch 不提升就自动停,既省时间又防止过拟合。imgsz=640是输入图片的短边尺寸,第 5 章会提到叠压场景下可以提到 960 或 1280。batch=16在 12GB 显存的消费级显卡上跑 yolo11s 不爆显存,如果是 8GB 显存降到 8。

4.2 模型选 yolo11s 还是 yolo11m:煤堆场景的取舍

很多初学者上来就选最大模型,这是煤块识别最容易翻车的地方。大模型在小数据集上过拟合更快,推理速度还拖后腿。针对 1767 张的规模,我一般先跑 yolo11s,效果不够再上 yolo11m:

模型相对速度显存占用适用情况
yolo11n最快约 2GBJetson 等边缘设备,追求帧率
yolo11s快约 4GB我建议的默认选择,精度和速度均衡
yolo11m中等约 8GB叠压严重、误检多时换这个
yolo11l/x较慢10GB 以上1767 张图不建议直接上

判断标准不是理论精度,而是现场延时的要求:如果模型部署在工控机上,yolo11s 在 GTX 1660 上能跑到 40 FPS 以上,完全够用;如果要驱动机械臂或分拣阀,m 版延迟也就多 20 毫秒左右,可以接受。我处理过的煤块项目里,s 版在 1767 张图上 mAP50 能到 0.96 左右,够用;如果视频里经常出现三五块煤叠压成一大片,s 版会框得比较粗糙,这时候换 m 版比加数据集更有效。

训练自己的数据集时,代码方式和命令行等价:

from ultralytics import YOLO # 加载预训练权重 model = YOLO("yolo11s.pt") # train 参数与命令行一一对应 results = model.train( data="/data/coal_block_dataset/data.yaml", epochs=150, imgsz=640, batch=16, patience=40, device=0, )

PyTorch 代码的好处是可以把调试逻辑塞进训练回调里,但对多数项目,命令行方式足够。model.train返回的 result 对象里能看到训练过程中的损失变化,训练结束后权重自动存到runs/detect/train/weights/best.pt,best 是验证集指标最优的那一版,别误用成最后一轮的 last.pt。

4.3 训练日志里的三条 loss 曲线怎么看

训练过程中,终端会输出 box_loss、cls_loss、dfl_loss 三行损失值,外加 precision、recall、mAP 等指标。煤堆识别场景里,普通人最容易犯的错是死盯 mAP,不看 loss。当过拟合或标注有污染时,mAP 可能还在涨,但 box_loss 和 cls_loss 已经分道扬镳了。

训练日志会自动存成 CSV,画个曲线更直观:

import pandas as pd import matplotlib.pyplot as plt # 训练结果保存在 runs/detect/train/results.csv df = pd.read_csv("runs/detect/train/results.csv") # 看 box_loss 的训练集和验证集趋势,比单看 mAP 可靠 plt.plot(df["epoch"], df["train/box_loss"], label="train box_loss") plt.plot(df["epoch"], df["val/box_loss"], label="val box_loss") plt.legend() plt.savefig("loss_curve.png")

曲线怎么判读?正常情况是 train 和 val 的 box_loss 同步下降,最后趋于平稳。如果 train loss 一直降、val loss 在某个 epoch 后回升,就是过拟合,解决方法是增大训练集、加数据增强或提前早停。如果两条线从头到尾都在高位震荡,那大概率不是模型问题,而是标注污染——比如 txt 里的框和图片内容对不上,第一步应该回到第 3 章的验收检查脚本重新查一遍标注,而不是调学习率。dfl_loss 是分布焦点损失,解释性不强,我习惯只看 box_loss 和 cls_loss 两条主曲线。

5. 煤堆大块煤识别的四个常见问题排查:叠压、粉尘、标注污染与亮度不均

这个章节专门总结我在煤堆识别场景里踩过的高频坑。前四个是数据侧的坑,第五个是训练参数侧的坑,每个都按现象、原因、解决三部分写,方便你对照排查。

5.1 叠压煤块被模型合并成一个框,堆底目标直接漏检

现象:训练完的模型在算法评测里 mAP 很高,放到实际煤流视频里,遇到四五块煤叠压在一起的画面,模型只输出一个大框,把整堆煤当成一块,底层的煤块全漏了,召回率不够。

原因有两层。第一层是标注习惯问题:用 LabelImg 画框时,标注人员看到两块煤重叠,习惯性地用一个大框把重叠区域全部包进去,模型学到的是一个“煤块堆”的形态,而不是单块煤的边界。第二层是数据增强问题:Ultralytics 默认开启 mosaic 增强,把四张图拼成一张,叠压场景被进一步混合,边界更模糊。

解决:标注规范里明确规定“只标可见煤块的可见轮廓,重叠部分按最外层煤块边缘切分;被完全遮挡的煤块不标”。如果你用的工具支持多边形,比如 Labelme 或 X-AnyLabeling,对叠压区域先画多边形再转矩形框,能保留更多边界信息。训练侧把imgsz从 640 提到 960,小目标优化最直接的手段就是提高输入分辨率,代价是训练时间多 50% 左右。叠压是煤堆场景的常态,不要把“框住整堆”当成正确标注,宁可少标,也不要标成大框。

5.2 低照度和粉尘导致现场漏检,训练集里却完全看不出来

现象:白天顺光拍摄的验证集上 mAP 在 0.95 以上,一到夜班或井下低照度环境,检测率掉到 70%,粉尘弥漫的画面基本全漏。

原因:采集现场图片时大多选光线好的时段,低照度、逆光、扬尘的样本占比太少。YOLOv11 默认的数据增强里也有亮度扰动,但幅度有限,覆盖不了煤矿这种极端光照差异。另一个容易被忽略的点是摄像头类型:如果现场用可见光相机在夜间补光不足,任何算法都救不了。

解决:采集阶段主动补数据,夜班、逆光、扬尘时段各抽几十帧进训练集,不需要单独标新类别,按同一个 large_coal 类标框即可。训练阶段调低hsv_v和degrees之外,还可以在离线层面对低照度图做 gamma 校正,把暗部提亮生成增强副本:

import cv2 import numpy as np def gamma_augment(img_path, out_path, gamma=0.6): """ gamma < 1 时提亮暗部,模拟夜视增强效果 """ img = cv2.imread(img_path) # 查表法做 gamma 变换,避免逐像素计算过慢 table = np.array([((i / 255.0) ** gamma) * 255 for i in range(256)]).astype("uint8") bright_img = cv2.LUT(img, table) cv2.imwrite(out_path, bright_img)

低照度场景更实用的方案是把现场的相机切到红外补光模式,模型在灰度图上做检测比在昏暗彩色图上稳定得多。数据层面再怎么增强,也赶不上输入源质量提升来得直接。

5.3 验证集 mAP 虚高,一到新视频就乱报

现象:train 和 val 的 mAP50 都到了 0.98,训练曲线漂亮,结果换一段没见过的皮带视频直接翻车,到处误报,甚至把皮带托辊当煤块框出来。

原因:数据划分时随机 shuffle 了文件名,导致同一段视频抽帧出来的连续图片同时落进训练集和验证集。两张图只差 0.2 秒,画面几乎一样,验证集等于在考试时偷看了答案,mAP 自然虚高。这是煤堆识别项目里最容易出现、也最容易被忽视的坑。

解决:按视频片段分组切分。采集时给每个视频片段编号,比如site1_20240110_001_0001.jpg,切分时以site1_20240110_001作为分组单位,整个组的图片要么全进 train 要么全进 val。写切分脚本时用组 ID 做键,不做逐文件名随机采样。另外,验证集里加 10% 左右的纯背景帧,也就是没有煤块的皮带空转画面,能有效压低误报率。负样本不需要标注,放到 images/val 里不配 txt 即可,如果验证集负样本太多导致 mAP 整体偏低,那反而说明模型确实要压一下误报。

5.4 图片和 txt 文件名不同步,训练时默默丢掉一批图

现象:训练日志里显示train: 1414 images, val: 353 images,但训完发现 val 里实际有效标注文件只有 300 个,另外 53 张图没有对应 txt,被当成了背景图。

原因:现场图片从相机导出时常有大小写后缀混用问题,比如有的叫IMG_001.jpg、有的叫IMG_001.JPG,在 Linux 服务器上这是两个文件名,而标注工具生成的 txt 只匹配了小写后缀。还有一种情况是图片在拷贝过程中被重命名,txt 没跟上。

解决:训练前跑一个文件名比对脚本:

# 检查 labels 目录里是否缺少和 images 对应的 txt for img in images/val/*.jpg images/val/*.JPG; do base=$(basename "$img" | sed 's/\.[Jj][Pp][Gg]$//') if [ ! -f "labels/val/$base.txt" ]; then echo "缺少标注文件: $img" fi done

这段脚本遍历 val 目录里的所有 jpg,把后缀剥离后去 labels 里找同名 txt,找不到就打印出来。全数据集跑完,把列出的缺文件图片要么重新补标,要么直接从数据集中移出。实际操作中,我经常在 windows 上标注、在 Linux 服务器上训练,建议标注完统一用脚本把所有图片后缀改成小写 jpg,再统一生成 txt,避免大小写问题在整个流程里反复出现。

6. 把模型接到皮带现场:用 yolo predict 保存推理结果并做两组验证

模型训练完,别急着上生产线,先用推理命令保存一批带框结果,用肉眼检查框的贴合度和置信度分布,这一步能帮你避免把没调好的模型直接暴露在真实煤流里。

6.1 用 yolo predict 保存推理结果,并输出 txt 标注

yolo detect predict \ model=runs/detect/train/weights/best.pt \ source=现场视频抽帧目录 \ conf=0.35 \ save=True \ save_txt=True \ project=runs/predict \ name=coal_test

save=True会把带检测框的图片保存到runs/predict/coal_test目录,save_txt=True会额外输出一份 YOLO 格式的 txt 推理结果,方便你用脚本统计误报率。conf=0.35是置信度阈值,煤堆识别场景里我建议先用 0.35 跑一遍看结果,再降到 0.15 对比一次,误报的增加数量如果超过漏检的减少数量,说明模型还没到可部署状态,回第 4 章重新调参。

6.2 两组贴近现场的验证:换时段视频和连续 30 秒断帧检查

第一组验证:换一段没有参与训练的视频,分别取白天、夜班、扬尘三个时段的帧各 30 张,跑完推理后计算漏检率。如果夜班帧漏检严重,按第 5.2 的解法补数据或调增亮参数。第二组验证:用一段连续 30 秒的视频跑实时推理,逐帧统计“有煤块但连续 5 帧以上没报警”的次数。因为皮带是连续运行的,真正的报警逻辑应该是连续帧都检出才触发,单帧偶发漏检问题不大,但如果连续很多帧消失,说明模型在该时段稳定失效,这种问题依靠调 conf 救不回来。

6.3 别只看框准不准,还要看现场报警口够不够快

我现在的习惯是:每次交付煤堆识别模型前,一定存一批真实视频帧跑逐帧推理,把漏检连续帧数和误报率一起写进验收报告,而不是只报一个 mAP。报警联动是最后一道保险,模型输出要经过一个简单的帧计数逻辑,比如连续检出 3 帧才触发报警,能过滤掉大部分单帧误报,煤堆识别才有实际部署价值。这套流程从标注格式到训练验证走一遍,1767 张图带来的模型基本能稳定工作。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询