FPGA 实现 LeNet-5 卷积神经网络 数字识别,提供工程源码和技术支持

目录

  • 1、前言
    • LeNet-5简洁
    • 基于Zynq7020 的设计说明
    • PL 端 FPGA 逻辑设计
    • PS 端 SDK 软件设计
    • 免责声明
  • 2、相关方案推荐
    • 卷积神经网络解决方案
    • FPGA图像处理方案
  • 3、详细设计方案
    • PL端:ov7725摄像头及图像采集
    • PL端:图像预处理
    • PL端:Xilinx推荐的图像缓存架构
    • PL端:识别结果的 PL 与 PS 交互
    • PL端:图像后处理
    • PL端:RGB 转 HDMI
    • PS端:图像获取
    • PS端:卷积层计算
    • PS端:池化层计算
    • PS端:隐藏层计算
    • PS端:输出层计算
  • 4、vivado工程介绍
    • PL 端 FPGA 逻辑设计工程
    • PS 端 SDK 软件设计工程
  • 5、工程移植说明
    • vivado版本不一致处理
    • FPGA型号不一致处理
    • 其他注意事项
  • 6、上板调试验证并演示
    • 准备工作
    • 输出静态演示
    • 输出动态演示
  • 7、福利:工程源码获取

FPGA 实现 LeNet-5 卷积神经网络 数字识别,提供工程源码和技术支持

1、前言

LeNet-5简洁

LeNet-5诞生于上世纪90年代,是CNN的开山之作,最早的卷积神经网络之一,用于手写数字识别(图像分类任务),它的诞生极大地推动了深度学习领域的发展。LeNet在多年的研究和迭代后,Yann LeCun将完成的这项开拓性成果被命名为LeNet5,并发表在论文《Gradient-Based Learning Applied to Document Recognition》上,如今的AlexNet、ResNet等都是在其基础上发展而来的,在当年是一种用于手写体字符识别的非常高效的卷积神经网络。如今的卷积神经网络模型早已沧海桑田,但作为基础入门的学习资料,LeNet-5依然在江湖中占有极其重要的一席之地;

基于Zynq7020 的设计说明

本文使用Xilinx的Kirtex Zynq7000系列的Zynq7020–xc7z020clg400-2型号FPGA 实现LeNet-5 卷积神经网络实现数字识别实验;基于Zynq7020的异构特性,本设计的图像采集、图像缓存、图像处理、图像输出用 PL 端的 FPGA 逻辑实现;LeNet-5 卷积神经网络的识别功能采用 PS 端的 SDK C语言软件实现;PS 端软件将识别结果通过 AXI-Lite 总线输出给 PL 端,实现了 PS 端软件与 PL 端硬件的交互;PL 端根据 PS 端软件的识别结果,将识别到的数字输出到显示器上,实现了人机交互;PL 和 PS 端是同步实时进行的;设计所用版本为vivado2019.1;

PL 端 FPGA 逻辑设计

输入视频源采用廉价的小分辨率的ov7725摄像头;Zynq软核通过EMIO模拟i2c总线配置ov7725摄像头分辨率为640x480;然后将输入视频送入纯verilog代码实现的视频采集模块,将DVP视频转换为RGB888视频;然后将视频送入纯verilog代码实现的图像预处理模块,该模块在640x480图像正中心框出一块122x122大小图像区域,该区域作为输入数字图像的采集区域,是后面的LeNet-5卷积神经网络进行识别的区域;然后调用Xilinx官方的 Video In to AXI4-Stream 将RGB888视频转换为AXI4-Stream视频;然后调用Xilinx官方的 VDMA 将视频缓存进PS侧DDR3再读出,为了低延时,VDMA设置为1帧缓存,需要在SDK中配置才能使用;然后调用Xilinx官方的 Video Timing Controller 和 AXI4-Stream to Video Out 将 AXI4-Stream 视频转换为 RGB888视频;然后调用Xilinx官方的 ps_pl_axi_lite 接收 PS 端软件LeNet-5数字识别结果,送入图像后处理模块,该模块例化了10个 ROM ,存储了 0~9 的9个数字,并根据识别结果输出对应的数字到显示屏的右上角显示;然后将图像送入纯verilog代码实现的RGB转HDMI模块,该模块输出HDMI视频到显示器;

