FPGA图像处理HLS实现三种图像缩放算法,线性插值、双线性插值、双三次插值,提供HLS工程和vivado工程源码
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
目录
一、三种图像缩放算法介绍
线性插值
线性插值是针对一维数据的插值方法。它根据一维数据序列中需要插值的点的左右临近两个数据来进行数值估计。当然了它不是求这两个点数据大小的平均值在中心点的时候就等于平均值。而是根据到这两个点的距离来分配比重的。
已知点x0,y0、x1,y1求取插值点x处的y.推导过程如下
由于( y-y0)/(x-x0)=(y1-y0)/(x1-x0)
所以变换一下x-x0/(x1-x0)=(y-y0)/(y1-y0)=k
那么:y=(1-k)y0+ky1
比较方便记忆
双线性插值
在数学上双线性插值是有两个变量的插值函数的线性插值扩展其核心思想是在两个方向分别进行一次线性插值即从X方向进行两次线性插值得到R1、R2再对Y方向进行一次线性插值就可以得到P。见下图
假如我们想得到未知函数 f 在点 P = (x, y) 的值假设我们已知函数 f 在 Q11 = (x1, y1)、Q12 = (x1, y2), Q21 = (x2, y1) 以及 Q22 = (x2, y2) 四个点的值。最常见的情况f就是一个像素点的像素值。首先在 x 方向进行线性插值得到
然后在 y 方向进行线性插值得到
综合起来就是双线性插值最后的结果
双三次插值
双三次插值英文是Bicubic interpolation。双三次插值是一种更加复杂的插值方式它能创造出比双线性插值更平滑的图像边缘。双三次插值方法通常运用在一部分图像处理软件、打印机驱动程序和数码相机中对原图像或原图像的某些区域进行放大。Adobe Photoshop CS 更为用户提供了两种不同的双三次插值方法双三次插值平滑化和双三次插值锐化。
在数值分析这个数学分支中双三次插值英语Bicubic interpolation是二维空间中最常用的插值方法。在这种方法中函数f在点 (x,y) 的值可以通过矩形网格中最近的十六个采样点的加权平均得到在这里需要使用两个多项式插值三次函数每个方向使用一个。
双三次插值又叫双立方插值用于在图像中“插值”Interpolating或增加“像素”Pixel数量/密度的一种方法。通常利用插值技术增加图形数据以便在它打印或其他形式输出的时候能够增大打印面积以及或者分辨率。
目前有不同的插值技术可供选用。双立方插值通常能产生效果最好最精确的插补图形但它速度也几乎是最慢的。“双线性插值”Bilinear interpolation的速度则要快一些但没有前者精确。在商业性图像编辑软件中经常采用的是速度最快但也是最不准确的“最近相邻”Nearest Neighbor插值。其他一些插值技术通常只在高档或单独应用的程序中出现。
通过双三次插值可以得到一个连续的插值函数它的一阶偏导数连续并且交叉导数处处连续。
如上图所示我们在新生成的图像中像素点是f(x,y)先映射到源图像中的坐标为f(i+u,j+v)需要找到对应的原图像中离最近的16个点。
和前面介绍的双线性插值的分析方法类似http://blog.chinaaet.com/justlxy/p/5100052604我们可以分别对行和列进行依次处理。则有
则有
而s(*)表示的则是权值有多种计算方法模型常用的有Bicubic、Mitchell和Lanczos等这里简单介绍一下Bicubic函数
该函数波形如下图所示
Lanczos函数为
波形也是类似的
二、HLS实现线性插值图像缩放
在前面的详细介绍了三种图像缩放算法看起来很复杂很NB对吧
然并卵
然并卵
然并卵
因为对于HLS来说干这活儿只需要一句话一行代码即可实现
因为Xilinx早就帮你做好了三种图像缩放算法的库并且可以综合既然如此我还需要去管他怎么实现的算法公式是怎样的吗这就是HLS的NB之处。。。
线性插值图像缩放HLS工程如下
线性插值图像缩放综合后的延时、资源占用等性能参数如下
头文件如下
#ifndef _HELAI_HLS_RESIZE_H_
#define _HELAI_HLS_RESIZE_H_
#include "hls_video.h"
#define MAX_HEIGHT 1080 //图像最大高度
#define MAX_WIDTH 1920 //图像最大宽度
#define INPUT_IMAGE "luoli.jpg"
#define OUTPUT_IMAGE "luoli_out.jpg"
typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM;
typedef hls::Mat<MAX_HEIGHT,MAX_WIDTH,HLS_8UC3> RGB_IMAGE;
void helai_hls_resize(AXI_STREAM&INPUT_STREAM,AXI_STREAM&OUTPUT_STREAM,int s_rows,int s_cols,int t_rows,int t_cols);
#endif
源文件的核心代码如下三种算法共用一个工程用注释选择使用哪一种
这里选择线性插值
hls::Resize_opr_linear(img_0,img_1); //线性插值
//hls::Resize(img_0,img_1,HLS_INTER_LINEAR); //双线性插值
//hls::Resize_opr_bicubic(img_0,img_1); //双三次插值
核心代码就一句话BN吧呵呵。。。。。。
三、HLS实现双线性插值图像缩放
双线性插值图像缩放综合后的延时、资源占用等性能参数如下
源文件的核心代码如下三种算法共用一个工程用注释选择使用哪一种
这里选择双线性插值
//hls::Resize_opr_linear(img_0,img_1); //线性插值
hls::Resize(img_0,img_1,HLS_INTER_LINEAR); //双线性插值
//hls::Resize_opr_bicubic(img_0,img_1); //双三次插值
核心代码就一句话BN吧呵呵。。。。。。
四、HLS实现双三次插值图像缩放
双三次插值图像缩放综合后的延时、资源占用等性能参数如下
源文件的核心代码如下三种算法共用一个工程用注释选择使用哪一种
这里选择双三次插值
//hls::Resize_opr_linear(img_0,img_1); //线性插值
//hls::Resize(img_0,img_1,HLS_INTER_LINEAR); //双线性插值
hls::Resize_opr_bicubic(img_0,img_1); //双三次插值
核心代码就一句话BN吧呵呵。。。。。。
五、HLS在线仿真并导出IP
线性插值原图缩小到320X320的HLS在线仿真结果如下
线性插值原图放大到800X800的HLS在线仿真结果如下
双线性插值原图缩小到320X320的HLS在线仿真结果如下
双线性插值原图放大到800X800的HLS在线仿真结果如下
双三次插值原图缩小到320X320的HLS在线仿真结果如下
双三次插值原图放大到800X800的HLS在线仿真结果如下
从仿真效果来看三种图像缩放算法效果貌似一样看不出有啥区别。。。。或许我外行了
六、其他FPGA型号HLS在线仿真并导出IP
HLS工程的FPGA型号选的是zynq7100可在zynq系列上用若需要在其他FPGA型号上运行则仅需修改FPGA型号然后重新综合导出IP即可HLS工程需修改FPGA型号方法如下
综合如下
导出IP如下
生成的IP位置如下
在我提供的网盘资料中已经包好了zynq7100的HLS工程生成的IP对于zynq系列FPGA都适用
七、zynq7100开发板vivado工程
开发板Xilinx zynq7100开发板
开发环境HLS2019.1vivado2019.1
输入OV5640摄像头输入分辨率1280x720
输出11280x720输入1920x1080分辨率HDMI输出
输出21280x720输入放大到1920x1080分辨率HDMI输出
输出31280x720输入缩小到640x480分辨率HDMI输出
本例程使用的是双线性插值算法的IP需要使用其他算法IP的兄弟需自行将HLS工程改下选择需要的算法然后综合导出IP
工程BD如下
生成顶层RTL如下
SDK主函数源码如下
#include "I2C_16bit.h"
#include "xiicps.h"
#include "xil_io.h"
#include "xparameters.h"
#include "helai_vdma.h"
#include "helai_hls_resize.h"
void main()
{
// Initialize OV5640 regesiter
I2C_config_init();
helai_hls_resize(720,1280,1080,1920); //放大到1920x1080
//helai_hls_resize(720,1280,480,640); //缩小到640x480
helai_vdma();
while (1) ;
}
放大或者缩小直接由helai_hls_resize()函数灵活配置即可所以这里的放大和缩小共用一个工程即可
八、上板调试验证
zynq开发板实物连接如下
下载程序后的演示
输出11280x720输入1920x1080分辨率HDMI输出如下原图大小
输出21280x720输入放大到1920x1080分辨率HDMI输出
输出31280x720输入缩小到640x480分辨率HDMI输出
九、福利工程源码获取
福利工程代码的获取
代码太大无法邮箱发送以某度网盘链接方式发送
资料如下获取方式私。
网盘资料如下