FPGA图像处理HLS实现三种图像缩放算法,线性插值、双线性插值、双三次插值,提供HLS工程和vivado工程源码

article/2025/9/23 15:12:22

目录

  • 一、三种图像缩放算法介绍
    • 线性插值
    • 双线性插值
    • 双三次插值
  • 二、HLS实现线性插值图像缩放
  • 三、HLS实现双线性插值图像缩放
  • 四、HLS实现双三次插值图像缩放
  • 五、HLS在线仿真并导出IP
  • 六、其他FPGA型号HLS在线仿真并导出IP
  • 七、zynq7100开发板vivado工程
  • 八、上板调试验证
  • 九、福利:工程源码获取

一、三种图像缩放算法介绍

线性插值

线性插值是针对一维数据的插值方法。它根据一维数据序列中需要插值的点的左右临近两个数据来进行数值估计。当然了它不是求这两个点数据大小的平均值(在中心点的时候就等于平均值)。而是根据到这两个点的距离来分配比重的。
在这里插入图片描述
已知点(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.1;vivado2019.1;
输入:OV5640摄像头,输入分辨率1280x720;
输出1:1280x720输入,1920x1080分辨率HDMI输出;
输出2:1280x720输入,放大到1920x1080分辨率HDMI输出;
输出3:1280x720输入,缩小到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 regesiterI2C_config_init();helai_hls_resize(720,1280,1080,1920);	//放大到1920x1080//helai_hls_resize(720,1280,480,640);	//缩小到640x480helai_vdma();while (1) ;
}

放大或者缩小,直接由helai_hls_resize()函数灵活配置即可,所以这里的放大和缩小共用一个工程即可;

八、上板调试验证

zynq开发板实物连接如下:
在这里插入图片描述
下载程序后的演示:
输出1:1280x720输入,1920x1080分辨率HDMI输出如下原图大小:
在这里插入图片描述
输出2:1280x720输入,放大到1920x1080分辨率HDMI输出;
在这里插入图片描述
输出3:1280x720输入,缩小到640x480分辨率HDMI输出;
在这里插入图片描述

九、福利:工程源码获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料如下:获取方式:私,或者文章末尾的V名片。
网盘资料如下:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/H0qJHnL9.shtml

相关文章

数字图像处理100问—27 双三次插值( Bicubic Interpolation )

提示&#xff1a;内容整理自&#xff1a;https://github.com/gzr2017/ImageProcessing100Wen CV小白从0开始学数字图像处理 27 双三次插值&#xff08; Bicubic Interpolation &#xff09; 使用双三次插值将图像放大1.5倍 双三次插值是双线性插值的扩展&#xff0c;使用邻域…

用于数字成像的双三次插值技术​

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶” 重磅干货&#xff0c;第一时间送达 双三次插值是使用三次或其他多项式技术的2D系统&#xff0c;通常用于锐化和放大数字图像。在图像放大、重新采样时&#xff0c;或是在软件中润饰和编辑图像时也会使到用…

插值算法(最邻近差值、双线性插值、双三次插值)

一、最邻近差值&#xff08;nearest&#xff09; 含义&#xff1a; 选取离目标点最近的点的值作为新的插入点的值。 两幅图坐标值变换关系&#xff1a; &#xff08;代码未验证&#xff09; for i1:size(dist,1)x round(i* (size(src,1)/size(dist,1))); %dst横坐标变换到s…

matlab双线性插值双三次插值对CUFED5进行处理

本文是摘抄与总结&#xff0c;仅供自己学习和日后查阅使用。 可以自己写一个双线性插值函数&#xff0c; ------------------------------------------------------------------- function outputimg my_imresize(A,n) % A 是图像矩阵,n是放缩的倍数 % 返回值outputimg是一…

双三次插值算法的C++实现与SSE指令优化

在上篇文章中&#xff0c;我们讲解了常见的最邻近插值算法、双线性插值算法和双三次插值算法的原理与实现&#xff0c;三种插值算法中双三次插值算法的插值效果最好&#xff0c;但其也是三种算法中计算复杂度最高、耗时最长的算法。本文在给出双三次插值C代码的基础上&#xff…

双三次插值 - 插值图像任意位置亚像素C++

双三次插值 - 插值图像任意位置亚像素C 一、概念 双三次插值又称立方卷积插值。三次卷积插值是一种更加复杂的插值方式。该算法利用待采样点周围16个点的灰度值作三次插值&#xff0c;不仅考虑到4 个直接相邻点的灰度影响&#xff0c;而且考虑到各邻点间灰度值变化率的影响。…

matlab 给图像双三次,图像灰度的双三次插值的MATLAB实现

相比C/C实现&#xff0c;图像灰度的双三次插值的MATLAB实现要方便的多&#xff0c;下面是MATLAB语言实现 clc,clear; ffimread(C:\Program Files\MATLAB\R2013a\bin\work\lena.bmp); [mm,nn]size(ff);%将图像隔行隔列抽取元素&#xff0c;得到缩小的图像f mmm/2;nnn/2; fzeros(…

java 双三次线性插值_三种常见的图像处理双三次插值算法

