1. 先说清楚:图像去雾到底在解决什么问题
做图像去雾的朋友应该都有印象,第一次跑出一张去雾后的图,那种“雾被擦掉一层”的直观冲击感确实挺爽。但真要把它当研究方向或者工程需求来做,第一步不是调模型,而是先搞清楚:我到底需要什么样的数据来训练和验证算法。
图像去雾,通俗点说,就是把带雾图像里的雾霾、薄雾、浓雾造成的不清晰和偏色问题处理掉,恢复出清晰的场景内容。对应的数据集就是用来训练和评估这类算法的图像集合,一般由成对的清晰图和带雾图组成,也有部分只提供真实雾图用于做无参考评估。
这类数据集适合谁用?范围其实很广。刚入门做毕业设计的学生,想用现成数据跑通一个去雾模型;做安防监控、自动驾驶感知的工程师,想通过去雾增强图像质量;还有做遥感影像、无人机巡检的朋友,也需要对雾天图像做预处理。可以说,只要你的视觉系统会在户外场景工作,图像去雾数据集就是你绕不开的练习场和试验田。
这篇文章我准备把市面上真正常见、能下到、口碑还不错的图像去雾数据集整理成一份带实操经验的使用指南,内容包括每个数据集的来源、结构、适用场景、怎么用、有哪些坑,以及我在实际训练过程中踩过的那些哭笑不得的雷。如果你正打算做去雾方向,或者只是需要一批雾图数据来凑实验,建议直接收藏这份。
2. 图像去雾数据集的整体分类逻辑
2.1 合成数据 vs 真实数据,各有什么优劣
先把顶层逻辑理清楚。目前图像去雾领域的数据集大体分两类:合成数据集和真实数据集。
合成数据集,简单说就是用干净的清晰图,配合深度信息或者人工生成的大气光、透射率,通过大气散射模型叠加出带雾效果。这类数据的最大优势是干净、可控、有成对标签,模型训练时能直接算像素级损失,方便对比还原效果。缺点也很明显,因为它本质上是模拟出来的雾,跟真实世界的雾在物理细节上多少存在偏差,模型在合成数据上练得好,跑到真实雾图上时常出现“水土不服”。
真实数据集,则是直接在真实雾天环境里采集到的带雾图像。这类数据真实感强,验证模型能力更有说服力,但最大难点是缺少对应的清晰参考图,没法做严格的定量评估,只能靠人眼或者无参考评价指标来打分。
我给新人的建议是:不要盲目追求真实数据,也不要迷信合成数据。做训练首选合成数据集,因为收敛快、评估方便;做最终效果验证一定留一批真实雾图,哪怕只有几十张,也能看出模型在实战中的真本事。两条腿走路,才不会在论文或者项目汇报时被质疑。
2.2 常用数据集的三个维度对比维度
挑数据集时,我习惯从三个维度去判断它适不适合自己的场景,简单列个参照:
第一,雾的浓度覆盖范围。有的数据集以薄雾为主,有的包含从薄雾到重雾甚至浓雾的连续变化。如果你的场景是高速公路上的遇到的重雾天气,只拿薄雾数据训练出来的模型肯定不扛事。
第二,场景内容多样性。城市街道、乡村道路、室内室外、行人车辆、建筑物、自然景观,不同场景的成像特性差异很大。数据集覆盖的场景越广,训练出的模型泛化能力越强,越不容易过拟合到某一类纹理上。
第三,数据规模和标签形式。有些数据集只有几十张,适合做测试不适合做训练;有些上千张,附带透射率图、深度图等额外标注,能够支持更复杂的模型设计,比如单独预测透射率的分支结构。
我整理了一张常见数据集速览表,方便大家快速定位:
| 数据集名称 | 类型 | 图像规模(约) | 是否成对标签 | 主要特点 |
|---|---|---|---|---|
| RESIDE | 合成+真实 | 数万张 | 是 | 规模大、场景全,最常用 |
| OTS | 合成 | 72135张 | 是 | RESIDE的子集,适合大规模训练 |
| ITS | 合成 | 13990张 | 是 | 室内场景,雾浓度梯度大 |
| SOTS | 合成 | 500张测试 | 是 | 室内+室外,公平评测基准 |
| Dense-Haze | 真实 | 54对 | 是 | 浓雾场景,挑战性高 |
| NH-HAZE | 真实 | 45对 | 是 | 非均匀雾,贴近实际 |
| O-HAZE | 真实 | 45对 | 是 | 室外真实雾,测色彩还原 |
| RESIDE-6K | 合成 | 6000张 | 是 | 轻量版,快速实验用 |
这些数据集大多能公开获取,下面我会挑最重要的几个重点展开讲解它们的内部结构和实际使用方式。
3. 主流合成去雾数据集逐个拆解
3.1 RESIDE 系列:绕不开的“标准答案”
如果你去搜图像去雾相关的论文,百分之八十以上的训练和测试都在RESIDE数据集上进行。这不是情怀,而是它确实做得比较全面。RESIDE数据集由北京大学等机构发布,全称是REalistic Single Image DEhazing,目前常见的有RESIDE、RESIDE-Standard和RESIDE-β等版本。
RESIDE的核心设计逻辑是用NYU Depth Dataset里面的室内场景深度图和室外场景深度图,通过大气散射模型自动合成带雾图像。大气散射模型公式很简单,直观理解就是:雾天的图像等于场景辐射经过衰减再加上大气光的散射影响,公式里的t(x)就是透射率图,A是全局大气光值。合成时,通过随机设定大气光A和透射率t的数值范围,就能控制雾浓雾淡和色调偏移。
实操中我主要使用的是RESIDE的Standard版,也就是常说的RESIDE-Standard。它的训练集包含两部分:室内训练集ITS有13990张合成雾图,室外训练集OTS则有72135张合成雾图。测试集SOTS包含室内和室外各500张,这部分数据专门用来做公平对比,很多论文里的PSNR和SSIM指标就是在SOTS上算出来的。
再提一个快速迭代的轻量版本叫做RESIDE-6K,它从RESIDE里挑了6000张图作为精简训练集。如果你只是想验证一个网络结构的可行性,或者显卡资源有限,我强烈建议先用RESIDE-6K跑通全流程,而不是一开始就上几万张图,不然光等训练就够喝一壶了。
3.2 ITS 和 OTS 的内部结构差异
很多人分不清ITS和OTS,其实就是一句话的问题:ITS是Indoor Training Set,室内训练集;OTS是Outdoor Training Set,室外训练集。
ITS的数据来源是NYU Depth V2数据集,选了室内场景下的清晰图像和对应深度图,再合成不同浓度的雾。所以ITS里面的场景大多是卧室、客厅、书房这类室内空间,物体的边缘轮廓比较规则,景深变化相对平缓。如果你做的是室内监控图像增强,ITS就很合适。
OTS的数据来源更丰富,主要是从网上收集的室外自然图像,再配上估计的深度信息来合成雾图。室外场景包含街道、建筑、树木、人物、车辆等,纹理更复杂,光照变化也更剧烈,训练出来的模型抗干扰能力更强。但我提醒一句,OTS里的图像比较大,原图尺寸五花八门,使用前最好统一resize成固定尺寸,不然训练时batch组成容易出问题。
我自己常用的做法是:先用ITS做小规模预实验,把模型调通,再用OTS做正式训练,最后在SOTS测试集上验证。这样既能快速迭代,又能保证最终模型见过足够多样化的场景。
3.3 SOTS 测试集为什么被称为“公平擂台”
做图像去雾研究的人心里都清楚,模型好不好,不能光看自己训练集上的损失降得有多低,关键是换一批没见过得数据还能不能打。SOTS就成了一个公认的“擂台”。
SOTS测试集来自RESIDE-Standard,包含500张室内合成雾图和500张室外合成雾图,雾浓度同样是多梯度覆盖。由于它是独立于训练集的,你在ITS或者OTS上训练出来的模型,拿到SOTS上测试,得到的结果才是可比较、可写进论文的数字。
使用SOTS时有个细节要注意:下载后你会发现它既提供了带雾图,也提供了对应的清晰参考图,并且有透射率图。做定量指标计算时,标准做法是将去雾网络输出的图像和清晰参考图计算PSNR和SSIM。如果你的模型是端到端的图像到图像映射,这操作没问题;但如果你设计了中间透射率预测分支,同时也要给reference透射率图做监督,这样SOTS的透射率图就能派上用场,别当摆设浪费了。
另外提醒一句,SOTS测试集文件命名里有hazy和gt两个目录,很多人一开始会忽略gt部分。要是你只拿了hazy目录去跑测试,又没清晰图做对比,那只能做定性展示,无法形成定量结论,很多审稿人最烦这个,直接拒稿。
4. 真实雾天数据集:硬骨头与稀缺资源
4.1 Dense-Haze:浓雾场景下的极限压力测试
真实世界里的雾不总是一层薄薄的纱,很多时候是白茫茫一片,能见度可能不足几米。这种情况下,几乎所有去雾模型都会表现得不尽如人意。Dense-Haze数据集就是为了专门考察模型在这种极端浓雾下的恢复能力而发布的。
Dense-Haze由爱尔兰都柏林城市大学等机构发布,包含33对真实的室外浓雾图像,是的,只有33对。这个数量放在深度学习领域简直少得可怜,但每张图都对应一张同一场景在无雾天气拍摄的清晰图,这是它最珍贵的地方。因为要在真实环境下等来雾天,还得保证相机位置和参数完全不变地再拍一次清晰图,采集难度和工作量都非常之大。
实际使用中,Dense-Haze很难用来训练模型,数据量太小,强行训练很容易严重过拟合。它真正的价值是作为测试集,用来检验你的模型在浓雾环境下的极限表现。我记得第一次用训练好的模型测试Dense-Haze时,输出结果仍然残留了大量白蒙蒙的色块,边缘也发灰,那一刻才意识到合成的薄雾数据和真实重雾之间的鸿沟有多大。
如果你有需要用Dense-Haze做测试,我建议同时关注主观视觉和客观指标。主观上可以看看能否恢复出高对比度的纹理细节;客观指标可以用PSNR和SSIM,但这两个指标在浓雾场景下的分值普遍偏低,不同模型间的差距也会被压缩,这时候不妨多看看LPIPS这类感知相似度指标,更能反映人眼感受。
4.2 NH-HAZE 与 O-HAZE:非均匀雾和自然场景的真实考验
NH-HAZE数据集的全称是Natural Haze,主打的是非均匀雾。真实世界里,雾气分布极少是完全均匀的,有的区域浓、有的区域淡,有的物体在雾的遮蔽下完全看不清,有的则依然保有清晰轮廓。NH-HAZE正是在这种条件下采集了45对真实场景图像,包括城市环境、自然景观等。
O-HAZE和NH-HAZE是同一研究团队前后发布的姊妹数据集,O代表Outdoor,采集的是清晰无雾条件下的室外场景和对应有雾天气的成对图像,同样是45对。O-HAZE的场景更加开阔,包含农田、山坡、建筑远景等,雾天条件下整张图像就像蒙了一层半透明毛玻璃。
这两个真实数据集有一个共同点:成对图像数量都很少,不够训练,但非常适合做跨域验证。跨域验证什么意思呢?就是你用RESIDE这种合成数据训练出的模型,不要只在SOTS上自嗨,拿到NH-HAZE和O-HAZE上跑一遍,就能知道模型在真实场景的迁移能力如何。我见过不少模型在SOTS上冲到30dB以上PSNR,到了NH-HAZE上直接掉到18dB左右,落差非常大。这也说明合成数据和真实数据之间的领域鸿沟确实是当前去雾技术的一大客观瓶颈。
另外,真实数据集的“清晰图”也不是绝对意义上的完美,因为户外光照变化、树叶摇动、空气中颗粒物干扰,同一场景两次拍摄之间多少会有细微差异。所以你拿这些真实数据计算指标时,数值上限本来就会受到限制,不必苛求模型把PSNR刷到多高,多看视觉对比图才是更可靠的方式。
4.3 还有一些值得二线关注的真实雾数据集
除了上面几个“大牌”,图像去雾领域还有几个相对小众但很有意思的数据集,抽样做补充实验能增加说服力。
比如Foggy Cityscapes,它是在Cityscapes自动驾驶数据集基础上添加了合成雾的效果,虽然本质上是合成,但模拟的是车载相机视角下的城市街景,场景结构跟实际道路非常接近,跑自动驾驶感知的人用起来很顺手。再比如Frosty Cityscapes,则是模拟霜冻天气对镜头成像的影响,虽然不属于传统雾气问题,但和去雾任务在图像增强上是难兄难弟。
还有SUIM和BAD-GAN生成的水下图像这类数据,它们处理的是水下浑浊介质下的图像降质问题,成像模型跟大气去雾有相似之处,经常被做水下图像增强的同学拿来跟去雾任务做方法对比。总之,真实数据集的丰富程度有限,大家做研究时不必非得一条路走到黑,合理组合多个数据集做互补验证,往往更高效。
5. 怎么正确下载、组织和处理这些数据集
5.1 下载渠道与文件目录结构解析
很多新手卡在第一步:数据集到底去哪里下?我先把几个最常用的通道列出来。
RESIDE系列可以通过官方项目主页或者GitHub搜索RESIDE数据集获取下载链接。但有时候官方链接会失效,或者下载速度慢得令人抓狂。这种时候不妨直接搜“RESIDE dataset download”,一般能找到论文作者在Google Drive或者百度网盘上分享的压缩包。不过百度网盘的链接时常过期,多准备几个备用链接比较稳妥。
Dense-Haze、NH-HAZE、O-HAZE这些数据集一般开放在专门的挑战赛网站或者大学实验室的公开页面上,直接填入邮箱申请即可自动发链接,流程相对顺利。
下载完成后,我习惯先扫描一遍目录结构,不要着急解压就开跑。以RESIDE-Standard为例,典型目录结构大致如下:
RESIDE-Standard/ ├── ITS/ │ ├── hazy/ │ ├── clear/ │ └── depth/ ├── OTS/ │ ├── hazy/ │ ├── clear/ │ └── depth/ └── SOTS/ ├── indoor/ │ ├── hazy/ │ └── clear/ └── outdoor/ ├── hazy/ └── clear/其中hazy目录存合成雾图,clear目录存清晰原图,depth目录是深度图。训练模型时,我们通常让网络输入hazy图并回归clear图,深度图只有在设计某些特定模块时才会用到。搞清楚这些目录的对应关系,后续做数据加载时才能少走弯路。
5.2 数据预处理的关键操作:裁剪、缩放与归一化
图像去雾的数据预处理不能随便套用经典分类任务的流程,有几点格外重要。
第一,图像缩放。原始图像尺寸差距太大,直接输入网络容易导致显存波动,也容易让batch内的图像比例失调。我通常先把长边按比例缩放到固定值,比如长边512或者640,再做随机裁剪到256×256或320×320。对于训练集,随机裁剪天然做了数据增强,能有效增加样本多样性;对于测试集,则保持原图比例直接resize到模型输入尺寸,或者用反射填充补边。
第二,像素归一化。去雾任务和分类任务不同,千万不要直接使用ImageNet的mean和std归一化来做去雾训练。因为去雾本质上要保留原图的绝对亮度和色彩信息,使用均值方差归一化会把图像的全局色调扭曲掉,导致模型学习出现偏差。我通常只将图像像素值从255缩放到[0,1]区间,在网络内部通过卷积层自行学习特征分布。如果你非要用BN层自带的归一化,那没关系,BN是按照batch内数据自动统计的,不影响绝对尺度信息。
第三,成对数据保证对齐。合成数据集里hazy和clear是严格对应关系,但在数据加载时,如果文件顺序对应错了,等于拿着完全无关的两张图做监督学习,模型怎么都收敛不了。我常用的做法是做一个字典,按照文件名base name(不包含扩展名)一一对应读取,生成一个索引表,而不是简单遍历两个目录并假设顺序一致。
5.3 数据加载代码的参考写法
这里放一小段我常用的PyTorch风格数据加载伪代码,方便大家直接参考改造成适合自己工程的形式:
import os from torch.utils.data import Dataset from PIL import Image import torchvision.transforms as T class DehazeDataset(Dataset): def __init__(self, hazy_dir, clear_dir, crop_size=256, train=True): self.hazy_dir = hazy_dir self.clear_dir = clear_dir self.train = train self.crop_size = crop_size self.hazy_names = sorted(os.listdir(hazy_dir)) self.clear_names = sorted(os.listdir(clear_dir)) assert len(self.hazy_names) == len(self.clear_names) def __len__(self): return len(self.hazy_names) def __getitem__(self, idx): hazy_path = os.path.join(self.hazy_dir, self.hazy_names[idx]) clear_path = os.path.join(self.clear_dir, self.clear_names[idx]) hazy = Image.open(hazy_path).convert("RGB") clear = Image.open(clear_path).convert("RGB") if self.train: # 随机裁剪到固定尺寸 i, j, h, w = T.RandomCrop.get_params(hazy, output_size=(self.crop_size, self.crop_size)) hazy = T.functional.crop(hazy, i, j, h, w) clear = T.functional.crop(clear, i, j, h, w) else: # 测试时直接resize到固定尺寸 hazy = T.Resize((self.crop_size, self.crop_size))(hazy) clear = T.Resize((self.crop_size, self.crop_size))(clear) hazy = T.ToTensor()(hazy) # 将像素转为[0,1]范围 clear = T.ToTensor()(clear) return hazy, clear这段代码有几个细节值得注意:一是用sorted保证文件名顺序对齐,不要用原始os.listdir的顺序,因为在某些操作系统上顺序不稳定;二是训练和测试分支分开处理,训练用裁剪,测试用resize;三是PIL读图后转RGB,防止灰度图或者带透明通道的图混进来导致张量形状不一致。实际生产环境里,可能还需要加入多进程num_workers、pin_memory等参数来提升数据加载效率,这块根据显存和CPU资源自行调节即可。
6. 训练与评估去雾模型时的实验设置建议
6.1 训练集/验证集/测试集应该怎么划分
很多刚入门的同学一股脑把所有数据灌进训练,然后在同一批数据的子集上做验证,这是非常危险的。如果只看训练集指标,模型已经“背下”了图像的特征,但在新数据上表现可能一塌糊涂,这就是典型的过拟合。
我建议把数据集划分为三个部分:训练集、验证集、测试集。训练集用来更新网络权重;验证集用来做模型选择,比如决定训练多少epoch、调整学习率、判断是否早停;测试集只在最终评估时使用一次,不参与任何训练决策。
以RESIDE为例,你可以从ITS中抽出一部分作为验证集,剩下的作为训练集,SOTS永远只作为最终测试。比如,从ITS的13990张里随机抽2000张做验证集,其他11990张做训练集,这样每次epoch结束都能在未见过的数据上观察Loss趋势,判断模型的泛化趋势。
对OTS这种上7万张的规模,验证集可以小一些,500到1000张就足够。验证集的分布最好和训练集近似,否则验证过程会掺杂太多噪声干扰判断。
6.2 常用的损失函数与评价指标解读
图像去雾任务的损失函数设计通常不止一个。最常见的做法是L1损失或者L2损失直接约束输出图和清晰图之间的像素差异。L2损失(均方误差)能更大地惩罚大的像素误差,但容易让输出图像过度平滑;L1损失对异常值更鲁棒,图像细节保留得更好。我自己通常优先用L1损失,如果训练后期出现明显的模糊感,再叠加一个感知损失或者结构相似性损失。
感知损失一般用预训练的VGG16或者VGG19提取中间层特征,计算特征图之间的L1或L2距离。它能有效保持高层次语义结构,让恢复出来的图像细节更接近人眼感知。结构相似性损失则直接优化SSIM,在保持亮度、对比度、结构信息方面有一定优势。
评估指标方面,PSNR、SSIM是论文必备。PSNR全称峰值信噪比,数值越高表示图像失真越小,但它在某些场景下跟人眼主观感知不一定完全一致;SSIM则是对亮度、对比度、结构三方面做综合评分,范围在0到1之间,越接近1越好。另外LPIPS逐渐被广泛使用,它利用深度网络特征计算图像感知距离,更符合人眼主观判断。
下面给一张指标速查表,方便实验报告里直接参考:
| 指标名称 | 全称 | 数值范围 | 越高越好还是越低越好 | 适用场景 |
|---|---|---|---|---|
| PSNR | 峰值信噪比 | 理论上无上限 | 越高越好 | 像素级失真评估 |
| SSIM | 结构相似性 | 0~1 | 越高越好 | 结构信息保持评估 |
| LPIPS | 学习感知图像块相似度 | 通常0~1 | 越低越好 | 人眼感知相似度 |
| UQI | 通用质量指标 | 0~1 | 越高越好 | 图像质量综合评价 |
特别提醒一点,论文里如果只报告PSNR和SSIM,而缺失视觉对比图,很容易被审稿人质疑指标无法反映真实视觉效果。因此做实验时一定要保存好输出图像,最后拼图对比时采用相同的裁剪区域和缩放比例,保证对比公平。
6.3 小模型快速迭代的工程技巧
如果你用的是普通消费级显卡,比如RTX 3060或者4060,显存只有8GB左右,直接训练RESIDE-OTS那么大的数据集会非常吃力。这时候有几个实用技巧可以大幅降低资源需求。
第一个技巧是先用低分辨率训练。比如先把图像缩放到256×256训练模型,等损失下降到一定程度后,再用高分辨率比如512×512微调网络。这样做的原理是:低分辨率下的高频细节虽然不足,但整体结构和颜色分布已经能学到,高分辨率微调只需要弥补细节差异,收敛速度快很多。实际测量下来,这个策略比直接高分辨率训练节省差不多一半的显存占用和时间。
第二个技巧是使用混合精度训练。PyTorch的自动混合精度(AMP)默认就能把FP32的权重降低到FP16计算,配合梯度缩放,能在不明显损失精度的情况下减少显存占用并且加速训练。开启方法很简单,使用torch.cuda.amp.autocast上下文包裹前向传播和损失计算,再加上GradScaler对梯度做反向传播即可。我实测在单卡8GB显存上,混合精度大概能多塞进去一倍的batch size。
第三个技巧是使用梯度累积。如果batch size只能设为4,但你想以batch size 16的效果更新参数,可以设置梯度累积步数为4,每4次小batch累积一次梯度,再统一更新权重。这个操作不会额外增加显存,但需要注意batch norm层对batch size比较敏感,过小的batch会带来不稳定的统计量。如果模型里用了BN,建议梯度累积时同步更新BN的running mean。
7. 常见问题与排查技巧实录
7.1 下载的数据文件损坏或解压不完整怎么处理
数据集体积动辄几个GB甚至几十GB,下载过程中断、网络波动导致文件损坏是极常见的事。最常见的表现是解压到一半报错,CRC校验不过;或者训练时突然读到一张打不开的坏图,直接让整个训练进程崩掉。
我在这块吃过不少亏,后来养成了几个习惯:一是下载后先核对文件大小和官方给出的sha256校验值,这样能提前发现压缩包是否完整;二是解压后写一段脚本批量检查所有图片是否能正常用PIL打开,遇到打不开的文件直接移出数据集,避免训练中途报错;三是在数据加载代码里加上异常捕获机制,如果某张图读取失败,就跳过这个样本继续训练,而不是终止整个进程。
如果发现确实有文件损坏,最简单的办法是删掉重新下载对应分卷,不要试图用修复工具硬修,浪费的时间够重下两遍了。
7.2 训练Loss不下降的常见原因
图像去雾任务里,Loss不下降的原因比其他任务更多样,我按踩坑概率从高到低列一下:
第一,数据对齐出错。前面提到hazy和clear顺序没对齐,模型输入输出的监督信号完全错开,训练Loss会一直在高位震荡。排查方法是随机打印几个样本的hazy和clear文件名,确认一一对应。
第二,学习率设置不合理。图像去雾的回归任务对学习率比较敏感,初始学习率设置过大,Loss容易震荡发散;设置过小,则收敛极慢。Transformer类模型常用较小学习率,比如1e-4到5e-5;CNN类网络可以从1e-4到3e-4开始,配合余弦退火或StepLR逐步衰减。如果你用AdamW,别忘了设置适当的weight decay防止过拟合。
第三,归一化层选择不当。如果网络里使用了InstanceNorm或者GroupNorm,对batch size要求相对宽松;如果是BatchNorm,batch size过小会造成统计偏差,影响训练稳定性。建议先用一个较小数据集迭代100个epoch试跑,观察Loss曲线是否有实质下降,再决定是否调整结构。
第四,数据值域不一致。如果你的hazy图被误缩放到[0,1]范围,而clear图仍然在[0,255]范围,Loss值会异常大,看上去像是在下降但实际梯度方向已经是乱跳。养成好习惯,在数据加载代码里打印一下输入张量的min、max值,确认范围一致。
7.3 模型在合成数据上效果好,但真实雾图效果差怎么办
这个问题几乎人人都会遇到,也是目前去雾领域的公认难题。第一个策略是在训练数据里加入少量真实雾图做微调,但真实雾图没有清晰参考,只能用无监督损失,比如暗通道先验损失或者循环一致性损失。现实中这样做能有限改善但不会根本解决。
第二个策略是采用域自适应思路,让网络在学习合成数据的同时,对真实雾图数据的特征分布进行对齐。具体实现复杂一些,需要借助对抗训练或者风格迁移的技巧,对新手来说门槛比较高。
第三个策略是我自己更推荐的实用路线:调整数据增强策略,在合成数据基础上模拟更真实的雾天情况。比如在RESIDE训练时,对hazy图像随机添加高斯噪声、随机调整亮度对比度、随机轻微模糊、随机色彩偏移,这样模型的正规化能力会更强,对真实雾图的适应性也会提升。实测下来,增强过的模型在NH-HAZE上的PSNR能比不增强的高出1到2个dB,效果还是不错的。
另有一个细节:真实雾图的图像分辨率通常更高,如果你在训练时固定使用256×256分辨率,而测试时直接输入2K分辨率原图,网络感受野和图像内容尺度都会变化,性能下降也难免。训练后期用高分辨率数据微调一下,能缓解这个尺度不匹配问题。
8. 图像去雾数据集使用的几点个人体会
做图像去雾这几年,我最大的感受是:数据集选得好不好,基本上决定了你80%的实验节奏。选一个规模过大、标注混乱的数据集,光处理数据就够让人崩溃;选一个规模太小、场景单一的数据集,实验结论又没说服力。所以从一开始就别嫌麻烦,花一两天时间把数据目录理清楚,把加载脚本写扎实,后面能省下无数个加班的夜晚。
对于刚入门的朋友,我建议先跑通RESIDE-6K加上SOTS测试这条最短路径,用一个小型U-Net结构的模型做实验,熟悉数据加载、训练、评估全流程。等流程顺畅了,再逐步引入真实数据集做验证,再进阶到感知损失、域自适应等方法。这条路走通之后,你对图像去雾领域的理解会非常立体,而不只是一知半解地调参。
最后再分享一个小技巧:在做实验记录时,一定要保存一份完整的数据集版本信息、数据预处理代码和随机种子。很多去雾实验表面上看起来一样,但数据加载顺序、裁剪方式、图像缩放算法的微小差异都会对最终结果产生影响。把环境固定下来,你后续的技术复盘和论文复现都会顺利得多。图像去雾数据集不是越新越好,也不是越大越好,找到适配自己问题的数据,比堆砌数量重要得多。希望这篇文章能帮你少踩一些我当年踩过的坑,把精力真正花在算法本身。