PS 端 SDK 软件设计

PS 端实现LeNet-5 卷积神经网络的识别功能,并将识别结果通过AXI-Lite 总线输出给 PL 端;首先在内存开辟一些列缓存空间,用来存储图像和LeNet-5 卷积神经网络计算的中间结果;软件先从 DDR3 中读取 28x28 大小的图像,然后存入事先开辟好的内存,由于需要识别的图像大小为122x122,所以需要取4次才能完整的取完一张图片;然后将图像送入卷积层计算,计算结果存入事先开辟好的内存;然后进行池化层计算,计算结果存入事先开辟好的内存;然后进行隐藏层计算,计算结果存入事先开辟好的内存;然后进行输出层计算,最后将输出结果通过AXI-Lite 总线输出给 PL 端;

免责声明

本工程及其源码即有自己写的一部分,也有网络公开渠道获取的一部分(包括CSDN、Xilinx官网、Altera官网等等),若大佬们觉得有所冒犯,请私信批评教育;基于此,本工程及其源码仅限于读者或粉丝个人学习和研究,禁止用于商业用途,若由于读者或粉丝自身原因用于商业用途所导致的法律问题,与本博客及博主无关,请谨慎使用。。。

2、相关方案推荐

卷积神经网络解决方案

我的主页有FPGA 卷积神经网络专栏,该专栏有 LeNet、 CNN、 DNN等卷积神经网络FPGA实现方案;以下是专栏地址:
点击直接前往

FPGA图像处理方案

我的主页目前有FPGA图像处理专栏,改专栏收录了我目前手里已有的FPGA图像处理方案,包括图像缩放、图像识别、图像拼接、图像融合、图像去雾、图像叠加、图像旋转、图像增强、图像字符叠加等等;以下是专栏地址:
点击直接前往

3、详细设计方案

本文使用Xilinx的Kirtex Zynq7000系列的Zynq7020–xc7z020clg400-2型号FPGA 实现LeNet-5 卷积神经网络实现数字识别实验;基于Zynq7020的异构特性,本设计的图像采集、图像缓存、图像处理、图像输出用 PL 端的 FPGA 逻辑实现;LeNet-5 卷积神经网络的识别功能采用 PS 端的 SDK C语言软件实现;PS 端软件将识别结果通过 AXI-Lite 总线输出给 PL 端,实现了 PS 端软件与 PL 端硬件的交互;PL 端根据 PS 端软件的识别结果,将识别到的数字输出到显示器上,实现了人机交互;设计框图如下:
在这里插入图片描述

PL端:ov7725摄像头及图像采集

输入视频源采用廉价的小分辨率的ov7725摄像头;Zynq软核通过EMIO模拟i2c总线配置ov7725摄像头分辨率为640x480;然后将输入视频送入纯verilog代码实现的视频采集模块,将DVP视频转换为RGB888视频;摄像头采集部分代码如下:
在这里插入图片描述
这里采用ov7725摄像头的主要原因是他的分辨率很小,只有640x480@60Hz,卷积神经网络对输入图像的大小求小不求大,因为太大的图像耗费的运算时间很长;

PL端:图像预处理

然后将视频送入纯verilog代码实现的图像预处理模块,该模块在640x480图像正中心框出一块122x122大小图像区域,该区域作为输入数字图像的采集区域,是后面的LeNet-5卷积神经网络进行识别的区域;图像预处理模块代码如下:
在这里插入图片描述
图像预处理模块首先对输入图像进行RGB转灰度操作,将RGB888视频转为8bit的灰度图,这样有利于图像识别,因为图像识别需要的只是图像边沿和轮廓的像素信息,RGB分量显然数据量太大,灰度图则完美契合;然后图像进行框选处理,即框选出需要进行识别的区域,正如前面所说,卷积神经网络对输入图像的大小求小不求大,对于640x480的采集图像,我们并不是全部都纳入识别范围,而是选择了0图像正中心框出一块122x122大小图像区域,因为数字本身就不会太大,不太可能整个屏幕全是单个数字吧?实现的效果如下:
在这里插入图片描述

PL端:Xilinx推荐的图像缓存架构

