基于PYNQ的深度学习模型设计与实现

本人其实做过一段基于ZYNQ的FPGA加速开发,但是后面不了了之了,也不太清楚脉动阵列发展到什么程度了,还有不断从ISE(CHIPSCOPE),到VIVADO(ILA,也包含SG,SDK套件)以及对应驱动,BOOT工具与教程,以及现在的SDSOC/SDx系列,HLS,PYNQ这样的基于ARM,LINUX,FPGA协处理器的板子等等等,不得不说Xilinx在文档还有与高校合作投入上真的很下功夫。

先来看看网上主要的基于PYNQ的实现吧。

1、基于PYNQ的人脸识别设计与实现

https://blog.csdn.net/qq_35999634/article/details/81670598

         摘  要


        近年来,人脸识别在支付、安保、机器人等领域得到了广泛应用,已成为计算机视觉领域的研究热点。人脸识别需要检测、对齐和识别等步骤,但Haar级联分类器、PCA等传统方法在检测识别精度、鲁棒性等方面表现不佳。随着深度学习技术的发展,将深度学习算法应用到人脸识别,有效提高了人脸检测精度和鲁棒性。传统算法结合深度学习,已成为现在以及未来计算机视觉领域的发展趋势。

        结合深度学习的人脸识别对算力要求较高,在PC机上开发算力相对足够,但是较难部署在嵌入式终端,需要综合考虑实时性、准确率、算力、功耗、成本、便携性、开发难易程度等因素。

        本课题针对上述问题,设计实现了一种基于PYNQ的人脸识别系统,在嵌入式终端实现结合深度学习的人脸识别——实时视频输入、人脸识别、显示结果输出。

        课题主要工作有:1、调研人脸识别背景、意义、应用前景,确定课题目标;2、分析传统和结合深度学习的人脸识别算法特性,并在PC端实现,对结果进行验证、对比分析;3、提出基于PYNQ的嵌入式终端人脸识别系统的设计实现方案,并对系统各个部分设计实现原理进行详细分析;4、搭建嵌入式终端人脸识别系统,对课题方案进行测试验证与结果分析;5、对课题进行总结展望,提出系统改进优化方案。

       本课题方案在实时性、准确率、功耗、成本等方面表现均较好。未来改进工作在算法方面人脸检测和识别可以尝试采用YOLO、SSD、BNN和Resnet等,实时性、准确性会更优。嵌入式终端实现方面若成本、功耗要求放宽,可以尝试Nvidia的GPU嵌入式开发平台—Jetson,性能应该会有较大提高且开发难度会降低。当然,仅使用FPGA,开发难度虽大,但性能满足要求且成本低、功耗小,应当尝试突破。

       本课题属于结合深度学习的计算机视觉算法的嵌入式实现这一研究方向,后续在此方向基于本课题将做更加深入的研究与实现。

关键词:人脸识别,计算机视觉,深度学习,PYNQ,MovidiusNCS

Video:https://www.bilibili.com/video/av39977458

GitHub(项目源码、视频等):https://github.com/666DZY666/Design-and-Implementation-of-Face-Recognition-based-on-PYNQ

微信公众号:https://mp.weixin.qq.com/s/ugGWIhkUilwH1QlCOHbiXA


不由得感叹,现在的博客已经这么完善了,还有这么教程,实例,想当初我们做这个是有多苦逼。。

2、python进阶之基于pynq开发板的人脸检测程序解析

https://blog.csdn.net/m0_37338590/article/details/78990425

