简介:面向电力场景红外图像的输电线路绝缘子检测,提供1846个样本的Pascal VOC与YOLO双格式标注,适用于计算机视觉目标检测模型的训练、验证与算法对比。样本统一使用labelImg绘制矩形边界框,标注类别为insulator,共计5318个标注框,覆盖变电站等典型电力场景,便于开展红外场景下的细粒度检测研究。
压缩包共2000个文件,以xml标注文件和txt标签文件为主要类型,整体大小约67.78MB,同时附带使用前必读说明。需要留意的是,部分图片由增强手段生成,下载前请结合实际需求甄别;数据集仅保证标注准确合理,不对训练模型精度作任何承诺。
目前已有771人浏览学习,适合电力巡检、无人机巡检等方向的研究者与开发者,用于快速获取规范化的绝缘子检测基准数据,支撑模型微调与实验分析。
1. 拿到这份1846张的红外绝缘子数据集,先别急着训YOLO
一条220kV线路挂几万串绝缘子,靠人眼盯热像图找温升异常,效率低还容易漏。把“红外图像+输电线路绝缘子检测”直接做成目标检测任务,正是这份数据集在做的事:1846张红外图片,单一类别,同时给出VOC和YOLO两种标注格式。VOC方便做标注复核与可视化,YOLO格式解压后能直接喂给YOLOv8、YOLOv5这类训练管线。适合谁?电力巡检算法的入门者、要做毕业设计复现YOLO训练流程的学生、以及想验证红外检测方案能不能落在现场设备的工程师。它最有价值的地方不是“1846张”这个数字,而是让你在动手之前先把数据格式、红外图像特性和训练验证流程想清楚,少走一段弯路。
2. 拆开.7z看家底:VOC与YOLO两种标注格式怎么对齐
拿到以.7z结尾的压缩包,第一步不是急着解压,而是先理解这份数据集为什么要同时提供两种格式。常见做法是:图片同一批,但标注分别放在Annotations/*.xml和labels/*.txt两个体系里。VOC(Pascal VOC)格式面向人工标注与通用检测框架,YOLO格式面向Darknet/YOLO系列的原生训练流程。两种格式表达的是同一批目标,只是坐标体系不同。搞懂它们的换算关系,你才能放心地在两种格式之间来回切换,不会在写脚本时把坐标算错。
2.1 目录结构与命名约定:决定训练脚本怎么写
典型的VOC目录长这样:JPEGImages/放原始图像,Annotations/放同名XML标注,ImageSets/Main/里的train.txt、val.txt记录训练与验证图片名。YOLO目录则是images/train/、images/val/放图片,labels/train/、labels/val/放同名txt标注。这份数据集的1846张图如果是单类别,那么txt里所有标注的目标类别id都是0,对应yaml配置里的names下标。
两种格式的对比如下:
| 项目 | VOC(Pascal VOC) | YOLO(Darknet/YOLOv8) |
|---|---|---|
| 标注文件 | Annotations/*.xml | labels/*.txt |
| 目标描述 | <object>节点,bndbox下的xmin/xmax/ymin/ymax,单位是像素 | 每行一个目标:class_id x_center y_center width height,单位是归一化比例 |
| 类别信息 | XML里的<name>存类别名 | 通过names列表顺序映射为整数id |
| 训练/验证划分 | ImageSets/Main/train.txt、val.txt | 按images/train与images/val目录区分 |
命名约定容易踩坑的点在于文件名一致性。YOLO训练脚本会拿图片名去labels目录里找同名txt,图片是IMG_0142.jpg,标注就必须是IMG_0142.txt。大小写、扩展名、_和-混用,都会导致对应关系断裂。解压后先抽十张图核对命名,这是最便宜的一次体检。
2.2 XML坐标换算成归一化txt:脚本与四个边界条件
如果你拿到的压缩包里只有VOC格式,或者你想把别人的VOC数据集转成YOLO,最稳妥的办法是自己写一个转换脚本。下面这段用的是Python标准库xml.etree.ElementTree,不依赖标注工具,适合批量处理。
# convert_voc_to_yolo.py import xml.etree.ElementTree as ET from pathlib import Path def convert_annotation(xml_path: Path, class_names: list, out_txt: Path): tree = ET.parse(xml_path) root = tree.getroot() size = root.find("size") w = int(size.find("width").text) h = int(size.find("height").text) lines = [] for obj in root.iter("object"): name = obj.find("name").text if name not in class_names: continue class_id = class_names.index(name) box = obj.find("bndbox") xmin = float(box.find("xmin").text) ymin = float(box.find("ymin").text) xmax = float(box.find("xmax").text) ymax = float(box.find("ymax").text) # 四个边界检查:坐标可能越界,先做裁剪再归一化 xmin = max(0.0, min(xmin, w)) xmax = max(0.0, min(xmax, w)) ymin = max(0.0, min(ymin, h)) ymax = max(0.0, min(ymax, h)) if xmax <= xmin or ymax <= ymin: continue x_center = (xmin + xmax) / 2.0 / w y_center = (ymin + ymax) / 2.0 / h box_w = (xmax - xmin) / w box_h = (ymax - ymin) / h # 归一化后理论上应在 [0,1],越界会直接让YOLO训练报错或忽略目标 if x_center < 0 or y_center < 0 or box_w <= 0 or box_h <= 0: continue lines.append(f"{class_id} {x_center:.6f} {y_center:.6f} {box_w:.6f} {box_h:.6f}") out_txt.write_text("\n".join(lines) + "\n", encoding="utf-8") # 示例:单类别数据集的调用 convert_annotation( Path("Annotations/IMG_0142.xml"), ["insulator"], Path("labels/IMG_0142.txt") )这段脚本的逻辑是把XML里的绝对像素坐标转成归一化中心点坐标。关键在两点:一是类别映射,class_names=["insulator"]决定了绝缘子对应的class_id=0;二是越界裁剪,标注工具偶尔会画出超出图片宽高的框,直接保留会让YOLO在预处理时算出负数或大于1的坐标,轻则警告,重则该标签做增强时生成错乱框。
参数上要注意:out_txt.write_text里的encoding="utf-8"不是可选项。Windows下默认编码可能是GBK,写出的txt带中文路径或注释会乱码。另外round(x_center, 6)的精度足够,不要保留太多小数位,训练脚本读取时按浮点数解析,位数多了只增加文件体积。
2.3 红外图像不是普通灰度图:单通道、测温与伪彩映射
红外图像和可见光图像在训练上有本质差异。大多数巡检用的红外相机输出的是单通道温度矩阵,常见位深是14bit或16bit,导出时可能直接保存为16bit PNG,也可能被设备处理成伪彩三通道图。这份数据集里的红外图如果以灰度/单通道为主,那么模型学习的不是“颜色纹理”,而是“温度分布形成的边缘与区域对比”。绝缘子在白天日光下与背景温差小,图像对比度低,边缘弱;到了夜间或阴天,背景温度低,绝缘子温度相对突出,模型学到的特征迁移性就差。
另一个容易忽略的问题是:三通道训练网络时,如果把单通道灰度图复制三次变成三通道,模型依然能训练,但没有引入额外语义信息。更值得做的是在输入层面统一位深和归一化范围。16bit图的像素值范围是0到65535,8bit图是0到255,混在一起训练会导致YOLO的LetterBox缩放后数值分布不一致,损失函数震荡。我的经验是:先统计所有图像的dtype和最大像素值,再决定用哪种归一化方式。这一步做不好,后面调任何模型参数都是白费。
3. 用YOLOv8在绝缘子数据集上跑通训练:解压、yaml与参数取舍
格式看懂了,接下来就进入“能不能跑起来”的环节。我一般用YOLOv8做这类单类别检测,因为它的数据接口简单,训练日志和可视化齐全,适合先用默认配置跑通,再一步步检查问题。前提是你已经把VOC+思路理清楚,接下来就是把文件放到约定好的目录里,写清楚一个dataset.yaml,然后启动训练。
3.1 解压与目录整理:把双格式归到YOLO的训练路径
先把压缩包解开。Windows下建议装7-Zip,命令行解压可以指定输出目录,避免中文路径把后续脚本搞出编码问题。
7z x 电力场景红外图像输电线路绝缘子检测数据集VOC+YOLO格式1846张1类别.7z -odataset_dir-o后面跟输出目录,注意-o与目录名之间没有空格,这是7-Zip的老规矩。解压后先别动原目录,直接新建一个干净的训练数据目录,把YOLO格式的图片和标签按训练/验证放好。
cd dataset_dir mkdir -p datasets/insulator/images/train mkdir -p datasets/insulator/images/val mkdir -p datasets/insulator/labels/train mkdir -p datasets/insulator/labels/val如果你的压缩包里已经有YOLO/images/train和YOLO/labels/train这种划分,直接用mv或cp移过来即可。没有现成划分时,建议按8:2比例从images里挑出验证集图片,再同步把同名标签放进labels/val。划分离散程度很关键,后面第6章会展开讲为什么不建议纯随机划分。这里你要记住一个原则:标签和图片必须严格同名,否则训练脚本会跳过那些“没有标签”的图片,且只在日志里打一行Warning。
3.2 dataset.yaml与训练命令:imgsz、batch、epochs怎么定
目录就绪后,写dataset.yaml。这个文件就是告诉YOLO“数据在哪、有几个类、类名叫什么”。
# insulator.yaml path: ./datasets/insulator train: images/train val: images/val nc: 1 names: 0: insulatorpath推荐用相对路径并配合你运行训练命令的当前目录,这样换机器不用改绝对路径。nc: 1对应单类别,names里0: insulator表示class_id=0叫insulator。如果你的标签txt里写的不是0开头,而是别的数字,训练时直接报“class id out of range”。
训练命令我一般会跑两个对比实验,一个有预训练权重,一个随机初始化:
# 实验1:用COCO上预训练的yolov8n作为起点 yolo detect train \ data=insulator.yaml \ model=yolov8n.pt \ imgsz=640 \ epochs=100 \ batch=16 \ patience=20 \ project=insulator_yolo \ name=s1_imagenet # 实验2:不加载预训练权重,从网络结构初始化 yolo detect train \ data=insulator.yaml \ model=yolov8n.yaml \ imgsz=640 \ epochs=100 \ batch=16 \ project=insulator_yolo \ name=s2_scratch参数取舍上,imgsz=640是YOLO系列默认值,但对输电线路巡检这种场景,绝缘子在原图里常常只占几十个像素,640意味着目标被缩得更小。我一般先用640跑通流程,后续再单独跑一版imgsz=1280对比。batch=16在8GB显存下是安全值,12GB显存可以提到32,但不要为了快把batch拉到爆显存的边缘,训练中途OOM会浪费大量时间。patience=20表示验证集指标连续20个epoch不提升就早停,对单类别数据集通常100个epoch内就能看到收敛曲线走平。
这两个实验对比的意义在于:COCO预训练权重见过大量自然图像纹理,但红外图像的灰度分布和可见光差异极大,预训练带来的“经验”可能是负迁移。YOLO的损失函数里,分类分支和回归分支共同决定梯度方向,随机初始化的模型在前10个epoch收敛慢,但如果50个epoch后两者mAP差距小于5%,说明这个场景下预训练权重提供的帮助有限,后续可以直接用随机初始化方案训练,省去下载和管理预训练权重的麻烦。
3.3 训练结束后先看这四个文件,再决定要不要调参
训练结束以后,别盯着终端里最后那条mAP数字高兴或沮丧,先去看runs/detect/s1/目录下生成的文件。
ls runs/detect/s1/这一目录下会出现PR_curve.png、confusion_matrix.png、labels.jpg、results.csv等可视化结果。我会按顺序看:
labels.jpg里显示的是训练数据的标注分布,包括所有目标框的位置和尺寸。如果这张图里目标框大多集中在图像正中间、尺寸都偏大,说明你的训练数据场景单一,模型很难学会在图像边缘和远处小目标上做检测。PR_curve.png的曲线越接近右上角越好,注意看曲线尾部有没有急剧下落,那说明存在大量低置信度误检。confusion_matrix.png里单类别模型主要看“background”那一行的数字,如果不为0,代表模型把无目标的区域判断成了绝缘子,这在电力巡检现场就是误报。
results.csv是每个epoch的完整指标历史:
head -1 runs/detect/s1/results.csv tail -5 runs/detect/s1/results.csv重点看metrics/mAP50(B)、metrics/mAP50-95(B)、metrics/precision(B)、metrics/recall(B)四列。单类别数据集上mAP50很容易做到0.9以上,那只能说明目标大致找得到;mAP50-95才是定位质量的真镜子,如果它明显偏低,说明预测框和真值框重叠度不高,问题多半出在小目标或边界模糊上,而不是网络结构不行。
4. 训练前自查:标签越界、坏图、重复图与16bit可视化陷阱
很多人在松开训练命令之后才发现数据集有问题,比如loss不降、验证集mAP为0、图片在日志里显示全黑。这些问题不是模型玄学,而是数据进入训练管线之前没做体检。下面这套自查脚本是我每次换新数据集都会先跑一遍的,花五分钟能省下好几个小时的纠错时间。
4.1 五分钟跑一遍数据体检:五类问题一次查完
这段脚本检查五件事:图片能不能被OpenCV正常读取、标签文件是否缺失、标签是否为空、坐标是否越界、图片是否重复。其中重复图最隐蔽,它会把同一张图同时分进训练集和验证集,让验证指标虚高,这就是典型的“数据泄漏”。
# check_dataset.py import cv2 import hashlib from pathlib import Path img_dir = Path("datasets/insulator/images/train") label_dir = Path("datasets/insulator/labels/train") report = {"坏图": [], "缺标签": [], "空标签": [], "越界坐标": [], "重复图": []} seen_md5 = {} for img_p in sorted(img_dir.glob("*.jpg")): # 检查1:图片能否被OpenCV解码 img = cv2.imread(str(img_p)) if img is None: report["坏图"].append(str(img_p)) continue h, w = img.shape[:2] # 检查2:标签是否存在 txt_p = label_dir / (img_p.stem + ".txt") if not txt_p.exists(): report["缺标签"].append(str(img_p)) continue # 检查3:标签是否为空 lines = txt_p.read_text(encoding="utf-8").strip().splitlines() if not lines: report["空标签"].append(str(img_p)) continue # 检查4:坐标是否在[0,1]范围内 for line in lines: parts = line.split() if len(parts) != 5: report["越界坐标"].append(f"{txt_p.name}: {line}") continue _, xc, yc, bw, bh = parts xc, yc, bw, bh = map(float, (xc, yc, bw, bh)) if not (0 <= xc <= 1 and 0 <= yc <= 1 and 0 < bw <= 1 and 0 < bh <= 1): report["越界坐标"].append(f"{txt_p.name}: {line}") # 检查5:文件md5是否重复 md5 = hashlib.md5(img_p.read_bytes()).hexdigest() if md5 in seen_md5: report["重复图"].append(f"{img_p.name} 与 {seen_md5[md5]} 重复") else: seen_md5[md5] = str(img_p) for key, items in report.items(): print(f"{key}: {len(items)}") for it in items[:5]: print(" ", it)脚本里用cv2.imread返回None来判断坏图,比检查文件后缀可靠得多。OpenCV默认按8bit读图,如果图片本身是16bit PNG,imread不会返回None,但读进来会变成一张全黑的8bit图,这种图没法靠这一个脚本查出来,需要配合4.2节的可视化检查。坐标越界的判断条件0 <= xc <= 1是针对归一化坐标的,如果有人给你的是像素坐标,先做xc / w再判断,别直接把像素值和1比较。
重复图的md5查重有个性能问题:read_bytes()会反复读整个文件,1846张图大约几十MB到几百MB,问题不大。但如果之后你的自建数据集到了几万张,建议先按文件大小粗筛一遍再算md5,否则脚本时间会明显拉长。
4.2 16bit红外图“全黑”不是坏了:位深与显示逻辑
红外相机直接导出的图,很多是14bit或16bit单通道。这种图用系统自带的看图器打开往往显示一片漆黑,用微信传一遍再保存还可能被强制转成8bit,丢掉大量温度细节。第一次接触红外数据的人很容易误判“数据集损坏了”,其实只是位深和显示范围不匹配。
在Python里查看位深要用IMREAD_ANYDEPTH:
import cv2 import numpy as np # 按原始位深读取,不转8bit img = cv2.imread("IMG_0142.png", cv2.IMREAD_ANYDEPTH) print(img.dtype, img.shape, img.max()) # 16bit图做线性拉伸后显示 if img.dtype == np.uint16 or img.max() > 255: vis = cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U) cv2.imwrite("IMG_0142_vis.png", vis)img.max()输出65535这一类数值时,说明原始图是16bit,需要归一化后才能正常显示。cv2.normalize里的NORM_MINMAX会把这个通道的最大值映射到255、最小值映射到0,这只是给人看的可视化,不是给模型训练用的预处理。模型训练时的归一化应该在dataset.yaml或数据加载器里统一做,别依赖这种临时拉伸。
可视化还有一个细节:红外伪彩图是三通道,但伪彩映射的关系是固定的,直接喂给YOLO也能学,只是换一台相机或换一套调色板之后,颜色分布变了,模型表现就会掉。更推荐的做法是统一转成灰度单通道或统一映射到同一个伪彩标准,让模型学到的是温度分布模式,而不是某一种颜色风格。
5. 绝缘子检测常见问题排查:红外场景里的4个典型坑
这一章把我在红外绝缘子检测上遇到过、也常在开源社区里看到的问题整理成排查记录。每一条都按“现象→原因→解决”的顺序写,方便你对照自己的训练日志和可视化结果。
5.1 损失很低mAP却上不去:单类别收敛的假象
现象:训练日志里box_loss和cls_loss都降得很低,总损失看起来已经收敛,但验证集mAP50只有0.3左右,PR曲线也很差。
原因:单类别数据集的分类分支太容易学了。模型只要学会“有目标就输出一类”,分类损失就会很低,但回归分支如果没把框位置学准,mAP就是上不去。另一种常见原因是训练集里混了大量没有目标的背景图,模型学会的是“这一整批图绝大多数是背景,直接输出空检测也能让损失平稳”,典型的类别不平衡。
解决:先用命令统计空标签图和每张图的目标数量分布。
find labels/train -name "*.txt" -size 0 | wc -l wc -l labels/train/*.txt | sort -n | tail -10第一条输出空标签文件数,第二条看单张图最多有多少个目标。空标签文件占训练集比例超过30%,就要考虑把它单独放到负样本集或直接剔除。如果绝大多数图只有1到2个目标,而个别图有20个以上目标,训练时马赛克增强会把这些密集样本切碎,导致小目标被丢弃。遇到这种情况,可以调整Mosaic和Copy-Paste增强的开关,或者使用.yaml里的augment参数单独调mosaic和scale。最后,检查回归损失权重,YOLOv8的损失函数里回归部分用的是CIoU和DFL,如果分类分支过于强势,可以考虑在超参配置里调低cls权重,具体数值要看你用的版本,但思路是让模型把更多梯度放到框的回归上。
5.2 训练读取全是黑图:位深不一致
现象:训练日志里能看到数据集图片数量正常,loss也在下降,但可视化train_batch图片时,所有输入图都是黑的,模型等于在学一张纯黑图上随机出现的框。
原因:上游数据处理时用了cv2.imread默认8bit读取,16bit图被截断成了全黑。更隐蔽的是混合数据集,一部分图是8bit,另一部分是16bit,前者正常后者全黑,模型被迫在这种“忽明忽暗”的输入上找规律。
解决:在数据集落地第一步就统一位深和归一化范围。先扫描所有图片的dtype和max()值,如果存在16bit图,全部转成8bit并做线性拉伸后另存到一个新目录,再进训练流程。注意不要覆盖原始文件,红外图的温度信息只在原始位深里保存得最完整。转8bit只是为了训练输入和可视化的一致性。这个过程和两点校正配合会更稳,具体做法在第6章展开。
5.3 小尺寸绝缘子漏检:imgsz与切图的选择
现象:大尺寸绝缘子检测得很好,但图像远端、小尺寸的绝缘子几乎全漏,mAP50-95比mAP50低一大截。
原因:原图上绝缘子可能只有30×30像素,缩放到640×640之后只剩不到5×5像素,特征图上的响应非常弱。YOLO系列对小目标的召回原本就不是强项,靠单尺度训练很难救回来。
解决:优先把imgsz提高到1280或1536再训练一轮。代价是显存占用和训练时间明显上涨,8GB显存下batch要降到4或8,但mAP50-95往往能提升5到10个点。如果提分辨率后显存撑不住,就用切图推理(SAHI思路):推理时把原图切成若干重叠块分别检测,再把框映射回原图坐标。注意切图的块大小和重叠率要跟你训练时的imgsz一致,否则目标被截断会导致置信度暴跌。
5.4 灰度漂移导致现场失效:先校正再做域适配
现象:在训练集验证集上mAP都挺好,一到现场新拍的另外一批红外图就明显变差,尤其是不同时间段、不同环境温度下拍的图。
原因:红外相机的输出受自动增益、测温量程和环境温度影响。同一片绝缘子,中午拍出来的灰度分布和凌晨拍出来差别很大。模型如果学到的是“这个灰度范围是绝缘子”,而不是“这个温度分布是绝缘子”,场景一换就失效。这就是红外图像两点校正要解决的核心问题。
解决:在数据进模型之前,先对红外图做两点校正,或者至少做基于固定参考体的线性归一化。两点校正的做法是采集低温参考和高温参考两个点,把所有灰度映射到统一范围。如果数据集里没有提供黑体和快门数据,退而求其次,用整张图的固定分位数做归一化,比如把1%和99%分位数映射到0和255,效果比简单min-max更抗噪。之后再考虑用自建补集做域适配,把现场实际拍摄的一小批图加进去微调。
6. 往现场走:把两点校正与自建补集变成训练流程的一部分
模型在数据集上跑出一个好看的mAP,距离“现场能用”还差最后一段路。这一段路主要是把输入数据的风格统一起来,再补一些现场工况数据做微调。我现在的流程中,这两步比反复换网络结构更能稳定落地效果。
6.1 红外图像两点校正的快速实现
两点校正的基本公式是把原始灰度经过两个参考点映射到目标范围。假设低温参考输出为dark,高温参考输出为hot,归一化后的灰度计算方式如下。
import numpy as np def two_point_correction(raw: np.ndarray, dark: float, hot: float) -> np.ndarray: # raw: 16bit原始灰度图,dark/hot: 两个参考点对应的灰度值 norm = (raw.astype(np.float32) - dark) / (hot - dark) norm = np.clip(norm, 0.0, 1.0) return (norm * 255.0).astype(np.uint8)dark和hot在不同设备上叫法不同,有的叫“快门校正”,有的叫“黑体标定”,本质都是给灰度映射找两个固定锚点。没有标定数据时,我就用np.percentile(raw, 1)和np.percentile(raw, 99)代替dark与hot。注意用分位数而不是min/max,因为红外图里常有点状高温噪点,min-max会把整体亮度压暗。做完整套数据校正后,训练和验证集必须用同一套参数。
6.2 按场景划分补集与增量训练
自建补集不需要一开始就标几千张。我的三步做法是:第一步,从现场不同时间段、不同天气、不同线路各抽几十帧,总共凑200到300张;第二步,用当前模型跑一遍推理,把置信度高的结果自动生成预标注,人工只复核那些低置信度的目标;第三步,把这批数据按场景分组加入训练集,用低学习率微调,lr0设在0.0001到0.0005之间,避免旧数据被冲掉。关键在划分方式:同一时间段连续拍的帧画面高度相似,如果随机按单帧划分训练和验证,验证集会包含大量与训练集几乎相同的帧,指标虚高,现场却撑不住。要按“场景组”划分,比如按拍摄日期或线路段分组,一组要么全在训练集,要么全在验证集。
6.3 在单类别红外数据上,评估指标这样看
单类别任务最迷惑人的地方就是mAP数字好看。建议最终评估看这四个指标:
| 指标 | 含义 | 在电力巡检里的判断 |
|---|---|---|
| mAP50 | 粗略定位能力 | 低于0.8说明基本不可用 |
| mAP50-95 | 框的精度与稳定性 | 与mAP50差距大同小目标定位弱 |
| F1 | 精确率与召回率的均衡 | 单类别场景下比mAP更直观 |
| 误报数/千帧 | 现场报警疲劳的直接来源 | 平均每千帧误报超过10次就要压阈值 |
最少画一条P-R曲线看阈值怎么定。红外绝缘子现场最常见的矛盾是:阈值调高,漏报增多,风险大;阈值调低,误报增多,运维人员很快就不信系统。最终阈值建议把召回率放在优先位,绝缘子漏检的代价通常高于几次无效报警。
我最早自己做红外绝缘子检测时,没做位深自查,把16bit图直接扔进脚本跑了一天,loss曲线很正常,后来把训练batch图导出来才发现模型看到的基本是全黑图。损失函数照样能降,模型学到的只是背景模式,从那时起,数据落地第一步永远是格式校验和位深检查。这套流程坚持下来,省下的返工时间远超过多写的那些脚本。希望帮到你。
本文还有配套的精品资源,点击获取