然后调用Xilinx官方的 Video In to AXI4-Stream 将RGB888视频转换为AXI4-Stream视频;然后调用Xilinx官方的 VDMA 将视频缓存进PS侧DDR3再读出,为了低延时,VDMA设置为1帧缓存,需要在SDK中配置才能使用;然后调用Xilinx官方的 Video Timing Controller 和 AXI4-Stream to Video Out 将 AXI4-Stream 视频转换为 RGB888视频;这是一套标准的Xilinx推荐的图像缓存架构;

PL端:识别结果的 PL 与 PS 交互

调用Xilinx官方的 ps_pl_axi_lite 接收 PS 端软件LeNet-5数字识别结果,并根据识别结果,将识别到的数字输出到显示器上;axi_lite是一个轻量级总线,在SDK里直接调用API即可写数据;

PL端:图像后处理

s_pl_axi_lite 接收 PS 端软件LeNet-5数字识别结果,送入图像后处理模块,该模块例化了10个 ROM ,存储了 0~9 的9个数字,并根据识别结果输出对应的数字到显示屏的右上角显示;图像后处理模块代码如下:
在这里插入图片描述
图像后处理的核心操作是像素替换,当有识别结果输入时,在显示屏右上角显示对应的数字,否则显示原始的ov7725采集像素;实现的效果如下:
在这里插入图片描述

PL端:RGB 转 HDMI

然后将图像送入纯verilog代码实现的RGB转HDMI模块,该模块输出HDMI视频到显示器;RGB转HDMI模块代码如下:
在这里插入图片描述

PS端:图像获取

软件先从 DDR3 中读取 28x28 大小的图像,然后存入事先开辟好的内存,由于需要识别的图像大小为122x122,所以需要取4次才能完整的取完一张图片;代码如下:
在这里插入图片描述

PS端:卷积层计算

然后将图像送入卷积层计算,计算结果存入事先开辟好的内存;代码如下:
在这里插入图片描述
卷积模型由Python训练得到,并转换为C语言数组;卷积核详情请看注释,注释还在进一步优化中。。。

PS端:池化层计算

然后进行池化层计算,计算结果存入事先开辟好的内存;代码如下:
在这里插入图片描述
池化层详情请看注释,注释还在进一步优化中。。。

PS端:隐藏层计算

然后进行隐藏层计算,计算结果存入事先开辟好的内存;代码如下:
在这里插入图片描述
隐藏层详情请看注释,注释还在进一步优化中。。。

PS端:输出层计算

然后进行隐藏层计算,计算结果存入事先开辟好的内存;然后进行输出层计算,最后将输出结果通过AXI-Lite 总线输出给 PL 端;代码如下:
在这里插入图片描述

4、vivado工程介绍

PL 端 FPGA 逻辑设计工程

开发板FPGA型号:Xilinx–Zynq7020–xc7z020clg400-2;
开发环境:Vivado2019.1;
输入:OV7725摄像头,分辨率640x480;
输出:HDMI,分辨率640x480;
工程作用:FPGA基于 LeNet-5 卷积神经网络实现数字识别;
工程BD如下:
在这里插入图片描述
工程代码架构如下:
在这里插入图片描述
工程的资源消耗和功耗如下:
在这里插入图片描述

PS 端 SDK 软件设计工程

PS 端 SDK 软件工程代码架构如下:
在这里插入图片描述

5、工程移植说明

vivado版本不一致处理

1:如果你的vivado版本与本工程vivado版本一致,则直接打开工程;
2:如果你的vivado版本低于本工程vivado版本,则需要打开工程后,点击文件–>另存为;但此方法并不保险,最保险的方法是将你的vivado版本升级到本工程vivado的版本或者更高版本;
在这里插入图片描述
3:如果你的vivado版本高于本工程vivado版本,解决如下:
在这里插入图片描述
打开工程后会发现IP都被锁住了,如下:
在这里插入图片描述
此时需要升级IP,操作如下:
在这里插入图片描述
在这里插入图片描述

FPGA型号不一致处理

如果你的FPGA型号与我的不一致,则需要更改FPGA型号,操作如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
更改FPGA型号后还需要升级IP,升级IP的方法前面已经讲述了;

