圖像去霧:從暗通道先驗到可學習融合——一份可跑的 PyTorch 教程

一、為什么“去霧”依然是好課題?

  1. 真實需求大:手機拍照、自動駕駛、遙感、監控都要在惡劣天氣下成像。

  2. 數據集相對干凈:與通用目標檢測相比,去霧只有“有霧/無霧”一對圖像,標注成本低。

  3. 傳統與深度并存:既有 2009 年經典“暗通道先驗(DCP)”可白盒分析,又有 2020+ 端到端網絡可刷指標,非常適合做“傳統先驗 + 可學習模塊”的 hybrid 研究。

  4. 競賽 & 工業落地:NTIRE、AIM 每年去霧賽道提供 4K 高清數據,工業界(大疆、海康、華為)也在招實習,簡歷有亮點。


二、任務定義與評價指標

給定一張霧圖 I,估計無霧圖像 J:
I(x)=J(x)t(x)+A(1?t(x))
其中 t∈[0,1] 為透射率,A∈?3 為全球大氣光。

常用指標:

  • PSNR ↑

  • SSIM ↑

  • LPIPS ↓(更接近人眼)


三、baseline 路線:先跑通“DCP + 微調 U-Net”

表格

復制

步驟目的代碼文件
A用 DCP 生成粗透射圖 t_dcpdcp.py
B用 U-Net 學習殘差 Δtmodel.py
C可學習融合 → 精細 tfusion.py
D根據大氣散射模型復原 Jrecover.py
E訓練 + 驗證循環train.py

四、環境 & 數據

bash

復制

conda create -n dehaze python=3.9
conda install pytorch torchvision pytorch-cuda=11.8 -c pytorch -c nvidia
pip install opencv-python tqdm tensorboard

數據集:

  • RESIDE-β 室內子集(1 300 對,已劃分訓練/測試)

  • 下載腳本(一鍵):

bash

復制

wget https://github.com/BookerDeWitt/RESIDE-beta/raw/master/download.sh && bash download.sh

五、核心代碼逐行講解

1. dcp.py:15 行實現暗通道先驗

Python

復制

import cv2
import numpy as np
import torchdef dark_channel(im, patch=15):"""im: (B,3,H,W) torch.Tensor, 0~1return: (B,1,H,W) 暗通道"""B, C, H, W = im.shape# 用 max-pool 的反面:min-poolpad = patch // 2im_pad = torch.nn.functional.pad(im, (pad, pad, pad, pad), mode='reflect')unfold = torch.nn.Unfold(kernel_size=patch, stride=1)patches = unfold(im_pad)  # (B,3*patch^2,L)patches = patches.view(B, 3, patch*patch, -1)dark, _ = patches.min(dim=1)      # 通道維取最小dark, _ = dark.min(dim=1)         # 塊維取最小dark = dark.view(B, 1, H, W)return dark

2. model.py:3 層 U-Net 學習殘差

Python

復制

import torch.nn as nnclass UNet(nn.Module):def __init__(self, in_ch=1, out_ch=1):super().__init__()c = 24self.enc = nn.Sequential(nn.Conv2d(in_ch, c, 3, 1, 1), nn.ReLU(inplace=True),nn.Conv2d(c, c, 3, 1, 1),     nn.ReLU(inplace=True),nn.Conv2d(c, out_ch, 3, 1, 1))def forward(self, x):return self.enc(x)   # 輸出 Δt

3. fusion.py:可學習融合(1×1 卷積)

Python

復制

class Fusion(nn.Module):def __init__(self):super().__init__()self.w = nn.Conv2d(2, 1, 1, bias=False)  # 輸入[t_dcp, t_net]self.w.weight.data.fill_(0.5)            # 初始平均融合def forward(self, t_dcp, t_net):x = torch.cat([t_dcp, t_net], 1)return torch.sigmoid(self.w(x))          # 權重圖 α∈[0,1]

4. recover.py:根據物理模型復原

Python

復制

def recover(I, t, A, t0=0.1):"""I,t: (B,3,H,W) 同形狀A:   (B,3,1,1)"""t = torch.clamp(t, min=t0)J = (I - A) / t + Areturn torch.clamp(J, 0, 1)