三种常见的图像处理双三次插值算法 双立方插值计算涉及16像素,间(i’, j’)像中的包括 小数部分的像素坐标。dx表示X方向的小数坐标。dy表示Y方向的小数坐标。 详细 能够看下图: 依据上述图示与双立方插值的数学表达式能够看出。双立方插值本质上图像16个像素点 权重卷积之和…

双三次插值 python实现_Python:用GPU实现双三次插值

它不是GPU(而是尝试利用线程和CPU的向量单元)&#xff0c;但是pyvips比scipy快很多&#xff0c;您可以测试一下。在 我做了个基准&#xff1a;import sys import time import scipy.ndimage import pyvips scale 10 n_loops 10 start time.time() test_image scipy.ndimage…

双三次插值及Matlab实现

双三次插值及Matlab实现 一、简单实例 采用简单实例进行对双三次插值的介绍&#xff0c;由于双三次插值对于目标图像的某一像素进行估计时&#xff0c;所采用的像素信息为其周围16个像素点信息&#xff0c;因此不同于最近邻插值和双线性插值&#xff0c;此时假设有 5 5 5\tim…

【opencv】最近邻插值、双线性插值、双三次插值(三次样条插值)

目录 1. 最近邻插值2. 双线性插值1&#xff09;简单理解2&#xff09;一般性 3. 双三次插值&#xff08;三次样条插值&#xff09;总结 b站 视频讲解 &#xff1a; https://www.bilibili.com/video/BV1wh411E7j9/ 1. 最近邻插值 举个简单例子&#xff1a;一个 3 3 3 \times 3…

挑战图像处理100问(27)——双三次插值

当我们需要对图像进行放大或缩小时&#xff0c;为了避免图像变形或失真&#xff0c;我们需要进行插值。插值是一种基于已知数据点&#xff0c;在这些数据点之间进行估计的方法。在图像处理中&#xff0c;常见的插值方法包括最邻近插值、双线性插值、双三次插值等。 双三次插值…

【图像超分辨(SR)】通俗直观彻底理解双线性插值、双三次插值及其作用

写在前面的一点话 网上讲解基本双线性插值、双三次线性插值的文章很多&#xff0c;但大部分都是只在讲为什么是这样&#xff0c;并不算非常通俗&#xff08;起码对我来说需要额外查很多资料来补充理解&#xff09;。很少有文章能够给初学者一些比较直观的理解&#xff0c;因此…

插值法(最邻近,双线性,双三次)的原理及实现

插值法(最邻近&#xff0c;双线性&#xff0c;双三次&#xff09;的原理及实现 常用的插值方法有最邻近插值法、双现象插值法和双三次插值法等&#xff0c;主要用于图像的放大或缩小。 缩小图像&#xff08;或称为下采样&#xff08;subsampled&#xff09; 或降采样&#xf…

表示关系x =y =z的c语言表达式为________.,为表示关系x≥y≥z,应使用C语言表达式____。...

为表焦距决定了画面的透视关系。 示关使用GREGRE ≥y≥桡神经沟位于 应C语言表关于脊柱正确的描写是() 建筑物或者其他设施以及建筑物上的搁置物、达式悬挂物发生( )造成他人损害的&#xff0c;所有人或者管理人应当承担民事责任,但能够证明自己没有过错的除外。 为表成对的脑颅…

C语言运算表达式整理

C语言的运算规则是按照运算符的优先级进行的&#xff0c;所以我们首先看一下C的运算优先级别 总结 最简单的优先级就是 算数运算符>关系运算符>逻辑运算符>赋值运算符 然后我们还要了解一个短路规则&#xff08;特性&#xff09; 短路规则&#xff1a;在整个逻辑表…

与数学式子对应的C语言表达式是(),与数学式子3乘以x的n次方/(2x-1)对应的C语言表达式是...

满意答案 lengwei241 2013.03.25 采纳率:43% 等级:13 已帮助:11778人 18 与数学式子3乘以x的n次方/(2x-1)对应的C语言表达式是 3*x^n/(2*x-1) 3*x**n/(2*x-1) 3*pow(x,n)*(1/(2*x-1)) 3*pow(n,x)/(2*x-1) 答案是3*pow(x,n)*(1/(2*x-1)) 为什么 解答:其中pow(x,n)为C语言…

C语言表达式和表达式的值

今天突然发现如果能很好的理解表达式和表达式的值的概念&#xff0c;可以使编程代码变的更整洁。很多时候我们总是忘记从最基本的概念开始考虑问题。我觉得我们有必要把C/C标准看下&#xff0c;在里面肯定有很多我们一直困惑的问题的答案。 C语言是基于结构化程序设计思想的程序…

以下c语言表达式与代数式计算结果,设有定义:float a=2,b=4,h=3;,以下C语言表达式中与代数式计算结果不相符的是...

设有定义:float a=2,b=4,h=3;,以下C语言表达式中与代数式计算结果不相符的是 设有式计算结Women in Britain, having some qualifications, were enfranchised until ______. 定义达式代数The usual rhyme scheme for the English or Shakespearean sonnet is( ). In “For …