ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

FPGA实时视频透雾增强:暗通道先验与导向滤波的硬件实现

FPGA实时视频透雾增强:暗通道先验与导向滤波的硬件实现 1. 项目背景与方案选型做FPGA图像处理的工程师迟早会碰到一个绕不开的需求给摄像头上传回的画面做透雾增强。前几年这玩意儿还是安防监控的专属需求雾天、雾霾天、烟尘环境里画面发白、对比度拉胯、细节全糊普通摄像头拍出来基本没法看。如今车载、无人机、工业检测、航道监控全都提出实时透雾的需求纯软件端的透雾算法再成熟一帧1080p的图在嵌入式CPU上也要几十毫秒到上百毫秒真要跑在实时视频链路上几乎不可能。我手里这个项目就是用FPGA实现ISP管线中的电子透雾Dehaze功能。所谓电子透雾跟镜头前加物理滤光片的光学透雾完全是两码事它是纯算法层面的图像增强后台把大气散射带来的模糊分量估算出来再反向恢复出清晰图像。FPGA在这里的优势天然明显像素级流水线、行缓冲、可编程逻辑并行计算透雾算法里大量的窗口统计、均值滤波、透射率计算都是高度并行的操作用FPGA做能稳定跑在4K30fps甚至60fps延迟只有几行像素的时间。整个设计环境我选了Xilinx Artix-7系列开发板带HDMI输入输出、DDR3、MIPI摄像头接口。算法上以暗通道先验Dark Channel Prior为核心用快速导向滤波替代传统导向滤波做透射率细化最后再做自动白平衡和色调映射兜底。这套方案做好了既可以在独立FPGA上跑也方便以后往Zynq平台上面迁移让ARM配合做参数在线调节。这篇文章就一步步拆解整个系统的架构设计、算法原理、RTL实现思路和调试中踩过的坑给同样在FPGA上做ISP图像增强的工程师一个完整参考。1.1 核心需求解析先厘清透雾的需求边界否则做出来的东西很容易“看着效果行了实际没法用”。项目立项时我梳理了四条硬性指标第一是实时性。1080p60fps输入单帧周期约16.7ms行周期约14.7us。整个透雾链路必须采用全流水线设计逐像素处理允许的最大端到端延迟一般不能超过一帧实际工程目标做到几行到几十行像素延迟。第二是画质要求。透雾不是简单拉对比度透过后天空不能过曝发灰远处细节不能出现明显光晕近处的物体色彩不能失真。也就是说算法要处理好“深度不连续”的区域这直接决定了要不要上导向滤波这类边缘保持的平滑算法。第三是资源约束。用中端FPGA比如Artix-7 200T级别跑1080p透雾片上BRAM总量约13MbDSP48E1有740个。如果算法设计不考虑资源窗口卷积随便一开就是几百个DSP最后必然落不了板。第四是鲁棒性。透雾算法在很多场景下是“一把钥匙开一把锁”雾天黄昏、逆光薄雾、夜间烟尘光照条件不同参数必须能自适应。纯静态参数只能糊弄测试图真实环境会把你按在地上摩擦。所以方案选型时我直接砍掉了各种深度学习透雾的念头。不是说深度学习效果不好而是当时平台上的CNN推理单元还没法塞进这个资源预算且保证逐像素的实时流水。传统物理模型方法虽然上限不如深度学习方法但胜在计算结构规整、可解释性强、资源开销可控这才是FPGA上务实的选择。1.2 电子透雾与光学透雾的取舍成像链路里透雾其实有两条路物理滤光和电子算法。光学透雾是利用红外波段穿透雾霾的能力在镜头前加特定波段的滤光片配合宽光谱响应传感器。它确实能有效穿透中等浓度的雾尤其对水雾效果明显但缺点也很致命滤光片会牺牲大量可见光波段的色彩信息画面偏色严重晴天环境还得摘掉滤光片机构设计复杂成本也高。电子透雾则是纯算法手段通过建立大气散射的物理模型估算环境光和透射率再把被雾“吃掉”的对比度和色彩恢复出来。优势在于不改硬件、成本几乎为零、适用场景灵活——同一套算法白天能透雾、晚上能去烟、逆光时还能顺手做对比度增强。缺点在于算法复杂度高计算量远大于普通的图像增强操作而且存在一定的“艺术效果”成分处理不好会有塑料感和伪影。最终选择电子透雾是考虑它在车载、安防、工业等领域更容易工程化落地。后端ISP本来就有3AAE、AWB、AF这些模块透雾作为ISP管线中的一环直接嵌入产品形态干净利落。2. 透雾算法核心原理既然要在FPGA上做透雾那算法原理必须吃透。我做项目有个习惯先把算法在Matlab和相关Python环境里完整仿真通过输出中间结果分析再去写RTL。算法不搞清楚直接上手RTL调试周期会长到你怀疑人生。2.1 大气散射模型的建立电子透雾算法的根子都在大气散射模型上所有透雾代码基本都长成一个样I(x) J(x)·t(x) A·(1 - t(x))I(x) 是相机直接拍到的带雾图像也就是输入J(x) 是场景辐射度即我们想恢复的清晰图像A 是全局大气光可以理解成天空区域或者无穷远处的亮度值t(x) e^(-β·d(x)) 是介质透射率和景深 d(x) 指数相关式子本身很好理解相机接受到的光分成两部分一部分是物体反射光经过雾气衰减后传过来的另一部分是大气光本身被散射进视场里的。透雾的核心任务就变成了从单张带雾图像 I(x) 中估计出 J(x)这是一个天然的病态问题未知数比方程多。为此需要额外假设来约束求解空间暗通道先验就是这类约束里最出名的一个。2.2 暗通道先验算法 DCP暗通道先验来自何恺明在2009年发表的经典论文核心统计观察是在绝大多数无雾的自然图像中每个局部小区域patch内至少存在一个颜色通道的强度值非常低接近0。即J_dark(x) min( c∈{R,G,B} , min( y∈Ω(x) , J_c(y) ) ) → 0用大白话说随便取一个小区块总能找到某个像素的RGB三个通道里至少有个通道像素值很小。基于这个先验可以把大气散射模型做如下变换对等式两边先做两次最小值滤波先通道内取min再空间邻域内取min推导出透射率t_est(x) 1 - ω · min_c( min_y∈Ω(x)( I_c(y) / A_c ) )ω是保留少量雾的常数一般取0.85到0.95目的是一点点保留景深层次感把图拉到底反而会有廉价HDR感。之后根据估计的大气光A和透射率t(x)恢复清晰图像J(x) ( I(x) - A ) / max( t(x), t0 ) At0通常在0.1附近防止分母为0导致噪点放大。2.3 透射率细化的必要性直接拿粗透射率恢复图像会有一个灾难性问题大量块状伪影。因为最小值滤波本身是块操作透射率在边缘处是阶梯状跳变的恢复时会沿边缘产生光晕halo effect。典型表现是物体边缘外侧出现一圈“发毛”的白边这在工程上是完全不能接受的。解决思路是给粗透射率做一次边缘保持平滑滤波。原论文用的是soft matting软抠图效果最好但涉及大型稀疏线性方程组求解动不动迭代几十次FPGA上根本不现实。后来有快速导向滤波方案结果质量接近软抠图计算量大幅下降且滤波窗口大小与计算时间无关非常适合硬件化。快速导向滤波的基本思路是以输入图像I灰度图作为引导图对粗透射率t进行边缘保持滤波。公式核心是两个局部线性系数a_k ( Σ_i∈w_k( I_i·p_i - u_k·p̄_k ) ) / ( σ_k² ε ) b_k p̄_k - a_k·u_k再在重叠窗口内平均系数得到最终输出。这么一通操作下来透射率贴合物体的边缘结构恢复出来的图像才不会在深度断崖处出现光晕。2.4 算法复杂度与硬件可行性分析我们把上面整套流程拆解成硬件模块逐个算算复杂度看看FPGA能不能扛得住。粗透射率计算先按通道做3x3或更大窗口如7x7最小值滤波再做跨通道最小值融合最后做一次除法得到初始透射率。最小值滤波本身不是乘加运算用比较器就能实现不耗DSP只耗逻辑和BRAM资源友好度很高。导向滤波部分最有压力。传统导向滤波若窗口半径r8均值滤波用盒式滤波来做每像素需要一次乘加、一次除法统计均值时可定点近似对1080p图像整个导向滤波至少要算多次整图均值滤波img、img²、img·p、p、局部方差等每次均值滤波都是一次全帧访问。若完全用FPGA逻辑实现为了不放下整帧图像只能用行缓冲和滑动窗口近似我后面展开讲具体做法。像素级恢复一次除法、数次乘加加上最后的数据截位每个像素大概需要3-4个DSP48。1080p60fps主频约148.5MHzDSP利用率只有3 x 1920 x 1080 x 60 ≈ 373M次乘加每秒A7-200T的740个DSP跑在200MHz就是148G次乘加每秒完全够。所以结论是核心瓶颈在导向滤波的实现方式不在乘法器数量。这也决定了我后面架构设计的重心全放在如何用低成本资源做高质量的局部窗口滤波。3. FPGA架构设计与模块实现算法给硬件指明了方向暗通道需要大窗口气泡滤波透射率细化要做一个引导滤波的近似图像恢复模块则相对简单。我最终把整个ISP透雾链路拆成六个可独立仿真的模块每个模块之间用Valid/Ready握手信号衔接方便仿真和后续复用。3.1 整体硬件架构设计系统的顶层框图分六块这里不画图直接文字描述逻辑图像输入模块支持MIPI或HDMI RX进来的YUV/RGB数据先把输入的串行像素转成并行RGB并同步产生像素有效信号和行列计数信号。暗通道模块Dark Channel先做通道内RGB取min再做N x N窗口最小值滤波。具体输出两个结果窗口内的最小亮度值用于估算透射率以及大气光候选值。大气光估计模块Atmospheric Light对暗通道图中最亮的前0.1%像素取原图中对应位置的最亮值作为全局大气光A估计。透射率精化模块Coarse-to-Refined T将上一步的粗透射率和原始灰度图作为输入做快速导向滤波输出边缘保持的细化投射率。恢复与白平衡模块Recovery AWB按物理模型逐像素恢复J(x)再叠加简单AWB做色彩校正最后做Gamma映射输出。输出时序控制模块把数据打包回YUV/RGB格式对齐到HDMI或MIPI输出的时序标准。整体信号链路是纯粹的流式处理没有“等整帧”的操作。大气光估计是一个逐帧更新的慢变量帧间滞后可接受通过一个AXI-Lite寄存器接口可以随时人工修改调试时也可以强制设定大气光很方便。这里额外提一句与FMC扩展相关的经验后期我把这个透雾核挂到一块带STM32H743控制器的板卡上时就是用FMC接口做寄存器读写ARM侧把透雾强度、透射率下限等参数配置成可视化的滑条在线调参体验拉满。3.2 行缓冲与窗口处理策略FPGA上做N x N窗口滤波的常规操作是行缓冲line buffer加移位寄存器阵列。以7x7暗通道滤波为例内部用6个FIFO实际是FPGA的BRAM配置成真双端口每个FIFO缓存一行有效像素再加上7行x7列共49个寄存器构成一个滑动的7x7窗口。行缓冲的原理很简单第0行数据进来填满第一行寄存器边填边往FIFO0里写下一行像素进入第二行寄存器时第一行数据从FIFO0中读回。如此滚动每一拍都能拿到一个完整的7x7数据窗口。注意点在于必须在有效像素信号de为高时才写FIFO否则会混入行消隐的无效像素。用BRAM做行FIFO时要小心行同步信号hdmi输入的行宽度是1920但每行实际包含HBlank区FIFO深度必须比最大宽度多留余量否则接近图像右边缘时窗口会错位。我之前最早一版就踩过这个坑行FIFO深度只精确等于1920结果图像右侧边缘几十个像素的暗通道值全部异常画面右侧出现一条明显的纹理错位。后来把FIFO深度改到2048问题消失。这就是为什么做FPGA图像处理永远要在FIFO深度上预留缓冲图像格式哪怕协议里写了1920也要防一手各种时序转换模块带来的额外数据。3.3 暗通道计算的硬件实现细节暗通道计算分成两级通道维度和空间维度。通道维度很简单三个8bit输入R、G、B取最小值用两级比较器。空间维度7x7窗口的最小值滤波最直观的方法是用49个寄存器全比较但这样逻辑延迟太大也消耗大量LUT。实际工程做法是用行列级联求最小值先把窗口的每一行7个像素分别求最小值每行用3级比较器得到7行列最小值再对这7个值求最小值又是3级比较。寄存器链可以插入流水线整体延迟大约6个时钟但最高频率能跑到250MHz以上。这种“行内先求最小、再做列方向最小”的做法本质上利用了最小值运算的分配率和二维均值滤波拆成行滤波加列滤波是同一个道理。用FPGA做图像处理能拆成行列分离的运算尽量拆资源瞬间降一个量级。暗通道块输出的暗通道图像和原始RGB图像需要保持严格的对齐关系。由于暗通道滤波经过了窗口延时而原始图像没有延迟要么把原始图像延迟同样的时钟周期要么在后续模块中用FIFO重新对齐。我选择把原始RGB延迟相同周期保证所有数据的像素坐标一一对应这会让后续大气光估计取原图像素时非常省心。3.4 大气光估计模块的两种实现大气光A的估计质量直接决定透雾后的色偏程度是那种“输错一个数、整张图全毁”的模块。实现方案一统计法。对整个暗通道图做直方图统计找到暗通道值排名前0.1%的像素再在这些位置取原始RGB图像的最大值取平均值作为A。在硬件上做一个全局的histogram统计分辨率1920x1080需要约2M个像素统计出一个“亮区掩码”之后再做一次遍历取平均。这个方案需要缓存整帧暗通道数据而且两次遍历之间要等一帧端到端延迟会多了整帧。实现方案二简化法。逐帧更新把每行窗口内的最大暗通道值记录到一组行寄存器同时记录对应3x3邻域内的最大值。当检测到比当前A值更大的候选值时按比例更新A。这样A的收敛在几帧内完成适合动态场景。项目最终选的方案二是它的变体取暗通道图中亮度最高的前0.1%像素对应原图的最大像素值作为A但又避免整帧缓存做法是分块处理。把画面划分成16x16的块block记录每个块的暗通道最大值全帧的块统计结果存到片上小RAM里帧结束后从128个小块里取出最大值位置再回到帧间缓存中取原图对应位置的像素值作为A。这个方案的好处是每帧输出一个稳定的A值同时挂到AXI-Lite寄存器方便外部强制设定。实测下来A值取暗通道最亮区域的亮度而非全局最亮像素。全局最亮像素很可能是高光、白色物体或光源直接取会严重过曝透雾后整张图灰蒙蒙。用区块统计能在一定程度上避免这种“高亮点污染”。3.5 透射率计算与快速导向滤波实现透射率粗略计算是逐像素进行一次减法、一次除法、一次乘系数操作。硬件里除法对资源不友善采用查表法或倒数近似。我的做法是把A的倒数预先算好存到寄存器公式改写成t_coarse 1 - ω · ( dark / A )等效于先算 dark / A 再乘 ω。因为A是每一帧才更新一次预计算1/A很划算一个除法器在帧期间长期空闲。真正烫手的是透射率的精化。原本的导向滤波在软件里跑步骤都是均值滤波组合。FPGA里我采用了两种近似方案方案A极小半径导向滤波选用3x3小窗口导向滤波直接行列做均值盒式滤波。因为窗口缩小直接用行缓冲搭3x3窗口做局部统计照搬导向滤波公式。实测下来边缘保持效果尚可光晕比粗透射率直接恢复小很多但对较细的物体边缘仍有轻微残留。方案B多级下采样导向滤波先把粗透射率和引导图做2x2或4x4均值下采样在下采样域做较大半径导向滤波等效原图的8x8或16x16窗口再把结果上采样回原始分辨率。用双线性插值做上采样。整体资源占用比全分辨率大窗孔导向滤波降低一个数量级边缘保持能力却显著优于方案A。最终板上的实现是方案B。下采样/上采样两端的行FIFO加起来占约12块BRAM导向滤波本身用3x3均值做局部统计一个像素大约8个DSP。透射率精化模块总计资源开销约4000 LUT、15个DSP、15块BRAM在Artix-7 200T上毫无压力这比我最初预想的要乐观得多。3.6 色彩恢复与白平衡增强模块恢复模块直接套公式J (I - A) / max(t, t0) A。由于I和A都是RGB三通道t是灰度标量所以需要做三次除法。除法器我全部用Xilinx的Division IP核流水线配置9bit分子8bit分母每个除法器延迟8个时钟三个通道可以共享一个除法器依次计算也可以并行三个除法器换取吞吐。1080p60fps没有吞吐压力我用一个除法器加一个小状态机分时复用资源省得吓人。透雾后经常出现整体偏灰的问题原因是大气光估计偏大时J(x)的动态范围被压缩。这时候要在末尾加一级自动对比度拉伸或者白平衡校正。我加了一个基于灰度世界假设的快速AWB统计R、G、B三个通道的均值计算增益系数把三通道均值拉回同一水平。这个模块在整个透雾链路里虽然不起眼但对产品最终主观画质提升作用很大。没有这一级的图不对比不知道对比之后你会觉得原来的图“像蒙了一层灰”。最后做Gamma映射标准sRGB的0.45次幂曲线。FPGA上实现反正函数直接用查找表256个输入值映射到256个输出值一块LUTRAM就搞定。3.7 状态机与资源规划表整个核心链路里除大气光估计外全是逐像素流式处理没太大状态机复杂度。大部分人写FPGA图像处理爱把状态机搞成“帧级状态机”把所有模块的状态耦合在一起最后调试时一个信号出错全都错。我的习惯是每个模块拥有独立的local状态机只对上层的valid/ready信号做响应。模块之间的握手尽量简单流式模块压根不用握手永远处于ready状态只有跨帧的模块大气光估计才有完整的状态机状态。这里给出我最终在Artix-7 200T上的资源使用情况供参考模块LUTFFBRAM(36Kb)DSP48E1暗通道模块(7x7)153298730大气光估计42131060透射率粗计算36628802导向滤波(下采样版)410623501514图像恢复79260403AWBGamma48831221总计770548512620整个透雾核心约占A7-200T的3% LUT、4% BRAM、3% DSP算上HDMI视频通路、DDR控制器、MIPI等周边整板占用依然非常宽裕。甚至后续把分辨率提到4K预留资源也足够扩展更大窗口的滤波。4. 仿真验证与上板调试FPGA图像处理工程最忌讳“上来就写RTL写完上板看效果”。上板前一定要有完整的仿真和确定性的指标验证流程。我自己做图像处理项目至少会准备三套测试数据标准雾天图片、合成雾图用深度图生成的梯度雾、真实雾天视频帧。4.1 仿真平台搭建仿真平台的搭建思路是用Matlab/Python脚本生成测试原图和参考结果再用SystemVerilog搭建一个Testbench通过文本方式读入图像经过DUT透雾处理后导出结果最后用Python脚本做PSNR和SSIM对比。Testbench里有三个关键部分图像读取器用$readmemh读入十六进制格式的图像数据按行按像素驱动到DUT输入端口。DUT实例挂上透雾核心全链路时钟用200MHz复位用异步复位。输出写入器监听输出端的valid信号把像素数据写入文本文件。整套仿真的关键是像素坐标对齐。我在Testbench里会生成一个简单的列计数器信号并且标记每个输出像素对应输入图像的行列坐标这样仿真结束后可以直接按坐标裁剪产生的图像避免因流水线延迟导致输出图像整体偏移、对齐不准。仿真跑完1080p一帧逻辑仿真大概需要几分钟到十几分钟不等视电脑性能而定。仿真过程中我会额外观察几个关键中间信号暗通道最小值是否合理一般无雾区域暗通道应该接近0雾浓区域暗通道值接近A、透射率是否在0到1范围、恢复后的图像三通道范围是否越界。4.2 板级验证与图像质量评估上板后连接HDMI输入输出接显示器或者采集卡。调试流程我建议分三步走——先看中间结果再看最终效果最后压测边界。第一步看中间结果很有价值。FPGA内部信号没法直接看图像但可以把暗通道、粗透射率、细化透射率这些中间结果用另一个通道输出我在板子上直接把透射率图单通道转RGB输出到HDMI这样在显示器上能直观确认透射率是否边缘保持、是否出现块状伪影。这种“把算法中间量可视化”的做法是我每做一个FPGA图像处理项目必用的调试手段比对着波形图猜快太多了。第二步看最终效果。接上真实摄像头的画面观察天空是否过曝、物体边缘是否有光晕、整体是否偏色。在雾天或严重灰霾条件下测试如果效果合适说明A估计和透射率恢复都正确。第三步压测边界。用低照度夜间图像测试是否放大噪声透射率接近0时恢复容易爆噪、用纯白墙画面测试是否出现条纹状色偏、用快速旋转相机测试大气光更新的滞后是否产生闪烁。实测下来最让人头疼的问题往往不是算法本身而是视频时序。FPGA图像处理的很多“算法效果问题”追根溯源其实是时序同步问题——帧同步不对、行计数错位、有效像素混入消隐区。4.3 关键时序与性能指标完成上述流程后系统可稳定跑到1080p60fps。核心透雾模块延迟从输入到输出约12us不到一行像素相比整帧16.7ms的周期来说可忽略不计。大气光更新周期为一帧在场景快速切换时会有轻微滞后我用寄存器配置了更新生效阈值A值变化超过阈值时采用自适应步长快速收敛。资源方面核心链路LUT不到8000BRAM 26块DSP 20个整体功耗比GPU方案低了两个数量级。这让我在后续接Zynq平台时非常从容因为留有大量资源去扩展其他ISP模块比如3DNR降噪、宽动态合成。5. 常见问题与调试心得实录做这个项目漂了一路坑把最典型的几个问题整理出来给后来者当避坑指南。5.1 常见问题与排查速查表现象可能原因排查思路与解决方案输出图像右侧出现竖向纹理错位行FIFO深度刚好等于有效行宽消隐期数据挤占FIFO行FIFO深度设为最大行宽加一些余量检查写入使能是否只在de有效时拉高透雾后天空区域出现一圈圈光晕透射率粗图直接用没做细化启用下采样导向滤波窗口半径不够就加大下采样倍率整个画面发灰对比度不足大气光A估计偏大恢复后没有做动态范围压缩改为分块统计暗通道最大值而非全局最亮像素恢复后加AWB和对比度拉伸夜间图像放大噪点严重透射率极小导致除法放大噪声增大t0下限或者叠加一个亮度相关的引导图让暗区透射率不至于太小场景快速切换时画面闪烁大气光A更新有延迟且增益变化跳变对A值做帧间平滑设置更新步长限制使能A变化超过阈值时的强制快速收敛算法输出正常但显示器显示黑色输出时序信号de、hsync、vsync没有对齐像素数据在输出模块中重新生成同步信号而不是直接透传输入端的信号输出端加FIFO缓存对齐跑仿真正常上板后图像偏色板级MIPI/HDMI的像素格式或通道顺序与预期不一致检查输入通道映射RGB565? RGB888? YUV422?在输入端增加颜色通道重排的可配置寄存器5.2 独家调试经验分享第一FPGA图像项目的仿真输入绝对不要用JPG直接转数据。JPG本身是有损压缩会在图像边缘产生振铃伪影这些伪影到算法里会被放大让你的调试分不清是算法问题还是输入数据本身的问题。一定用PNG或者BMP无压缩格式生成输入素材。第二调透雾参数时最好做一个“可在线调节的寄存器组”把暗通道窗口大小、ω、透射率下限t0、对比度增益、白平衡开关全部做成AXI-Lite寄存器。不要把任何参数硬编码。我最早为了省事把ω写成了常量0.85后来在一批逆光测试图上发现远处的细节恢复效果不稳定改成寄存器后几分钟就找到了合适的参数。第三验证时最终结果不要只看主观效果PSNR/SSIM指标要记录。客观指标能帮你判断“这个改动是变好了还是变坏了”尤其是你做版本迭代时没有指标记录全凭感觉到头来都不知道哪一版是最优的。第四如果想快速验证某个局部模块的改动就做一个“旁路模式”寄存器。让它可以跳过透雾直通输入输出。这样在上板时你可以用一块屏幕的画面左右分屏对比“透雾”和“非透雾”的差异结构调整的效率会高很多。最后串接在ISP管线里时Dehaze模块必须遵守上下游模块对像素格式的约定。如果上游是YUV422的数据你非要做RGB处理那你需要先做YCbCr转RGB处理完再转回去两个转换虽然公式不难但会引入精度误差4:2:0采样还会带来额外的色度信息损失。我在这项目里干脆选择了全程RGB888处理把输入端的格式转换和输出端的回转都做在透雾模块外面保证了透雾核心的数据一致性。这个基于FPGA的图像电子透雾项目做完之后一个很深的体会是FPGA上的ISP算法工程算法理解能力、硬件架构设计能力、调试耐心三者缺一不可。算法层面的“暗通道导向滤波”只是起点真正拉开差距的是你对资源、延迟、数据流的理解。只要把数据流理清了、中间过程验证扎实了一个中等规模的FPGA芯片上跑实时透雾并没有想象中那么遥不可及。后面如果再往深做我会考虑把透雾参数和3A模块联动起来做成一个真正自动化的ISP透雾子系统让不同天气条件下的画质稳定性再上一个台阶。现阶段这个版本至少已经能应对雾天、灰霾和轻度烟尘的实时视频增强需求了。
返回列表