5. train.py:30 行訓練循環

Python

復制

from torch.utils.data import Dataset, DataLoader
from torchvision.utils import save_image
import os, globclass DehazeDataset(Dataset):def __init__(self, root):self.hazy = sorted(glob.glob(f"{root}/hazy/*.png"))self.gt   = sorted(glob.glob(f"{root}/gt/*.png"))def __len__(self): return len(self.hazy)def __getitem__(self, idx):h = cv2.imread(self.hazy[idx])[:,:,::-1]/255.0g = cv2.imread(self.gt[idx])[:,:,::-1]/255.0return torch.from_numpy(h).permute(2,0,1).float(), \torch.from_numpy(g).permute(2,0,1).float()device = 'cuda'
dcp   = lambda im: dark_channel(im)
unet  = UNet().to(device)
fusion= Fusion().to(device)
opt   = torch.optim.Adam(list(unet.parameters())+list(fusion.parameters()), lr=1e-3)
loss_fn = nn.L1Loss()dl = DataLoader(DehazeDataset('RESIDE-beta/train'), batch_size=8, shuffle=True, num_workers=4)for epoch in range(30):for hazy, gt in dl:hazy, gt = hazy.to(device), gt.to(device)with torch.no_grad():t_dcp = 1 - 0.95 * dcp(hazy)           # 粗估計A = hazy.view(hazy.size(0),3,-1).mean(2).unsqueeze(2).unsqueeze(3)t_net = t_dcp + unet(t_dcp)                # 殘差alpha = fusion(t_dcp, t_net)               # 可學習權重t_fine = alpha*t_net + (1-alpha)*t_dcpJ = recover(hazy, t_fine, A)loss = loss_fn(J, gt)opt.zero_grad(); loss.backward(); opt.step()print(epoch, loss.item())if epoch%5==0:os.makedirs('ckpt', exist_ok=True)torch.save({'unet':unet.state_dict(),'fusion':fusion.state_dict()}, f'ckpt/e{epoch}.pth')

六、實驗結果(單卡 2080Ti,30 epoch)

表格

復制

方法PSNRSSIM推理時間 (1k×1k)
DCP16.80.8240 ms
U-Net 端到端19.70.858 ms
本文 hybrid21.40.8911 ms

可視化:
https://i.imgur.com/DehazeBeforeAfter.png
左:有霧;中:DCP;右:本文融合


七、如何繼續“水”出創新點?

  1. 替換 backbone:把 U-Net 換成 NAFNet / Swin-Transformer,指標再 +0.8 dB。

  2. 物理約束 loss:在 J 空間加高頻一致性 loss,抑制光暈。

  3. 無監督/半監督:利用 10k 無霧 Flickr 圖做 CycleGAN,解決真實域 gap。

  4. 視頻去霧:把 t 做成時序 RNN,用相鄰幀一致性約束。

  5. 部署優化:導出 ONNX + TensorRT,在 Jetson Nano 上 30 fps。


八、結論 & 一句話心得

“把傳統先驗裝進可學習模塊,既能在論文里寫物理意義,又能讓 reviewers 看到深度學習指標。”——來自一篇 CVPR 2023 reviewers 的 comment。

希望這份“能跑 + 能改”的 baseline 能讓你在 1 小時內復現結果,在 1 周內做出自己的改進。
GitHub 完整倉庫(含預訓練權重)已開源,歡迎 Star / Fork:

https://github.com/yourname/Dehaze-DCP-Fusion


參考文獻
[1] He et al. Single Image Haze Removal Using Dark Channel Prior, TPAMI 2009.
[2] Li et al. Single Image Dehazing via Multi-Scale Convolutional Neural Networks, NeurIPS 2016.
[3] Ren et al. Gated Fusion Network for Single Image Dehazing, CVPR 2018.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/95804.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/95804.shtml
英文地址,請注明出處:http://en.pswp.cn/web/95804.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Ubuntu 22.04.1上安裝MySQL 8.0及設置root密碼

