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

news2024/12/23 1:59:19

目录

  • 一、三种图像缩放算法介绍
    • 线性插值
    • 双线性插值
    • 双三次插值
  • 二、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 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开发板实物连接如下:
在这里插入图片描述
下载程序后的演示:
输出1:1280x720输入,1920x1080分辨率HDMI输出如下原图大小:
在这里插入图片描述
输出2:1280x720输入,放大到1920x1080分辨率HDMI输出;
在这里插入图片描述
输出3:1280x720输入,缩小到640x480分辨率HDMI输出;
在这里插入图片描述

九、福利:工程源码获取

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/165096.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

纪念QT可直接安装的离线版最后版本5.14.2

为什么说纪念呢&#xff1f;因为&#xff0c;这个版本之后再也没有可下载下来安装的版本了&#xff0c;因为我们以后再也没有这么方便了。为是很么说纪念呢&#xff1f;因为我们从QT还很柔弱的时候开始就是使用的离线版。 以前用c#来做组态&#xff0c;自定义控件开发起来也还…

基础知识一览2

这里写目录标题1.XML2.1 XML中的转义字符2.2 CDATA区2.3 如何去约束XMl:DTD2.3.1 xml文件内部引用DTD约束2.3.2 xml文件引用外部DTD约束2.3.3 xml文件引用公共DTD约束1.XML xml的文件后缀名是.xmlxml有且只有一个根标签xml的标签是尖括号包裹关键字成对出现的&#xff0c;有开…

如何做好banner设计(banner设计要点包括哪些)

网页设计的Banner作为表达网站价值或者传达广告信息的视觉主体&#xff0c;一直在根据网络环境的变化而变化着&#xff0c;从表现形式到尺寸大小&#xff0c;再到创意的多元化&#xff0c;因此更需要我们网页设计师们对其设计创意进行丰富和完善&#xff0c;才能真正达到宣传的…

Elasticsearch入门——Elasticsearch7.8.0版本和Kibana7.8.0版本的下载、安装(win10环境)

目录一、Elasticsearch7.8.0版本下载、安装1.1、官网下载地址1.2、下载步骤1.3、安装步骤(需要jdk11及以上版本支持)1.4、启动后&#xff0c;控制台中文乱码问题解决二、Node下载、安装&#xff08;安装Kibana之前需要先安装Node&#xff09;2.1、Node官网下载地址2.2、Node下载…

Linux文字处理和文件编辑(三)

1、Linux里的配置文件&#xff1a; /etc/bashrc文件&#xff1a;该配置文件在root用户下&#xff0c;权限很高。~/.bashrc文件&#xff1a;只有当前用户登录时才会执行该配置文件。每次打开终端&#xff0c;都会自动执行配置文件里的代码。比如&#xff0c;alias md‘mkdir’就…

《2022年终总结》

2022年终总结 笔者成为社畜的一年&#xff0c;整整打了一年工&#xff01; 之前都说每年都有点变化&#xff0c;今年的变化可能就是更加懒散了&#xff0c;玩了更多的手机 就是运动的坚持更加多了&#xff0c;收入也增加了&#xff0c;哈哈&#xff01; 其实今年的变化不大&am…

41. 【农产品溯源项目前后端Demo】后端目录结构

本节介绍下后端代码的目录结构。 1. 实现用户管理、菜单管理、角色管理、代码自动生成等服务,归结为系统管理,是若依框架提供的能力。 2. ruoyi-traces实现农产品溯源应用的代码,如果要引入其他Java包,修改本模块的pom.xml文件。 1)config包加载配置文件数据,配置文件路…

FPGA:IIC验证镁光EEPROM仿真模型(纯Verilog)

目录日常唠嗑一、程序设计二、镁光模型仿真验证三、testbench文件四、完整工程下载日常唠嗑 IIC协议这里就不赘述了&#xff0c;网上很多&#xff0c;这里推荐两个&#xff0c;可以看看【接口时序】6、IIC总线的原理与Verilog实现 &#xff0c;还有IIC协议原理以及主机、从机Ve…

基于SpringBoot的车牌识别系统(附项目地址)

