上一章介绍了如何在FPGA中使用最近邻插值的方法实现图像的放大,本章继续介绍如何在FPGA中使用双线性插值的方法从而实现对图像的放大。
首先更正上一章的一个错误,29%的RAM资源消耗是1280×1024的图像,对于640×512的图像实际RAM资源消耗是15%。
放大示意图如下图所示,首先根据不同的放大倍数得到原图像A中小图b的左上角起始坐标,然后通过双线性插值得到放大后的图像B,图像B的尺寸与原图像A大小一致。
双线性插值原理的介绍网上很多,这里不做介绍,直接上公式。
其中B为放大之后的图像,i为B图像的横坐标,j为B图像的纵坐标, A为放大之前的原图,A(x,y)、A(x+1,y)、A(x,y+1)、A(x+1,y+1)分别为双线性插值计算需要的4个点,u、v为相对距离,计算公式如下。
FPGA的优势在于可以对图像进行流水处理,从而实现算法加速,而公式1需要同时取到原图像中4个点才能进行,因此可以对公式1进行相应的变换,首先在列上进行处理,然后再在行上进行处理,变换后的公式如下。
变换之后u、v是分开的,因此可以首先在列上进行处理,即根据公式2计算得到的坐标位置进行如下运算。
列上计算完成之后进行图像行上的运算,计算公式如下。
根据上面的公式既可以完成基于双线性插值的图像放大操作。
程序一共分为3个模块,第一个模块根据公式4首先完成每一行内即列上插值像素的处理,第二个模块根据公式2计算图像中心区域左上角起始坐标位置(up,left),第三个模块根据计算公式5完成图像的缓存以及对应行图像的提取。
程序的接口如下图所示。
信号名 |
信号含义 |
Img_W |
图像宽 |
Img_H |
图像高 |
Pixel_Size |
像素位宽 |
Clk_Freq |
像素时钟频率 |
Img_Freq |
图像帧频 |
Line_Spac |
行消隐 |
Line_Front |
行前肩 |
Line_Back |
行后肩 |
clk |
像素时钟 |
Zoom_Sel |
放大倍数,支持1.1~32倍无极放大,1.1倍放大对应Zoom_Sel为11,以此类推 |
img_v_i |
输入图像场同步信号 |
img_h_i |
输入图像行有效信号 |
img_pix_i |
输入图像数据 |
img_v_o |
输出图像场同步信号 |
img_h_o |
输出图像行同步信号 |
img_pix_o |
输出图像数据 |
对于大小为640×512的图像,在K7-325T中资源消耗情况如下所示。
放大2.8倍的FPGA仿真时序图如下图所示。
下图是放大2.8倍,原图、matlab放大效果图以及fpga放大效果图对比如下所示。
放大4.5倍的FPGA仿真时序图如下图所示。放大倍数越大,处理完的图像输出延时越大,但是均能保证当帧实时处理。
下图是放大4.5倍,原图、matlab放大效果图和fpga放大效果图。
下一章继续介绍,在FPGA中用双三次插值实现无极放大。
需要FPGA和Matlab源码的可以加微信L_cola1。