__author__ = 'Jonny'
__doc__ ='http://pillow.readthedocs.io/en/3.1.x/reference/Image.html?highlight=fromarray'
# """
# 脸检测属于计算机视觉的范畴,早期人们的主要研究方向是人脸识别,即根据人脸来识别人物的身份,
# 后来在复杂背景下的人脸检测需求越来越大,人脸检测也逐渐作为一个单独的研究方向发展起来。
#
# 目前的人脸检测方法主要有两大类:基于知识和基于统计。
#
# “基于知识的方法主要利用先验知识将人脸看作器官特征的组合,根据眼睛、眉毛、嘴巴、鼻子等器官的特征以及相互之间的几何位置关系来检测人脸。
# 基于统计的方法则将人脸看作一个整体的模式——二维像素矩阵,从统计的观点通过大量人脸图像样本构造人脸模式空间,根据相似度量来判断人脸是否存在。
# 在这两种框架之下,发展了许多方法。目前随着各种方法的不断提出和应用条件的变化,将知识模型与统计模型相结合的综合系统将成为未来的研究趋势。”
#
# 基于知识的人脸检测方法
#
# Ø 模板匹配
# Ø 人脸特征
# Ø 形状与边缘
# Ø 纹理特性
# Ø 颜色特征
# 基于统计的人脸检测方法
# Ø 主成分分析与特征脸
# Ø 神经网络方法
# Ø 支持向量机
# Ø 隐马尔可夫模型
# Ø Adaboost算法
#
# PIL (Python Image Library) 是 Python 平台处理图片的事实标准,兼具强大的功能和简洁的 API.
#  实际上安装的却是 Pillow。PIL 的更新速度很慢,而且存在一些难以配置的问题,不推荐使用;
#  而 Pillow 库则是 PIL 的一个分支,维护和开发活跃,Pillow 兼容 PIL 的绝大多数语法,推荐使用
#
#
# OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。
# 它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,
# 实现了图像处理和计算机视觉方面的很多通用算法。
#
# OpenCV提供了两个程序可以训练自己的级联分类器opencv_haartraining与opencv_traincascade。
# opencv_traincascade是一个新程序,使用OpenCV 2.x API 以C++编写。
# 这二者主要的区别是opencv_traincascade支持 Haar和 LBP (Local Binary Patterns)两种特征,
# 并易于增加其他的特征。与Haar特征相比,LBP特征是整数特征,因此训练和检测过程都会比Haar特征快几倍。
# LBP和Haar特征用于检测的准确率,是依赖训练过程中的训练数据的质量和训练参数。训练一个与基于Haar特征同样准确度的LBP的分类器是可能的。
# """
#打开 base>video 文件夹下的 opencv_face_detect_hdmi.ipynb。按照提示依次运行代码。
from pynq.overlays.base import BaseOverlay
from pynq.lib.video import *
 
base = BaseOverlay("base.bit")
 
#实例化一个视频图像输入接口对象
hdmi_in = base.video.hdmi_in
#实例化一个视频图像输出接口对象
hdmi_out = base.video.hdmi_out
 
#初始化
#配置多媒体接口以使用合适的像素模式,
#24指的是色彩位数,
# ‘1’==>黑白两色
# ‘2’==>4color,用于CGA
# ‘4’==>16中颜色,用于CGA,EGA,VGA
# '8'==>灰阶,都是在黑灰白之间
# '15/16' ==>高彩色
# ‘24’==>真彩色 也就是通常说的256*256*256
# ‘32’==>真彩色+alpha频道(储存重叠图层的图形资料)
# PIXEL_RGB = PixelFormat(24, COLOR_IN_RGB, COLOR_OUT_RGB)、
# PIXEL_RGBA = PixelFormat(32, COLOR_IN_RGB, COLOR_OUT_RGB)
# PIXEL_BGR = PixelFormat(24, COLOR_IN_BGR, COLOR_OUT_BGR)
# PIXEL_YCBCR = PixelFormat(24, COLOR_IN_YCBCR, COLOR_OUT_YCBCR)
# PIXEL_GRAY = PixelFormat(8, COLOR_IN_YCBCR, COLOR_OUT_GRAY)
hdmi_in.configure(PIXEL_RGB)
hdmi_out.configure(hdmi_in.mode, PIXEL_RGB)
 
#开启输入输出多媒体接口,实现图片的输入和输出
hdmi_in.start()
hdmi_out.start()
 
#输入待检测的图片(截屏)
import PIL.Image
 
#从通道读取一个帧并返回给用户
# 这个函数可能会阻塞,直到一个完整的框架被读取。》》必须是一次读取一个完整的视频图片的框架之后才能够进行处理,生成相应的图片和视频
# 一个单独的帧缓冲区被保存,因此在长时间的暂停阅读之后,第一个帧会返回一个陈旧的框架。
# 在开始处理循环之前,要确保一个最新的帧,在开始处理循环之前要读取一个额外的时间。
frame = hdmi_in.readframe()
img = PIL.Image.fromarray(frame)
#  从导出数组阵列接口的对象(使用缓冲协议)创建图像内存。
#  如果obj不是连续的,则调用tobytes方法并frombuffer()使用它。
# 参数:
#   obj - 具有数组接口的对象
#   模式 - 使用的模式(如果没有,将从类型确定)参见:模式。
# 返回:
#   一个图像对象。
img.save("/home/xilinx/jupyter_notebooks/base/video/data/face_detect.jpg")
# 将该图像保存在给定的文件名下。如果没有指定格式,如果可能的话,使用的格式是从文件扩展名确定的。
# 关键字选项可以用来为作者提供额外的指令。如果一个作者不能识别一个选项,它会被默默地忽略。每个作者的图像格式文档中描述了可用的选项 。
# 您可以使用文件对象而不是文件名。在这种情况下,您必须始终指定格式。文件对象必须实现seek,tell和write 方法,并在二进制模式打开。
# 参数:
#  fp - 文件名(字符串),pathlib.Path对象或文件对象。
#  格式 - 可选的格式覆盖。如果省略,则使用的格式由文件扩展名确定。如果使用文件对象而不是文件名,则应始终使用此参数。
#  选项 - 额外的参数给图像写入器。
#  返回:	没有
#
# 举例:
#    KeyError - 如果输出格式不能从文件名确定。使用格式选项来解决这个问题。
#    IOError - 如果文件无法写入。该文件可能已被创建,并可能包含部分数据。
#img
#使用 opencv 进行面部检测
 