其他注意事项

1:由于每个板子的DDR不一定完全一样,所以MIG IP需要根据你自己的原理图进行配置,甚至可以直接删掉我这里原工程的MIG并重新添加IP,重新配置;
2:根据你自己的原理图修改引脚约束,在xdc文件中修改即可;
3:纯FPGA移植到Zynq需要在工程中添加zynq软核;

6、上板调试验证并演示

准备工作

Zynq7000系列开发板,我用的Zynq7020;
OV7725摄像头;
HDMI显示器;
打印一张0~9的数字的纸张,字体要加粗,可以用我资料包里的文档打印,打印出来如下:
在这里插入图片描述
将显示器中的采集区域对着数字,移动摄像头对准,如下:
在这里插入图片描述

输出静态演示

识别结果如下:
在这里插入图片描述
在这里插入图片描述

输出动态演示

录制了一个小视频,输出动态演示如下:

LeNet-5数字识别

7、福利:工程源码获取

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

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

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

相关文章

ASO优化实践经验和改进措施

在积累了大量的实战经验后,小柚总结了一些关于ASO优化的经验给大家分享。共同进步!共同学习!Fighting! 一、关键词研究 关键词研究是ASO优化的基础。在进行关键词研究时,需要了解用户搜索意图、关键词竞争情况和关键…

1265. 数星星(树状数组/蓝桥杯)

题目&#xff1a; 输入样例&#xff1a; 5 1 1 5 1 7 1 3 3 5 5输出样例&#xff1a; 1 2 1 1 0 思路&#xff1a; 树状数组 代码&#xff1a; #include<cstdio> #include<iostream> using namespace std; const int N32010; int n; int tr[N],level[N];int lo…

linux:掌握systemctl命令控制软件的启动和关闭、掌握使用ln命令创建软连接

掌握使用systemctl命令控制软件的启动和关闭 一&#xff1a;systemctl命令&#xff1a; Linux系统很多软件(内置或第三方)均支持使用systemctl命令控制:启动停止、开机自启 能够被systemctl管理的软件一般也称之为:服务 语法: systemctl | start | stop | status | enable …

C++接口类使用Qt的虚信号

项目中封装库的对外接口类&#xff0c;包括Qt的插件框架&#xff0c;希望接口类是一个比较干净的类&#xff0c;不需要继承自Object&#xff0c;与Qt无关系&#xff0c;但又需要它的子类使用Qt的信号和槽机制&#xff0c;则可以如下处理。 接口类&#xff1a; /* 处理请求 */ …

golang实现注册系统服务(Windows、Darwin)

golang实现注册系统服务&#xff08;Windows、Darwin&#xff09; 仓库地址&#xff1a;https://github.com/ziyifast/yiSystemService 使用第三方包&#xff1a;go get “github.com/kardianos/service” 日志库&#xff1a;go get “github.com/sirupsen/logrus” log “gith…

Qt Q_DECL_OVERRIDE

Q_DECL_OVERRIDE也就是C的override&#xff08;重写函数&#xff09;&#xff0c;其目的就是为了防止写错虚函数,在重写虚函数时需要用到。 /* 鼠标按下事件 */ void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; 参考: Qt Q_DECL_OVERRIDE - 一杯清酒邀明月 - 博客…

Mybatis复习总结

MyBatis是一款优秀的持久层框架&#xff0c;用于简化JDBC的开发 MyBatis本是Apache的一个开源项目&#xff0c;2010年这个项目由apache迁移到了Google&#xff0c;并且改名为 Mybatis&#xff0c;2013年11月迁移至Github。 持久层 指的就是数据访问层&#xff0c;用来操作数…

图用邻接表表示的深度优先和广度优先遍历

邻接表表示法进行深度优先遍历的示例代码&#xff1a; #include <stdio.h> #include <stdlib.h>#define MAX_VERTEX_NUM 100// 边表节点结构体 typedef struct ArcNode {int adjvex; // 邻接顶点下标struct ArcNode* nextarc; // 指向下一个邻…

数组指定部分逆序重放