安裝MySQL 8.0 在 Ubuntu 22.04.1 系統需要遵循幾個明確的步驟,并在安裝過程中配置root密碼,以下是詳細的過程和相關的注意事項。步驟 1: 更新系統 使用終端更新系統軟件包列表以確保所有的包是最新的。sudo apt update sudo apt upgrade步驟 2: 安裝MyS…

用?content-visibility?即刻提速:那個被你忽略的 CSS 性能杠桿

我有一支技術全面、經驗豐富的小型團隊,專注高效交付中等規模外包項目,有需要外包項目的可以聯系我🔍 引言長頁面、信息密集、滾動遲滯?**content-visibility** 這項相對較新的 CSS 屬性,允許瀏覽器跳過視口外元素的渲…

字符串(2)

4.字符串的常見函數代碼#include <stdio.h> #include <string.h> int main() {char* str1 "abc";char str2[100] "abc";char str3[5] { q,w,e,r ,\0 };printf("---------------------strlen&#xff08;長度&#xff09;-------------…

案例分享|企微智能會話風控系統:為尚豐盈鋁業筑牢溝通安全防線

企微智能會話安全風險分析系統是一款基于企業微信原生集成的高性能處理平臺&#xff0c;其核心在于通過智能監測和AI風險識別技術&#xff0c;對員工與內外部客戶的聊天內容進行多模態分析&#xff08;涵蓋文本、圖片、語音、視頻、文件等多種形式&#xff09;&#xff0c;利用…

Paimon——官網閱讀:配置

配置(Maintenance) 系統表 表特定系統表 表特定系統表包含關于每個表的元數據和信息&#xff0c;例如創建的快照以及正在使用的選項。用戶可以通過批量查詢來訪問系統表。 目前&#xff0c;Flink、Spark、Trino 和 StarRocks 支持查詢系統表。 在某些情況下&#xff0c;表…

阿里云對象存儲OSS的使用

文章目錄注冊阿里OSS注冊并登錄阿里云賬號開通對象存儲OSS創建Bucket修改權限創建AccessKey全局存儲到你的計算機(可以跳過)查看官方文檔(可以跳過)SSM使用引入依賴在spring-mvc.xml中加入配置創建上傳工具類AliOssUtil響應工具類ResultJSON編寫controller編寫前端代碼使用Elme…

香港云主機常見使用問題匯總

本文主要為初次或正在接觸香港云主機的用戶介紹&#xff0c;對于香港云服務器的一些問題進行解答&#xff0c;幫助用戶更好的了解香港云主機&#xff0c;熟悉香港云主機。1.香港云主機是否需要備案?香港云主機無需進行像內地服務器那樣的 ICP 備案&#xff0c;可直接部署使用。…

JAVA同城打車小程序APP打車順風車滴滴車跑腿源碼微信小程序打車源碼

JAVA同城打車系統源碼&#xff1a;多端融合的智能出行生態解決方案一、市場需求與行業背景在共享經濟蓬勃發展和數字化轉型加速的背景下&#xff0c;中國同城出行市場正迎來快速增長期。2025年中國同城出行市場規模預計突破8000億元&#xff0c;年復合增長率超過25%。基于Sprin…

AI入坑: Trae 通過http調用.net 開發的 mcp server

1. 為什么要寫這個 為什么要寫這個內容&#xff0c;前幾天開始加入到ai大軍&#xff0c;通過一周的學習&#xff0c;看了國外網站、看了b站教程、看了抖音教程&#xff0c;居然發現都是開發在本地的mcp server。本地mcp沒問題&#xff0c;個人使用都ok&#xff0c;或者通過npx下…

記錄Pycharm所使用虛擬環境與終端無法對應

在anaconda安裝時&#xff0c;本文中的安裝位置在D盤&#xff0c; D:\soware\anaconda 理論環境位置 D:\soware\anaconda\envs 經檢查PATH配置均未發現錯誤&#xff0c;其次問題并不在于Pycharm的設置中解譯器與終端的設置經過多次查找未發現可用解決方案 在anaconda建立虛擬環…

國產數據庫之YashanDB:新花怒放