import cv2
import numpy as np
#frame = hdmi_in.readframe()
#先加载xml文件(也就是实现训练好的数据)生成级联分类器face_cascade。
face_cascade = cv2.CascadeClassifier(
 '/home/xilinx/jupyter_notebooks/base/video/data/'
 'haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier(
 '/home/xilinx/jupyter_notebooks/base/video/data/'
 'haarcascade_eye.xml')
#将图片灰度化,如果img维度为3,说明不是灰度图,先转化为灰度图gray,如果不为3,也就是2,原图就是灰度图
# if img.ndim == 3:
#  gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# else:
#  gray = img
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
#获取人脸坐标
# scale_factor:被检测对象的尺度变化。尺度越大,越容易漏掉检测的对象,但检测速度加快;尺度越小,检测越细致准确,但检测速度变慢。
# min_neighbors:数值越大,检测到对象的条件越苛刻;反之检测到对象的条件越宽松;
# minSize:检测对象的大小
#返回值是一个以元组形式为元素的列表
# 先加载xml文件生成级联分类器face_cascade
# ,然后用这个级联分类器对灰度图进行检测face_cascade.detectMultiScale(gray, 1.2, 5),
# 返回值即图片中所有人脸的坐标(x,y,w,h),在上面的函数中,我们转化了一下,使得函数返回的是人脸矩形的左上、右下顶点坐标。
# (注:坐标零点即原始图像左上顶点,往下y增加,往右x增加)。
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
#利用训话读取每一张人脸的位置坐标
for (x,y,w,h) in faces:
 #用矩形将人脸框出来,
 cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
 roi_gray = gray[y:y+h, x:x+w]
 roi_color = frame[y:y+h, x:x+w]
 eyes = eye_cascade.detectMultiScale(roi_gray)
 for (ex,ey,ew,eh) in eyes:
  cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
 
#将 OpenCV 面部识别结果输出到显示器
hdmi_out.writeframe(frame)
 
#在 Jupyter 中显示 OpenCV 面部识别结果并保存为 JPEG 格式图片
img = PIL.Image.fromarray(frame)
img.save("/home/xilinx/jupyter_notebooks/base/video/data/face_detect.jpg")
#img
 
#关闭 HDMI
hdmi_out.stop()
hdmi_in.stop()
del hdmi_in, hdmi_out

上来就是代码,应该是主要做的显示工作,这部分可能也需要费些功夫,要使用ARM,配合显示器的协议。

关于这部分网上的资料真的好多,感觉有时间确实可以玩一下,毕竟在板子上跑深度学习,不用使用PC或者GPU,还是很爽的。

参考:

https://blog.csdn.net/sinat_33705291/article/details/85449246
https://download.csdn.net/download/a1159280679/10309807
https://download.csdn.net/download/weixin_42497265/10774298
https://blog.csdn.net/weixin_38438451/article/details/83474691

甚至还有人直接抛出了yolo的github:
https://blog.csdn.net/xiuxin121/article/details/78343045
https://blog.csdn.net/abcdef123456gg/article/details/89753886
https://blog.csdn.net/baobei0112/article/details/80134991
https://download.csdn.net/download/shiyangcool/10664362
https://blog.csdn.net/cj1343395571/article/details/77001432
https://blog.csdn.net/xiuxin121/article/details/78999697


你自己也可以在网上搜索,基于FPGA的yolo算法实现,一大堆。。

我这里强推的,也是非常标准与完善的一个教程,感觉Xilinx官网也很友好,提供了很多已经设置好的示例可供学习,大家可以看看这位博主写的,这个主页做的也不错,还有搜索的功能哈哈。

https://steinslab.io/archives/1543#TinyYOLO

我就不转载了,大家可以直接去这位博主的网站,一览无遗。。

更多新闻:

http://www.777n.com/keji/29413.html
http://www.fpgadeveloper.com/2018/04/setting-up-the-pynq-z1-for-the-intel-movidius-neural-compute-stick.html
https://china.xilinx.com/about/events/cvpr-2018.html

你可能感兴趣的:(计算机基础知识)