yx-image-recognition: 基于spring boot maven opencv 实现的图像深度学习Demo项目&#xff0c;包含车牌识别、人脸识别、证件识别等功能&#xff0c;贯穿样本处理、模型训练、图像处理、对象检测、对象识别等技术点 介绍 spring boot maven 实现的车牌识别及训练系统 基于…

3-1存储系统-存储器概述主存储器

文章目录一.存储器概述&#xff08;一&#xff09;存储器分类1.按在计算机中的作用&#xff08;层次&#xff09;分类2.按存储介质分类3.按存取方式分类4.按信息的可保存性分类&#xff08;二&#xff09;存储器的性能指标二.主存储器&#xff08;一&#xff09;基本组成1.译码…

6 个必知必会高效 Python 编程技巧

编写更好的Python 代码需要遵循Python 社区制定的最佳实践和指南。遵守这些标准可以使您的代码更具可读性、可维护性和效率。 本文将展示一些技巧&#xff0c;帮助您编写更好的 Python 代码 文章目录遵循 PEP 8 风格指南1.遵守 PEP 8 命名约定2. 使用描述性的和有意义的变量名…

读书笔记--- ggplot2:数据分析与图形艺术

最近看了这本书《ggplot2&#xff1a;数据分析与图形艺术》&#xff08;第2版&#xff09;&#xff0c;实际上网页在线版本已经更新到第3版了&#xff08;https://ggplot2-book.org/&#xff09;。 这本书页数不多&#xff0c;但是整体还是值得阅读&#xff0c;不愧是Hadley W…

【Proteus仿真】【STM32单片机】酒精浓度检测系统设计

文章目录一、功能简介二、软件设计三、实验现象联系作者一、功能简介 本项目使用Proteus8仿真STM32单片机控制器&#xff0c;使用LCD1602显示模块、按键模块、LED和蜂鸣器、MQ-3酒精传感器模块等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示酒精浓度值和阈值&…

插入排序.

根据找插入位置的方法分为&#xff1a; ①、顺序法定位插入位置——直接插入排序 ②、二分法定位插入位置——二分插入排序 ③、缩小增量多遍插入排序——希尔排序 一、直接插入排序&#xff08;以升序为例&#xff09; 先背模板&#xff01; void insert_sort(int *a,int le…

远程服务器(恒源云)上使用NNI进行训练调参的详细流程

远程服务器&#xff08;恒源云&#xff09;上使用NNI进行训练调参的详细流程 一、环境配置 pip下载安装nni&#xff0c;&#xff08;可使用豆瓣源&#xff0c;可快速下载&#xff0c;在安装命令后加 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com&#x…

VUE|后台管理项目——动态路由权限管理

公共数据复用1.1 为什么要公共数据复用&#xff1f;因为我们只有把导航和路由的数据公共的提出来&#xff0c;我们才能告知后端人员需要返回什么数据。1.2 怎么数据复用呢&#xff1f;首先&#xff0c;我们可以在utils文件夹里新建一个navDate.js的文件&#xff1a;把我们需要的…

go入门知识

step1:去https://go.dev下载golang step2:下载jetbrains的Goland编译器&#xff08;安装的过程会自动帮你配置好环境变量&#xff09; 一个最简单的go程序 package mainimport ("fmt" )func main() {fmt.Printf("Hello World")}1.定义变量&#xff1a; …

蓝桥杯C51(试题内容学习)

因为C51只有一组数码管&#xff0c;但是我们需要显示的东西有很多&#xff0c;所以通过按键切换是我们必须要知道的 按键之间有嵌套&#xff0c;切换&#xff0c;计数&#xff0c;对于按键的使用我们是必须知道的 1. HC573锁存器的选择 我们在之前的基础上对其进行了优化&…

java+springboot笔记2023005--java基础

Java语言是纯粹的面向对象的程序设计语言&#xff0c;主要表现为Java完全支持面向对象的三种基本特征&#xff1a;继承、封装和多态。Java语言完全以对象为中心&#xff0c;Java程序的最小程序单位是类&#xff0c;整个Java程序由一个一个的类组成。 封装指的是将对象的 实现细…