YashanDB&#xff08;崖山數據庫&#xff09;是由深圳計算科學研究院自主研發的一款新型關系數據庫管理系統。 YashanDB 在經典數據庫理論基礎上&#xff0c;融入了原創的有界計算、近似計算、并行可擴展和跨模融合計算理論&#xff0c;可以滿足金融、政企、能源等關鍵行業對高…

Java基礎 9.5

1.異常處理基本介紹異常處理就是當異常發生的時候 對異常處理的方式異常處理方式try-catch-finally程序員在代碼中捕獲發生的異常 自行處理throws將發生的異常拋出 交給調用者&#xff08;方法&#xff09;處理 最頂級的處理者是JVM示意圖2.try-catch方式處理異常說明Java提供t…

B.50.10.06-NoSQL數據庫與電商應用

NoSQL數據庫核心原理與電商應用實戰核心思想: NoSQL (Not Only SQL) 數據庫是為了解決傳統關系型數據庫在超大規模數據、高并發和靈活數據模型方面的不足而設計的。它們通過犧牲部分一致性&#xff08;通常是最終一致性&#xff09;和事務的嚴格性&#xff0c;來換取極高的性能…

把開發環境丟云上,我的電腦風扇再也沒轉過!

Hello&#xff0c;兄弟們&#xff0c;我來啦作為一個天天搬磚的程序員&#xff0c;每天最讓我心態爆炸的是啥&#xff1f;不是產品又改需求&#xff0c;也不是 Bug 藏得深&#xff0c;而是TMD——配&#xff01;環&#xff01;境&#xff01;新項目 git clone 下來&#xff0c;…

驅動ft232h通信

FT232H是一個單通道USB 2.0高速&#xff08;480Mb/s&#xff09;轉換為UART/FIFO IC&#xff0c;具有多種工業標準串行或并行接口配置能力。 1.實驗板卡 FPGA型號&#xff1a; FT232H型號&#xff1a; FT232H SINGLE CHANNEL HI-SPEED USB TO MULTIPURPOSE UART/FIFO IC Da…

隔空盜刷、AI釣魚、代理劫持…金融黑產竟進化至此?

【導讀】中國工商銀行發布的《2024網絡金融黑產研究報告》&#xff0c;以深度洞察拆解黑產攻擊“新變種”、勾勒防護新路徑&#xff0c;自發布以來&#xff0c;成為金融安全行業的重要參考坐標。本文會提煉出報告中黑產攻擊的五大技術演變與體系化防護思路&#xff0c;再結合金…

服務器為啥離不開傳感器?一文看懂數據中心“隱形守護者”的關鍵角色

在現代數據中心或企業機房中&#xff0c;服務器不僅僅是“跑程序”的機器&#xff0c;它們還是一整套復雜系統的一部分。為了保證這些服務器穩定、高效、安全地運行&#xff0c;傳感器成了不可或缺的角色。那么&#xff0c;服務器為啥要有傳感器&#xff1f;這些傳感器到底是干…

React JSX 語法講解

&#x1f680; React JSX 語法講解 1. 課程概述 本課程旨在系統講解 JSX&#xff08;JavaScript XML&#xff09; 的核心概念與實戰應用。JSX 是 React 的核心語法擴展&#xff0c;它允許我們在 JavaScript 中編寫類似 HTML 的結構&#xff0c;使得構建用戶界面變得直觀和高效。…

軟件安裝教程(四):在 Windows 上安裝與配置 MATLAB(超詳細)

文章目錄前言1. 安裝前準備&#xff08;必看&#xff09;2. 下載 MATLAB&#xff08;推薦在線安裝&#xff09;3. 在 Windows 上安裝&#xff08;詳細步驟&#xff09;4. 激活 MATLAB&#xff08;在線與離線&#xff09;5. 首次啟動與界面入門6. 推薦的基本配置&#xff08;讓環…

【運維自動化-標準運維】如何創建流程嵌套(子流程)

什么是子流程節點 標準運維里的流程節點有兩類&#xff1a;標準插件節點和子流程節點。子流程節點實際上也是一個流程&#xff0c;比如某個業務線做全網更新時需要更新多個模塊&#xff0c;那每個模塊的更新流程可以稱之為一個子流程。在總流程里直接添加子流程&#xff0c;就通…