第九章 基于金字塔融合的弱光照图像增强算法及其FPGA实现

📅 2026/6/30 10:30:03
第九章 基于金字塔融合的弱光照图像增强算法及其FPGA实现
市面上介绍FPGA图像处理的书籍大都是“由浅入深”但是最终却止步于一个个独立的算法模块。初学者非常容易陷入算法的FPGA实现细节中无法自拔更无法实现一个面向应用的图像处理系统。为了避免管中窥豹《ZYNQ视频图像处理》一书将从系统出发深入细节面向实战。因此磊哥会先介绍本书中最复杂的算法——基于金字塔融合的“弱光照图像增强”让大家能够从架构层去审视那些耳熟能详的算法看它们在系统中扮演着什么样的角色又是如何集成到一起从而实现实际的应用。9.1 弱光照图像在照明条件较差的环境中由摄像头采集到的图像或视频的质量会下降。在道路监控、安防、或者消费类电子产品中低照度图像将会影响系统的性能。我们将在本章讨论一种基于“金字塔图像融合”的弱光照图像增强算法并阐述在FPGA中实现该算法的架构。在我们的日常生活中使用手机拍照时拍摄的图像存在局部或者整体较暗的情况是很常见的。比如在夜间照明不良的情况下拍摄的图像会呈现出整体亮度和对比度较低的特点。或者在背光拍摄时由于曝光设置的限制较亮的背景和较暗的前景中的目标很难同时被捕获如下图所示图 9.1.1 背光拍摄的照片图 9.1.1是磊哥于2013年在华山之巅拍下的由于照片是在日出之时背光拍摄因此前景中的人物偏暗。这个问题出现的根本原因是数字相机的动态范围有限而现实世界中的动态范围较宽也就是说场景中光线的明暗差异较大。通过调整相机的曝光可以选择将有限的动态范围用于捕获较亮或者较暗的场景但是很难同时者兼顾因此图像会存在过曝或者欠曝的区域。9.2 多曝光图像融合在论文《Exposure fusion》T. Mertens, J. Kautz, F. V. Reeth,2007中提出可以使用多张不同曝光的图像进行融合从而得到一个高质量的图像如下图所示图 9.2.1 多张不同曝光图像的融合由于图 9.2.1中的方法需要对同一场景拍摄多张不同曝光的图像进行融合因此不适合用于针对视频流的处理。但是论文中介绍的基于金字塔分解的多曝光图像融合方法非常具有启示意义如下图所示图 9.2.2 基于金字塔分解的多曝光图像融合在图 9.2.2中对两张不同曝光的图像进行拉普拉斯金字塔分解并对每张图像的权重图进行高斯金字塔分解其中权重图用于衡量图像的对比度、饱和度等信息。在图像的欠曝和过曝区域通常呈现出灰度级平坦、缺少色彩等特征这些区域被赋于较低的权重而我们感兴趣的区域通常拥有较亮的颜色和更多的细节它们应该被保留。从图 9.2.2中的Weight Map中可以看出第一张图片主要保留建筑、灯光以及较亮的天空区域而第二张图则主要保留了建筑在水中的倒影、水面、以及较暗的天空区域。通过金字塔图像分解可以在不同尺度上对两张图像的特征进行融合从而避免最终混合得到的图像有明显的拼接痕迹。9.3 基于融合的弱光照图像增强在论文《A Fusion-based Enhancing Method for Weakly Illuminated Images》中提出了一种基于融合思想的弱光照图像增强方法。该方法采用图像金字塔分解技术将多种经典图像增强算法融合有效地取长补短使增强后的图像能够同时克服对细节增强、对比度提升和主观感知效果等方面都兼顾的难题。同时该方法的计算复杂度较低易于实现。论文中提出的算法框架如下图所示图 9.3.1 基于融合的弱光照图像增强算法值得一提的是该论文由厦门大学傅雪阳博士、曾德炉教授等人合作并获得了欧洲信号处理学会旗下的期刊Signal Processing 2020年度唯一最佳论文奖。不同于前面所提到的多张曝光图像的融合图 9.3.1中的算法可以应用于单张图像因此更适合视频流处理。磊哥基于该算法框架进行了FPGA架构设计如图 9.3.2所示。图 9.3.2 基于融合的弱光照图像增强算法FPGA架构图在上图所示的FPGA架构图中最左侧输入的是弱光照条件下的彩色原始图像经过RGB转HSV模块将亮度、饱和度和色调分离出来。分离出来的亮度信息将通过派生输入图像模块获取额外两张灰度图像它们分别代表了亮度增强和对比度增强后的结果。此外派生输入图像模块还会计算出三张灰度图像各自的权重信息模块输出的权重图和亮度图将按照图 9.2.2中所示的方法进行金字塔分解与融合。接下来分别对三个权重图像进行三层高斯金字塔分解同时对三个亮度图像进行三层拉普拉斯金字塔分解。分解得到的各层权重和亮度信息会在每一层上进行金字塔融合然后进行金字塔反向重构重构得到的灰度图像在增强了暗部区域的同时兼顾了图像的对比度。金字塔反向重构后的结果相比于输入的视频流会存在多行的延迟因此需要在行缓存模块中对色调和饱和度信息延迟相同的行数然后在数据流对齐模块中对H、S、V三个通道进行对齐操作。对齐之后的HSV通道由HSV转RGB模块转换成彩色图像这就是算法最终输出的弱光照增强图像。磊哥在Xilinx A7系列的FPGA上实现了整个设计Vivado源文件层次目录如下图所示图 9.3.3 FPGA设计的源文件层次目录9.4 派生输入图像派生输入图像VIP_DL_Derived_Input模块用于从灰度图像中获取亮度增强和对比度增强的图像加上原始的灰度图像一共输出三张亮度图用于后续的融合。同时输出的还有三张亮度图所对应的权重图像其FPGA架构如下图所示图 9.4.1 派生输入图像VIP_DL_Derived_Input模块架构图图 9.4.1中的直方图均衡模块用于提升图像的全局对比度伽马校正模块用于提升图像暗部区域的亮度和对比度另外还要对输入的原始亮度图像进行延迟从而与对比度增强和亮度增强的结果进行同步。接下来对三张亮度图像分别计算亮度权重和对比度权重。在亮度权重模块中对于曝光良好的像素赋予更高的权重对于过曝或者欠曝的像素赋予较低的亮度权重。我们使用高斯曲线来衡量不同亮度所对应的权重计算方式如下公式中的k代表三张灰度图在计算像素点的对比度时权重时需要注意对比度并不是单一地由亮度信息决定还要考虑到色彩信息。因此对比度权重模块需要同时使用HSV三个通道进行计算图中没有画出色调和饱和度信息。对比度权重的计算方式如下公式中α 2φ 250◦在权重归一化模块中每个图像的亮度权重和对比度权重进行相乘然后三个图像的相乘之后的权重进行归一化之后分别输出。计算方式如下需要注意的是在图 9.4.1中三个亮度图像Bright0~Bright2需要进行延迟从而与归一化后的三张权重图像进行同步。9.5 图像金字塔的分解与重构如果直接对派生输入图像模块输出的权重图和亮度图进行融合将会在融合后的图像中产生伪影严重影响增强后的图像的视觉效果如下图所示图 9.5.1 左原始图像 中直接融合图像 右多尺度融合图像图 9.5.1中间的图像为三个权重图像和亮度图像直接进行融合的结果由于权重图像并不平滑不同亮度区域的权重有剧烈的变化因此导致融合后的图像有伪影比如小女孩的面部区域。而最右侧的图像采用了基于图像金字塔的多尺度融合该方法混合的是图像的特征而不是亮度因此具有较好的效果。三层高斯金字塔和拉普拉斯金字塔的分解与重构过程如下图所示图 9.5.2 三层图像金字塔的分解与重构过程高斯金字塔的第一层就是输入的灰度图像先对其进行高斯滤波然后进行下采样即可得到第二层的高斯金字塔。第二层金字塔的尺寸是第一层金字塔的四分之一。对第二层高斯金字塔重复上面的操作即先进行高斯滤波再下采样即可得到第三层高斯金字塔。在高斯金字塔分解的基础上可以得到拉普拉斯金字塔又称拉氏金字塔。我们对第二层高斯金字塔先进行上采样再进行高斯滤波最后与高斯金字塔的第一层作差即可得到第一层拉氏金字塔。同样对第三层高斯金字塔进行上采样和高斯滤波并与第二层高斯金字塔作差可以得到第二层拉氏金字塔。而第三层拉氏金字塔与第三层高斯金字塔是完全相同的。从图 9.5.2中可以看出拉氏金字塔包含了图像不同尺度上的细节信息特征而高斯金字塔则包含了图像不同尺度上的背景信息。我们将不同图像的权重高斯金字塔与亮度拉普拉斯金字塔进行融合可以达到融合图像特征的效果。在金字塔的反向重构过程中我们对拉氏金字塔的第三层进行上采样和高斯滤波然后与第二层拉氏金字塔相加即可以得到重构的第二层金字塔。接下来对重构得到的第二层金字塔重复上采样和高斯滤波的操作并与第一层拉氏金字塔相加即可得到重构的第一层金字塔也就是最终的输出图像。在FPGA中实现图像金字塔的分解与重构最大的难点在于如何进行流水的设计磊哥设计实现的FPGA金字塔架构如下图所示图 9.5.3 FPGA实现金字塔的分解与重构图 9.5.3中的卷积操作使用的是3x3的高斯卷积核下采样直接隔行隔列抽取像素数据即可上采样使用的是临近值插值。需要注意的是在获取拉氏金字塔的时候需要对上层高斯金字塔和下层高斯金字塔经过上采样和高斯滤波的结果进行作差另外在反向重构的过程中需要用上层拉氏金字塔与下层重构金字塔经过上采样和高斯滤波的结果进行求和。在作差和求和的过程中需要对两路视频流进行同步因此FPGA实现图像金字塔的分解与重构时需要耗费较多的RAM资源用于缓存图像在图 9.5.3中使用“Delay”标志该过程。FPGA中实现三层高斯金字塔的RTL视图如图 9.5.4所示其中VIP_DL_Gauss_Filter模块实现高斯滤波VIP_DL_Down_Sample模块实现下采样。另外VIP_DL_Line_Buffer模块用于对第一层和第二层高斯金字塔进行延迟以达到与拉氏金字塔的第一层和第二层同步的目的从而能够进行后续的融合操作。图 9.5.4 FPGA实现三层高斯金字塔RTL视图在介绍了如何在FPGA中实现高斯和拉普拉斯金字塔之后下面的图就很容易理解了。图 9.5.5展示了亮度拉氏金字塔和权重高斯金字塔的融合过程。从图中可以看出我们对权重高斯金字塔的第一层和第二层做了延迟以达到与拉氏金字塔的第一层和第二层同步的目的。为了使该示意图不显得过于复杂这里我们只画出了一个亮度金字塔及其权重金字塔在每一层上的乘法运算即图 9.5.5中的“Mult”标志。实际上在金字塔的每一层乘法运算之后还会与其余两个图像的乘积结果一起进行求和从而实现三张图像的亮度和权重金字塔的融合与重构。图 9.5.5 亮度拉氏金字塔和权重高斯金字塔的融合与重构9.6 Vivado仿真结果为了能够直观地分析FPGA图像处理算法的实现结果磊哥在Vivado中搭建了基于AXI4-Stream接口的FPGA图像处理算法仿真平台。该仿真平台可以输入BMP格式的测试图像并将仿真的结果以及中间过程以BMP图片的形式打印出来除此之外它还支持修改分辨率以应对不同尺寸的测试图像。这里我们分别选择室内和室外两种场景下的弱光照图像用于Vivado仿真测试图像的分辨率为640*480p。以下是基于金字塔融合的弱光照图像增强算法的FPGA仿真结果图 9.6.1 室内弱光照图像增强效果左侧为原图右侧仿真结果图 9.6.2 室外弱光照图像增强效果左侧为原图右侧仿真结果从上面的两个仿真结果中我们可以直观地感受到算法对弱光照图像的增强效果。以图 9.6.2为例相比于左侧图像中昏暗的夜景右侧仿真结果的图像亮度得到了明显的提升。而且增强后图像的对比度也得到了保留无论是近处的车辆与树木还是远处的楼宇和云朵纹理层次都清晰可见。这一刻时间仿佛按下了快进瞬间从深夜来到了清晨。在Vivado仿真过程中还输出了亮度拉氏金字塔和权重高斯金字塔在每一层上的融合结果以及金字塔反向重构的结果如下所示图 9.6.3 金字塔在每一层上的融合结果共三层图 9.6.4 金字塔反向重构的结果灰度图9.7 ZYNQ开发板下载验证磊哥将“基于金字塔融合的弱光照图像增强算法”部署在了【征服者】ZYNQ开发板上其PL部分等同于Xilinx A7系列的FPGA。在ZYNQ 7020芯片上的资源占用情况如下图所示图 9.7.1 ZYNQ 7020 FPGA资源消耗最后我们使用两种方式对算法的FPGA实现结果进行验证。第一种方式是使用SD卡加载测试图像然后通过VDMA将图像输入到PL端的算法中进行处理最后将处理结果再写回SD卡中。经过对比写回SD卡中的图像处理结果与前面的仿真结果完全一致说明基于金字塔融合的弱光照图像增强算法在ZYNQ开发板上验证成功。第二种方式是通过OV5640摄像头采集实时画面然后在PL中进行图像处理最后通过HDMI接口将增强后的图像显示出来。这种方式能够证明该算法可以在FPGA中进行实时的视频处理。需要注意的是基于金字塔融合的弱光照图像增强算法是本书中最复杂的算法磊哥花了整整一个月的时间完成其FPGA设计。大家只需要将本章的内容作为科普大致了解算法的原理以及FPGA实现架构而具体的技术细节将在后续的章节中逐一讲解。如果对本章内容有疑问可以添加磊哥的V进行交流DaLei_FPGA。大家也可以到磊哥的B站大磊FPGA观看本章节配套的视频教程以及下载验证的演示视频