文章目录
- 文章概要
- 算法原理
- 大气散射模型
- 暗通道先验
- FPGA 定点化
- 程序架构
- 模块层次
- 数据流图
- 流水线说明
- 代码实现
- 顶层模块端口
- IP例化端口
- 算法优势
- 天空或云层伪彩或问题
- 景物轮廓有位移或较粗重影问题
- 全屏闪烁或随机噪点横纹问题
- 注意事项
文章概要
电子透雾(Electronic Image Dehazing)是基于大气散射模型的图像增强技术,旨在恢复雾霾天气下退化图像的清晰度和对比度。本文介绍一种基于 Dark Channel Prior(暗通道先验)算法的 FPGA 硬件实现方案,采用三级流水线架构,支持 1080p@60Hz 实时处理,固定延迟 11 个时钟周期。算法核心参数 W0(透射率系数)和 T0(透射率下限)可通过参数化配置灵活调节,去雾使能信号支持帧消隐期动态切换,避免画面撕裂。
基于FPGA的图像电子透雾-开启前后效果视频演示
请点击查看
算法原理
大气散射模型
雾霾图像的形成可由大气散射模型描述:
I ( x ) = J ( x ) ⋅ t ( x ) + A ⋅ ( 1 − t ( x ) ) I(x) = J(x) \cdot t(x) + A \cdot (1 - t(x))I(x)=J(x)⋅t(x)+A⋅(1−t(x))
其中I ( x ) I(x)I(x)是输入的有雾图像,J ( x ) J(x)J(x)是待恢复的无雾图像,t ( x ) t(x)t(x)是透射率(0~1),A AA是大气光强度。去雾的核心即从I ( x ) I(x)I(x)估计t ( x ) t(x)t(x)和A AA,再反解J ( x ) J(x)J(x):
J ( x ) = I ( x ) − A ⋅ ( 1 − t ( x ) ) t ( x ) J(x) = \frac{I(x) - A \cdot (1 - t(x))}{t(x)}J(x)=t(x)I(x)−A⋅(1−t(x))
暗通道先验
He 等人在 CVPR 2009 提出暗通道先验(Dark Channel Prior):在大多数无雾图像的非天空局部区域中,总存在某些像素的至少一个颜色通道强度值极低,即:
J d a r k ( x ) = min y ∈ Ω ( x ) ( min c ∈ { R , G , B } J c ( y ) ) → 0 J^{dark}(x) = \min_{y \in \Omega(x)} \left( \min_{c \in \{R,G,B\}} J^c(y) \right) \to 0Jdark(x)=y∈Ω(x)min(c∈{R,G,B}minJc(y))→0
由此可将透射率估计简化为:
t ( x ) = 1 − w ⋅ min c ( I c ( x ) A ) t(x) = 1 - w \cdot \min_{c} \left( \frac{I^c(x)}{A} \right)t(x)=1−w⋅cmin(AIc(x))
其中w ww(0~1)为保真系数,保留少量雾气以维持图像自然感。
FPGA 定点化
FPGA 实现中避免浮点除法,透射率系数计算、除法、透射率下限钳位采用定点化处理,具有纯布线无IP、零逻辑开销等优势。
程序架构
模块层次
FPGA 去雾模块isp_dehaze由四部分构成:
isp_dehaze (顶层旁路, 9 + 2 = 11 cycles) ├── isp_dehaze_rgb_dark 暗通道提取 (2 cycles) ├── isp_dehaze_transmittance_dark 透射率计算 (3 cycles) ├── isp_dehaze_defogging 大气散射恢复 (6 cycles) └── isp_dehaze_rom_w0 ROM 查表 (1 cycle, 内嵌于 defogging)数据流图
i_data ───┬──→ [RGB Dark] ──→ dark ──→ [Transmittance] ──→ T,dark_max ──→ [Defogging] ──→ dehaze │ 2 cycles 3 cycles 4 cycles │ │ │ └──→ [Bypass Chain] ──── _d1 → _d2 → ... → _d9 ────────────────────────────────→ [MUX] → o_data 9 cycles 2 cycles (sw_dehaze_latched)流水线说明
Stage 1 — 暗通道提取(2 cycles)
逐像素取 R/G/B 三通道最小值作为暗通道灰度值。第 1 拍计算min{R,G},第 2 拍计算min{Stage1, B},输出 3 通道相同的暗通道值{dark, dark, dark}。
Stage 2 — 透射率计算(3 cycles)
帧内逐像素计算透射率:t r a n s m i t t a n c e = 255 − d a r k × ( 255 − W 0 ) / 256 transmittance = 255 - dark \times (255 - W_0) / 256transmittance=255−dark×(255−W0)/256,结果钳位到T 0 T_0T0下限。帧间采集暗通道最大值dark_max,在帧尾(fval 下降沿)锁存并清零,供下一帧 Stage 3 使用。
Stage 3 — 大气散射恢复(4 cycles)
RGB 图像和透射率各经过 4 级打拍对齐后,逐通道执行定点化去雾计算。大气光A = d a r k _ m a x A = dark\_maxA=dark_max(上一帧采集)。当I × 255 < A × ( 255 − T ) I \times 255 < A \times (255 - T)I×255<A×(255−T)(大气光主导)时 bypass 输出原像素,避免负值。
Stage 4 — 消隐期切换与输出(2 cycles)
i_sw_dehaze在帧消隐期(i_fval==0)锁存,确保切换发生在帧间。去雾路径(9 cycles)与旁路路径(9 cycles)延迟严格相等,末级 MUX 选择后经 2 级输出寄存器统一打出。
总延迟恒为 11 cycles,两路径严格控制同周期、同相位。
代码实现
顶层模块端口
module isp_dehaze ( input clk , // 像素时钟 input rst_n , // 异步复位(低有效) input i_sw_dehaze , // 去雾使能(消隐期锁存) input i_fval , // 帧有效 input i_lval , // 行有效 input i_dval , // 数据有效 input [23:0] i_data , // RGB888 输入 output o_fval , // 帧有效(11-cycle延迟) output o_lval , // 行有效(11-cycle延迟) output o_dval , // 数据有效(11-cycle延迟) output [23:0] o_data // RGB888 输出 );IP例化端口
算法优势
规避了其他家电子透雾算法发生的一些问题。
天空或云层伪彩或问题
景物轮廓有位移或较粗重影问题
全屏闪烁或随机噪点横纹问题
注意事项
输入时序约束
- 输入必须为逐像素连续视频流(RGB888 格式),fval/lval/dval 遵循标准消隐时序。
i_fval==0(帧消隐期)必须周期性出现,这是 sw_dehaze 切换和 dark_max 帧间锁存的唯一窗口。若 fval 永久为 1,去雾效果将异常。- 帧尾时 fval 下降沿之后至少 1 个时钟周期 dval 不有效,确保 max_dark 锁存逻辑正确触发。
首帧注意事项
- 复位后第一帧
dark_max = 0,大气光 A=0,去雾公式退化为 J=I,第一帧等效旁路输出。从第二帧起 dark_max 使用前一帧采集值正常。
- 复位后第一帧
参数调优
W0(默认 128,即 w=0.50):控制去雾强度,W0 越大去雾越强,但过高会导致天空区域颜色失真。典型范围 80~160。T0(默认 96,即 t_min=0.375):透射率下限,防止浓雾/天空区域除法不稳定。T0 越小恢复越强但噪声放大;T0 越大保护越强但去雾不足。DEVIDER(固定 4096=2^12):不可随意修改。若改为非 2 的幂次,除以 DEVIDER 将需要完整除法器(~200 LUT),资源开销成倍增加。
资源估算
- 暗通道提取:比较器 + 少量寄存器,< 50 LUT。
- 透射率计算:1 个 DSP48(8×8 乘法)+ 约 100 个寄存器。
- 大气散射恢复:3 个 DSP48(16×12 乘法,每通道一个)+ 约 200 个寄存器。
- ROM:1 个 BRAM18(256×12bit)。
- 旁路延迟链 + MUX:约 250 个寄存器。
- 总计:< 400 LUT + 4 DSP48 + 1 BRAM18,资源开销极低。
场景适用性
- 暗通道先验假设非天空区域暗通道趋近于零。对于大面积天空、雪景、白墙等本身较亮的场景,暗通道先验失效,去雾效果减弱或出现颜色偏移。此类场景可考虑结合引导滤波或天空区域分割等增强策略。