系列文章目录 进阶的卡莎C++_睡觉觉觉得的博客-CSDN博客数1的个数_睡觉觉觉得的博客-CSDN博客双精度浮点数的输入输出_睡觉觉觉得的博客-CSDN博客足球联赛积分_睡觉觉觉得的博客-CSDN博客大减价(一级)_睡觉觉觉得的博客-CSDN博客小写字母的判断_睡觉觉觉得的博客-CSDN博客纸币(…

pgsql的jsonb相关处理及样例

目录 1、某个字段中包含目标list中的全部使用>&#xff1a; 2、某个字段中包含目标list中任意值使用?|&#xff1a; 3、其他操作样例&#xff1a; 1、某个字段中包含目标list中的全部使用>&#xff1a; SELECT * FROM "public"."t_a" WHERE a::j…

ubuntu 20.04 docker prometheus

ubuntu 20.04 docker https://docs.docker.com/engine/install/ubuntu/ Ubuntu20.04下部署linux资源监控平台&#xff08;docker部署&#xff09;grafanaprometheusnode_exporter&#xff08;docker离线包&#xff09; https://blog.csdn.net/deer_cui/article/details/1340208…

基于ssm物资进销存论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本货物进销管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

day15-动画和路由过渡和切换

&#x1f4da; 目录 介绍介绍 AnimationCurveAnimationControllerTween监听动画 自定义路由切换动画Hero飞行动画交织动画动画切换组件 AnimatedSwitcherAnimatedSwitcher封装 动画过渡组件 本文学习和引用自《Flutter实战第二版》&#xff1a;作者&#xff1a;杜文 1. 介绍 …

C#中HttpWebRequest的用法

前言 HttpWebRequest是一个常用的类&#xff0c;用于发送和接收HTTP请求。在C#中使用HttpWebRequest可以实现各种功能&#xff0c;包括发送GET和POST请求、处理Cookie、设置请求头、添加参数等。本文将深入介绍HttpWebRequest的用法&#xff0c;并给出一些常见的示例。 目录 前…

Java面试总结——集合篇

摘自javaguide的集合总体框架图&#xff1a; List, Set, Queue, Map 的区别 List&#xff1a;底层基于object[]数组&#xff0c;存储的元素有序、可重复。 Set&#xff1a;底层基于HashMap实现&#xff0c;存储的元素无序&#xff0c;不可重复。 Queue&#xff1a;单…

科研院校和研究所都在用功率放大器做哪些实验

科研院校和研究所在科研工作中常常使用功率放大器进行实验。功率放大器是一种电子设备&#xff0c;其主要功能是将输入信号的功率增加到预定的输出功率水平&#xff0c;并保持信号的波形不失真。它在各个学科领域都有广泛的应用&#xff0c;包括通信、无线电、雷达、生物医学等…

vue3 使用<script lang=“ts“ setup>加上lang=“ts“后编译错误

报错信息 报错原因 加上了langts解决 下载typescript和loader npm install typescript ts-loader --save-dev配置vue.config.js 添加下面的代码 configureWebpack: { resolve: { extensions: [".ts", ".tsx", ".js", ".json"] }…

Axure中继器的使用

一.中继器介绍 在Axure中&#xff0c;中继器&#xff08;Relays&#xff09;是一种功能强大的元件&#xff0c;可以用于创建可重复使用的模板或组件。中继器允许您定义一个主要的模板&#xff0c;并在页面中重复使用该模板的实例。以下是中继器的作用和优缺点&#xff1a; 作…

Wireshark在移动网络中的应用

第一章&#xff1a;Wireshark基础及捕获技巧 1.1 Wireshark基础知识回顾 1.2 高级捕获技巧&#xff1a;过滤器和捕获选项 1.3 Wireshark与其他抓包工具的比较 第二章&#xff1a;网络协议分析 2.1 网络协议分析&#xff1a;TCP、UDP、ICMP等 2.2 高级协议分析&#xff1a;HTTP…

2023 英特尔On技术创新大会直播 |我感受到的AI魅力

文章目录 前言英特尔技术创新大会 的来历芯生无限 赋能AI创新后记 前言 近年来&#xff0c;人工智能&#xff08;Artificial Intelligence&#xff09;的应用与发展呈现出爆发式增长的态势&#xff0c;成为科技领域最为引人注目的热门话题之一。作为全球领先的半导体公司&…