紫光同创FPGA实现图像去雾 基于暗通道先验算法 纯verilog代码加速 提供2套工程源码和技术支持
1、前言
2019年初我刚出道时,还是Xilinx遥遥领先的时代(现在貌似也是),那时的国产FPGA还处于黑铁段位,国产FPGA仰望Xilinx情不自禁道:你以为躲在这里就找不到你吗?没用的,你那样拉轰的男人,无论在哪里,都像黑夜里的发光虫那样的鲜明、那样的出众,你那忧郁的眼神,稀嘘的胡渣子,神乎其技的刀法,还有那杯Dry martine,都深深的迷住了我。。。然而才短短4年,如今的国产FPGA属于百家争鸣、百花齐放、八仙过海、神仙打架、方兴未艾、得陇望蜀、友商都是XX的喜极而泣之局面,面对此情此景,不得不吟唱老人家的诗句:魏武挥鞭,东临碣石有遗篇,萧瑟秋风今又是,换了人间。。。
言归正传,目前对于国产FPGA的共识有以下几点:
1:性价比高,与同级别国外大厂芯片相比,价格相差几倍甚至十几倍;
2:自主可控,国产FPGA拥有完整自主知识产权的产业链,从芯片到相关EDA工具
3:响应迅速,FAE技术支持比较到位,及时解决开发过程中遇到的问题,毕竟中文数据手册。。
4:采购方便,产业链自主可控,采购便捷
没玩过图像处理都不好意思说自己玩儿过FPGA,这是CSDN某大佬说过的一句话,鄙人深信不疑。。。本文使用紫光同创的PGL22G-6MBG324 FPGA实现暗通道先验算法图像去雾,输入视频采用静态图片或者OV5640摄像头模组,所以提供2套PDS工程源码,第一套采用SD卡提供静态图片作为视频输入,第二套采用OV5640摄像头作为视频输入;FPGA采集到视频数据后,首先将视频送入DDR3中做乒乓缓存后读出,然后视频经过图像去雾模块处理后送入HDMI输出模块,最后送显示器输出显示;
本博客详细描述了紫光同创FPGA实现图像去雾的设计方案,工程代码可综合编译上板调试,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做学习提升,可应用于医疗、军工等行业的高速接口或图像处理领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;
免责声明
本工程及其源码即有自己写的一部分,也有网络公开渠道获取的一部分(包括CSDN、Xilinx官网、Altera官网等等),若大佬们觉得有所冒犯,请私信批评教育;基于此,本工程及其源码仅限于读者或粉丝个人学习和研究,禁止用于商业用途,若由于读者或粉丝自身原因用于商业用途所导致的法律问题,与本博客及博主无关,请谨慎使用。。。
本去雾模块的特点
1:纯verilog代码实现,模块本身可在各种FPGA间自由移植;
2:采用基于暗通道先验算法实现,理论较为成熟;
3:本模块目前并不完善,还存在BUG,对输入视频或图像要求较高,所以我提供一个处理效果较好的视频源和图片给大家,其他视频源或图片不能保证能很好地去雾,推荐的视频源链接如下:
直接点击前往
4:模块还在持续优化中,会实时更新。。。
2、目前我这里已有的图像处理方案
目前我这里已有的图像处理方案有很多,包括图像缩放、图像拼接、图像旋转、图像识别跟踪、图像去雾等等,所有工程均在自己的板子上跑通验证过,保证代码的可靠性,对图像处理感兴趣或有项目需求的兄弟可以参考我的图像处理专栏,里面包含了上述工程源码的详细设计方案和验证视频演示:直接点击前往
3、设计思路框架
本文使用紫光同创的PGL22G-6MBG324 FPGA实现暗通道先验算法图像去雾,输入视频采用静态图片或者OV5640摄像头模组,所以提供2套PDS工程源码,第一套采用SD卡提供静态图片作为视频输入,第二套采用OV5640摄像头作为视频输入;FPGA采集到视频数据后,首先将视频送入DDR3中做乒乓缓存后读出,然后视频经过图像去雾模块处理后送入HDMI输出模块,最后送显示器输出显示;
第一套PDS工程设计思路框架如下:
第二套PDS工程设计思路框架如下:
SD卡初始化
第一套工程使用了此模块,SD 卡初始化模块完成对SD卡的上电初始化操作,严格按照SD卡初始化流程写出上电时序,采用三段式状态机方式实现,代码位置如下:
由于这部分代码很简单,所以不过多描述,可自行百度SD卡初始化流程时序;
SD卡读操作
第一套工程使用了此模块,作用是根据SD卡读时序对其进行读数据操作,代码位置如下:
由于这部分代码很简单,所以不过多描述,可自行百度SD卡读时序;
SD卡读图片
第一套工程使用了此模块,作用是将图片从SD卡里读出来,代码位置如下:
这个模块很重要,他直接关系到能否正确读出图片,里面有两个参数很重要,可能需要修改,如下:
这两个参数是2张图片在SD卡中的扇区地址,由于不同的图片在SD卡中的扇区地址可能不同,所以这两个参数需要根据你的实际情况来修改,那么SD卡中图片的扇区地址如何查看呢?使用我提供的WinHex工具查看,WinHex软件在提供的压缩资料包里面,方法如下:
注意:如果提示缺少管理员权限,是否重新程序 WinHex,选择“是”,然后重新选择“打开磁盘”。
在“物理驱动器”下,我们看到上图标记位 2 的地方有 RM2、Generic STORAGE DEVICE(14.8GB,USB)的字样,该物理驱动器对应的是 TF 卡,标号为 RM2,我们找到标号 RM2 在逻辑驱动器中的位置即箭头 1 所指的地方,选中后点击“确定”按钮即可查看文件的起始扇区地址,打开后的界面如下图所示:
可以看到:
第一张图片的物理扇区地址为22122;
第二张图片的物理扇区地址为16672;
与我们SD卡读图片模块的配置地址一致,如下:
OV5640摄像头配置及采集
第二套工程使用了此模块,OV5640摄像头需要i2c配置才能使用,需要将DVP接口的视频数据采集为RGB565或者RGB888格式的视频数据,这两部分均用verilog代码模块实现,代码位置如下:
其中摄像头配置为分辨率1280x720,如下:
摄像头采集模块支持RGB565和RGB888格式的视频输出,可由参数配置,如下:
RGB_TYPE=0输出本RGB565格式;
RGB_TYPE=1输出本RGB888格式;
本设计使用RGB888格式;
HDMA图像缓存
工程一和工程二均用到了此模块,HDMA图像缓存的本质就是一个封装了用户接口的AXI4-FULL-MASTER总线,HDMA对外与DDR3交互,紫光同创FPGA自带的DDR3控制器的用户接口为AXI4-FULL总线,HDMA对内例化两个FIFO与FPGA内部逻辑交互,所以开发者在使用HDMA时,已无需再关心复杂的为AXI4-FULL协议,只需要像使用FIFO那样简单即可;HDMA架构如下:
代码架构如下:
输入输出视频
输入视频的数据格式为RGB,即典型的pclk、vs、de、rgb形式的VGA视频时序,但需要注意的是,因为输入视频直接与FIFO交互,FIFO的AXI侧的数据位宽为128位,为了数据的不错位,输入视频的rgb信号接口不能为传统的24位,这里可以设置为16或者32位,代码中通过参数配置,我配置为32位,如下:
HDMA缓冲FIFO
例化两个FIFO作为FPGA逻辑数据与AXI4数据的缓冲,所谓缓冲,即数据位宽的转换、时钟域的转换、读写时机的控制等部分,FPGA逻辑侧的数据位宽为32位,AXI4侧的数据位宽为128位;以写FIFO为例,配置如下:
HDMA控制模块
HDMA控制模块的主要功能是实现AXI4-FULL主机和图像缓存读写地址切换两大功能;AXI4-FULL主机比较简单,照着AXI4-FULL时序图写就完事儿了,图像缓存读写地址切换就难了,本设计通过顶层的参数来配置图像缓存的帧数,如下:
HDMA_PINGPANG_EN=1则图像做三帧缓存;
HDMA_PINGPANG_EN=0则图像做单帧缓存;
本设计配置为HDMA_PINGPANG_EN=1;
为了实现图像的多帧缓存,将读写地址分段,如下:
读写地址=帧地址+数据地址;
数据地址:即正常的AXI4数据突发的地址增量;
写帧地址:一帧图像到来时+1;
读帧地址:一帧图像到来时+2;
如此做到了同时读写不同的帧地址,输出的图像是完美的。。。
这也叫做乒乓操作,核心代码如下:
图像去雾模块详解
暗通道先验-图像去雾由3个模块顺序执行,3个模块内部并行执行,实现了FPGA加速算法的目的,分别由求RGB最小值和求折射率以及图像去雾组成,框图如下:
求RGB最小值的目的是实时的比较求出每个像素点RGB分量的最小值,也就是暗通道,该模块顶层接口如下:
求折射率的目的是输出暗通道最大值和折射率,该模块顶层接口如下:
图像去雾的目的是输出暗通道最大值和折射率,该模块顶层接口如下:
三个模块整合封装后的图像去雾模块接口如下:
HDMI输出
HDMI输出包括VGA时序和HDMI编码模块,VGA时序在紫光PGL22G-6MBG324 FPGA上只能做到720P,因为此FPGA可能太低端了,无法输出742.5M的串行时钟,当然,你用HDMI编码芯片是可以实现1080P的,所以这里只能做到720P的输出分辨率;HDMI编码模块待用原语实现,和Xilinx家的一样,代码结构如下:
4、PDS工程1详解:SD卡提供有雾图片
开发板FPGA型号:紫光同创--PGL22G-6MBG324;
开发环境:Pango Design Suite 2021.4
输入:SD卡里的有雾图片,分辨率1280x720;
输出:HDMI,分辨率1280x720;
工程作用:紫光同创FPGA实现图像去雾;
工程代码架构如下:
工程的资源消耗和功耗如下:
工程已经综合编译完成,如下:
5、PDS工程2详解:OV5640输入
开发板FPGA型号:紫光同创--PGL22G-6MBG324;
开发环境:Pango Design Suite 2021.4
输入:OV5640输入,分辨率1280x720;
输出:HDMI,分辨率1280x720;
工程作用:紫光同创FPGA实现图像去雾;
工程代码架构如下:
工程的资源消耗和功耗如下:
工程已经综合编译完成,如下:
6、上板调试验证并演示
准备工作
你需要有以下装备才能移植并测试该工程代码:
1:FPGA开发板;
2:SD卡或OV5640摄像头,如果没有也可以,就选择动态彩条;
3:HDMI传输线;
4:HDMI显示,要求分辨率支持1280x720;
SD卡制作
准备一张SD卡,两张一模一样的带有雾气的图片,图片需要旋转180°,我已准备好并放在了资料包里,将SD卡格式化,然后将图片复制粘贴进去,再用WinHex软件查看两张图片的物理扇区地址,并在SD卡读图片模块中修改扇区地址的值,详情参考前面的SD卡读图片章节;我提供的有雾图片在资料包的路径如下:
静态演示
工程1:SD卡读取图片输入1280x720分辨率图像去雾后HDMI输出静态演示如下:
原始有雾图像:
图像去雾处理后的输出图像如下:
工程2:ov5640摄像头输入1280x720分辨率图像去雾后HDMI输出静态演示如下:
动态演示
仅以工程2的OV5640输入的动态视频演示如下:
点击观看视频
7、福利:工程源码获取
福利:工程代码的获取
代码太大,无法邮箱发送,以百度网盘链接方式发送,
通过微信获取资料:
资料如下: