Verilog实现基于双线性插值算法的图像放大IP设计
本文主要介绍一下verilog实现基于双线性插值算法的图像放大IP的实现思路,最终利用该方法实现了实时的图像放大处理。关于双线性插值的原理,网上有很多讲解的特别好的帖子,本文就不再赘述原理部分,而是重点根据该原理设计硬件实现方案。
背景
随着各种处理平台的计算能力的逐步提升,人们在各个领域对于视频图像的清晰度以及分辨率要求越来越高,然而有时在数据源端并不能直接获得高分辨率的视频或图像,这时候往往希望可以将获取的视频或者图像进行放大后在输出给后端或者直接用于显示,(1) 比如在红外领域,由于目前的红外传感器的分辨率都比较低,为了得到高分辨率图像经常会使用图像放大方法进行处理;(2) 在某些视频图像处理应用中,希望可以将原始图像的中的部分区域放大到全幅面输出,这也需要用到图像放大处理。
目前在图像放大算法方面,较为常用的传统方法包括最邻近插值、双线性插值、双三次插值、多项插值等等,近年来基于深度学习/神经网络的图像放大方法取得了更好的效果,这些方法在基于PC的平台都比较容易实现。然而对于硬件应用领域(FPGA或IC),仍然是传统方法所占比重较大,传统方法中最邻近插值算法计算量最小,但是这种方法得到放大图像中经常会存在很严重的锯齿,而双线性插值方法的计算量稍大一些,但是图像放大效果也较最邻近插值提升很多,而对于双三次插值、多项插值等算法,效果比较好但是计算很复杂,因此本文的重点是基于双线性插值算法设计图像放大IP,可以应用于IC或者FPGA实现实时的视频放大处理,在文章的最后,介绍了本IP消耗的资源以及功能仿真结果。
本文设计的图像放大IP的规格
- 输出分辨率:1920*1080,实现实时处理
- 输入分辨率:可调节(处理时钟频率与源数据像素时钟频率的比例限制了放大的倍数)
- 视频放大原理:基于双线性插值方法
- 所需存储资源:需要存储三行原始图像数据,无需缓存整帧图像
- IP端口信号介绍:
clk :源数据像素时钟信号
clk_proc:处理时钟信号
rst_n :复位,低电平有效
vsync_i :视频数据流场(帧)同步信号
de_i :视频数据流数据有效信号
data_i :视频数据流输入数据信号
src_width_i :输入视频的宽度
src_height_i:输入视频的高度
valid_o :插值放大后视频的数据有效信号
data_o :插值放大后视频的数据信号 - 本IP可以将任意输入视频(将原始视频宽度和高度通过src_width_i端口和src_height_i端口进行配置)进行双线性插值放大到1920x1080输出
硬件方案架构图
为了更加清晰的表示本IP的整体架构,利用vivado软件将本ip的源代码进行了综合,IP顶层架构图如下所示:
子模块功能介绍
input_buffer模块:
接收前端输入的原始视频数据(clk是源数据像素时钟信号),然后完成跨时钟域处理,以clk_proc(时钟频率高于clk信号)高速处理时钟信号输出数据到buffer_ctrl模块中。该模块的主要功能就是实现跨时钟域处理,当buffer_ctrl模块准备好(ready信号拉高)接收数据时,将数据以clk_proc时钟发送到buffer_ctrl模块。
buffer_ctrl模块:
实现源数据的缓存,以便于后续进行双线性插值计算过程使用。该模块主要是实现数据缓存,以及实现数据缓存的控制。当该模块准备好接收数据时,接收前端input_buffer模块发送过来的数据并将数据进行缓存,同时根据缓存的数据情况,控制后端的scaler_ip模块开始工作,当后端的scaler_ip模块开始工作时,从本模块中读取缓存的数据用于计算放大图像。
scaler_ip模块:
该模块的功能就是利用双线性插值方法实现图像插值放大,当前端buffer_ctrl模块使能scaler_en_o信号后,本模块开始工作,从前端buffer_ctrl模块中读取缓存的数据,然后计算每个数据对应的权重系数,最终利用四个像素点的原始灰度值以及每个像素点对应的权重系数,利用双线性插值算法计算得到最终的插值放大图像,并将插值结果输出。
功能仿真结果
功能仿真波形:
下面贴几张功能仿真的结果图像(将功能仿真结果存到txt文本中,然后利用matlab转成图像,最终结果如下所示,因为csdn无法上传过大的图像,因此是将放大结果压缩后上传的,所以上传的图像质量降低了很多)
-
输入图像分辨率:960x540
通过本IP经过功能仿真放大到1920x1080结果:
-
输入图像分辨率:600x600
通过本IP经过功能仿真放大到1920x1080结果: