资料介绍
描述
介绍
本指南提供了在 Ultra96-V2 平台上用 Python 实现人脸检测和人脸跟踪的详细说明。
本教程建立在以下“Avnet Vitis 平台的 Vitis-AI 1.1 流程”两部分教程的基础之上:
https://www.hackster.io/AlbertaBeef/vitis-ai-1-1-flow-for-avnet-vitis-platforms-part-1-007b0e
https://www.hackster.io/AlbertaBeef/vitis-ai-1-1-flow-for-avnet-vitis-platforms-part-2-f18be4
虽然本教程专门针对 Ultra96-V2 平台,但它可以针对以下任何平台:
- Ultra96-V2开发板
- UltraZed-EV SOM (7EV) + FMC 载卡
- UltraZed-EG SOM (3EG) + IO 载卡
- UltraZed-EG SOM (3EG) + PCIEC 载卡
在本教程中,我们将构建以下 AI 管道,用 Python 实现,它可以作为未来算法探索的基础。
有许多算法可用于人脸检测:
还有几种算法可用于对象跟踪:
- 光流
- 卡尔曼滤波
- 均值偏移/凸轮偏移
将“检测”算法与“跟踪”算法结合起来的一种可能策略是利用“跟踪”算法通常比“检测”算法更快的事实。一种可能的实现可以从一次“检测”迭代开始,然后是几次“跟踪”迭代,以优化有限的计算资源。
在本教程中,我将采用不同的策略。由于我们已经有一个实时运行的优化人脸检测算法(DenseBox),我将在每一帧上执行人脸“检测”,并使用一个更简单的跟踪算法,也在每一帧上执行。
我决定使用的对象跟踪是一个简单的质心跟踪器,由 PyImageSearch 的 Adrian Rosebrock 实现:
Adrian Rosebrock,使用 OpenCV 进行简单对象跟踪,PyImageSearch,https: //www.pyimagesearch.com/2018/07/23/simple-object-tracking-with-opencv/ 于 2020 年 6 月 15 日访问
如前所述,本教程将重用现有的预优化densebox模型进行人脸检测。我们已经在“Vitis-AI 1.1. Avnet Vitis 平台的流程”教程。这一次,我们将从 Python 脚本而不是 C++ 应用程序调用它。使用 Python 的动机很简单,因为 Python 语言在业界主要用于快速算法探索。有大量的 Python 包和示例可用于快速构建创意原型。
本教程将执行以下步骤:
- 步骤 0 – Python 脚本概述
- 第 1 步 – 为支持 Vitis-AI 1.1 的平台创建 SD 卡映像
- 第 2 步 – 安装教程文件和所需的软件包
- 第 3 步 - 执行人脸检测和跟踪 Python 脚本
步骤 0 – Python 脚本概述
人脸检测的Python实现
赛灵思提供的 Vitis-AI 1.1 为赛灵思器件上的 AI 推理提供了开发流程。该流程包括一个称为 DPU(深度学习处理单元)的 AI 引擎,以及一个用于 Linux 应用程序的 API,称为 VART。
此 VART API 可用于 C++ 应用程序以及 Python 脚本。
提供的大多数示例都是用 C++ 编写的,而其中两个分类示例是用 Python 提供的:
- 初始-v1
- 资源网50
但是,没有为以下人脸检测模型提供 Python 示例:
- 密集盒
由于理解 API 的最佳方式是编写利用它的代码,因此我着手编写 Python 版本的人脸检测示例,利用 Model Zoo 中的 densebox 模型。
事实证明,我在模型动物园中找到了一个验证脚本,用于 cf_densebox_wider_360_640_1.11G 模型,
models/cf_densebox_wider_360_640_1.11G/code/test/visualTest/detect.py
这个脚本被用作我的代码实现的参考。
首先,使用 VART API 的 Python 示例的一般格式如下:
dpu = runner.Runner("vitis_rundir")[0]
""" Prepare input/output buffers """
...
""" Execute model on DPU """
job_id = dpu.execute_async( inputData, outputData )
dpu.wait(job_id)
""" Retrieve output results """
...
第一行初始化 VART API,并指定可以找到模型元数据的目录。在我们的Vitis-AI 1.1平台中,我们感兴趣的是640x360版本的densebox模型,它位于“/usr/share/vitis-ai_library/models/densebox_640_360”目录下,内容如下:
/usr/share/vitis_ai_library/models/densebox_640_360/
│
│ densebox_640_360.elf
│ densebox_640_360.prototxt
│ meta.json
“meta.json”文件包含模型的元数据:
{
"target": "DPUv2",
"lib": "libvart-dpu-runner.so",
"filename": "densebox_640_360.elf",
"kernel": [ "densebox_640_360" ],
"config_file": "densebox_640_360.prototxt"
}
该文件表明我们使用“libvart-dpu-runner.so”API 以“DPUv2”硬件内核为目标。该模型有一个内核,它是构成 CNN 模型的连续层序列。内核名称为“densebox_640_360”,该内核的可执行代码/数据包含在“densebox_640_360.elf”二进制文件中。
prototxt 文件指示了我们 Python 实现所需的重要预处理信息(平均值、比例因子)。
model {
name : "dense_box_640x360"
kernel {
name: "tiling_v7_640"
mean: 128.0
mean: 128.0
mean: 128.0
scale: 1.0
scale: 1.0
scale: 1.0
}
model_type : DENSE_BOX
dense_box_param {
num_of_classes : 2
nms_threshold: 0.3
det_threshold: 0.9
}
}
第一步是对输入图像进行预处理,并准备输入/输出缓冲区:
""" Image pre-processing """
# normalize
img = img - 128.0
# resize
img = cv2.resize(img,(inputWidth,inputHeight))
""" Prepare input/output buffers """
inputData = []
inputData.append(np.empty((inputShape), dtype=np.float32,order='C'))
inputImage = inputData[0]
inputImage[0,...] = img
outputData = []
outputData.append(np.empty((output0Shape), dtype=np.float32,order='C'))
outputData.append(np.empty((output1Shape), dtype=np.float32,order='C'))
预处理包括减去均值 (128)、缩放(在本例中为 1.0,因此不执行),以及将输入图像的大小调整为模型的输入尺寸 inputWidth x inputHeight (640 x 360)。
接下来,需要准备一个包含输入图像的输入缓冲区,并且需要为以下两个输出分配两个输出缓冲区:
- 边界框:160 x 90 x {xmin, ymin, xmax, ymax}
- 分数:160 x 90 x {score0,score1}
请注意,模型输出由 2D 网格结果组成,比输入图像小 4 倍(宽度和高度)。
模型在 DPU 上执行,然后从内存中检索两个输出结果。
""" Execute model on DPU """
job_id = dpu.execute_async( inputData, outputData )
dpu.wait(job_id)
""" Retrieve output results """
OutputData0 = outputData[0].reshape(1,output0Size)
bboxes = np.reshape( OutputData0, (-1, 4) )
#
outputData1 = outputData[1].reshape(1,output1Size)
scores = np.reshape( outputData1, (-1, 2))
边界框坐标是相对于每个网格位置的,因此需要进行后处理,将每个网格位置的绝对坐标添加到边界框结果中。以下 Python 代码以矢量化方式实现了这一点,以保持最佳性能:
""" Get original face boxes """
gy = np.arange(0,output0Height)
gx = np.arange(0,output0Width)
[x,y] = np.meshgrid(gx,gy)
x = x.ravel()*4
y = y.ravel()*4
bboxes[:,0] = bboxes[:,0] + x
bboxes[:,1] = bboxes[:,1] + y
bboxes[:,2] = bboxes[:,2] + x
bboxes[:,3] = bboxes[:,3] + y
每个网格位置的两个分数结果对应于与不存在和存在的边界框相关联的分数。这两个结果需要归一化为总和为 1.0 的概率分布。我们使用 softmax 函数来执行这一步。更具体地说,我们使用了一个特殊版本的 softwax,softmax_2,它执行 2 类归一化的几次迭代 (160x90)。一旦归一化,我们只保留边界框出现的概率高于某个阈值的结果。
""" Run softmax """
softmax = softmax_2( scores )
""" Only keep faces for which prob is above detection threshold """
prob = softmax[:,1]
keep_idx = prob.ravel() > self.detThreshold
bboxes = bboxes[ keep_idx, : ]
bboxes = np.array( bboxes, dtype=np.float32 )
prob = prob[ keep_idx ]
此时,仍有许多边界框,其中大部分是彼此的重复(重叠实体)。为了去除这些重复,使用了非最大抑制算法,该算法测量每个边界框相对于彼此的重叠(IOU)。
""" Perform Non-Maxima Suppression """
face_indices = []
if ( len(bboxes) > 0 ):
face_indices = nms_boxes( bboxes, prob, self.nmsThreshold );
faces = bboxes[face_indices]
最后一步是将检测到的人脸坐标缩放回原始输入图像大小。对于这一步,我没有以矢量化风格进行编码,但这应该可以忽略不计,因为我们通常应该有少于十几个面孔。
# extract bounding box for each face
for i, face in enumerate(faces):
xmin = max(face[0] * scale_w, 0 )
ymin = max(face[1] * scale_h, 0 )
xmax = min(face[2] * scale_w, imgWidth )
ymax = min(face[3] * scale_h, imgHeight )
faces[i] = ( int(xmin),int(ymin),int(xmax),int(ymax) )
留给读者作为练习,以向量化的形式重新编码本节。请在下面的评论中分享您的实施。
上面所有的代码都被封装在了下面的类中:
vitis_ai_vart/facedetect.py
这使得演示脚本更易于编码和阅读。例如,以下是人脸检测示例的代码摘录:
...
import runner
from vitis_ai_vart.facedetect import FaceDetect
...
# Initialize Vitis-AI/DPU based face detector
dpu = runner.Runner("/usr/share/vitis_ai_library/models/densebox_640_360")[0]
dpu_face_detector = FaceDetect(dpu,detThreshold,nmsThreshold)
dpu_face_detector.start()
...
while True:
...
faces = dpu_face_detector.process(frame)
...
# Stop the face detector
dpu_face_detector.stop()
del dpu
人脸追踪
为了实现人脸跟踪,人脸检测之后是一个简单的基于质心的对象跟踪算法。对于每个检测到的人脸,计算边界框的质心,并逐帧跟踪。有关此跟踪实现的更多详细信息,请参阅 PyImageSearch.com 上的原始教程:
Adrian Rosebrock,使用 OpenCV 进行简单对象跟踪,PyImageSearch,https: //www.pyimagesearch.com/2018/07/23/simple-object-tracking-with-opencv/ 于 2020 年 6 月 15 日访问
单线程与多线程
单线程演示脚本的主要流程如下图所示,其中“Worker”指的是我们的“Face Detection”和“Face Tracking”应用示例。
单线程实现的最大帧率受限于整个应用流水线的总执行时间:Capture + Worker + Display。这并不理想,因为我们知道 CPU 在等待来自 USB 摄像头的新帧时可能处于空闲状态,并且肯定会等待 DPU 完成每个内核的执行。
为了提高帧速率,还提供了一个多线程实现,它将应用程序分解为三个主要任务:
- 捕获任务
- 工作任务
- 显示任务
任务通过同步队列相互通信。
下一个简化图说明了每个任务如何可以并行开始执行。
为 CaptureTask 和 DisplayTask 线程提供了一个线程,而为 WorkerTask 提供了用户可配置数量的线程,允许对 DPU 的多个请求进行流水线化。
下表概述了本教程提供的 Python 脚本。
第 1 步 – 为支持 Vitis-AI 1.1 的平台创建 SD 卡映像
有关创建支持 Vitis-AI 1.1 的平台的详细说明,请参阅“Avnet Vitis 平台的 Vitis-AI 1.1 流程”2 部分教程:
https://www.hackster.io/AlbertaBeef/vitis-ai-1-1-flow-for-avnet-vitis-platforms-part-1-007b0e
https://www.hackster.io/AlbertaBeef/vitis-ai-1-1-flow-for-avnet-vitis-platforms-part-2-f18be4
有关创建支持 Vitis-AI 1.1 的 Ultra96-V2 平台的快速说明,请执行以下步骤:
1) 下载并解压以下预构建 SD 卡映像
- ULTRA96V2:http ://avnet.me/avnet-ultra96v2-vitis-ai-1.1-image (MD5SUM = 7f54ceed152a0c704f5da18c4738b3fc)
2) 使用 Balena Etcher 将“Avnet-ULTRA96V2-Vitis-AI-1-1-2020-05-15.img”映像编程到 16GB micro SD 卡
3) 下载 Vitis-AI 1.1 教程的以下解决方案存档,并解压到 micro SD 卡的 BOOT 分区:
- 常见:http ://avnet.me/Avnet-COMMON-Vitis-AI-1-1-image (MD5SUM = 464ecc94368d1cb7deb184b653e740a1)
4) 使用 SD 卡启动 Ultra96-V2 开发板
5) 对 WAYLAND 桌面进行如下配置,可以改变显示器的分辨率(详见 Vitis-AI 1.1 教程)
$ cd /mnt/runtime/WAYLAND
$ source ./install.sh
$ cat weston_append.ini >> /etc/xdg/weston/weston.ini
$ source ./change_resolution_1920x1080.sh
6)对VART运行时进行如下配置
$ cd /mnt/runtime/VART
$ source ./install.sh
$ cd /mnt/runtime
$ dpkg -i vitis_ai_model_ULTRA96V2_2019.2-r1.1.1.deb
要验证支持 Vitis-AI 1.1 的平台,请执行以下步骤:
7)更改为较低的分辨率,例如1280x720
$ source /mnt/runtime/WAYLAND/change_resolution_1280x720.sh
8)定义DISPLAY环境变量
$ export DISPLAY=:0.0
9)运行C++版本的人脸检测示例
$ cd /mnt/Vitis-AI-Library/overview/samples/facedetect
$ ./test_video_facedetect densebox_640_360 0
第 2 步 – 安装教程文件和所需的软件包
本教程的文件可以在 Avnet github 存储库中找到:
https://github.com/Avnet/face_py_vart
在 Ultra96-V2 嵌入式平台上启用以太网连接后,使用“pip3 install ...”安装 Python 包:
$ cd /mnt
$ git clone https://github.com/Avnet/face_py_vart
如果您的嵌入式平台上没有可用的以太网连接,请从存储库下载教程文件:
然后,将其复制到 SD 卡的 BOOT 分区,在名为“face_py_vart”的目录下。
本教程具有以下项目结构:
/mnt/face_py_vart/
│
│ avnet_face_detection.py
│ avnet_face_detection_mt.py
│ avnet_face_tracking.py
│ avnet_face_tracking_mt.py
│ avnet_passthrough.py
│ avnet_passthrough_mt.py
│
├───pyimagesearch
│ │ centroidtracker.py
│ │ __init__.py
│ └───__pycache__
│
└───vitis_ai_vart
│ facedetect.py
│ __init__.py
└───__pycache__
“avnet_*.py”脚本是主要的演示脚本。
“vitis_ai_vart”目录包含基于 VART 的人脸检测的 Python 实现。
“pyimagesearch”目录包含来自 PyImageSearch.com 的重用质心跟踪代码
本教程需要以下 Python 包。
在 Ultra96-V2 嵌入式平台上启用以太网连接后,使用“pip3 install ...”安装 Python 包:
$ pip3 install imutils
如果您的嵌入式平台上没有可用的以太网连接,请从以下网站下载“imutils.0.5.3.tar.gz”包:
然后,将其复制到您的 SD 卡,并使用以下命令进行安装:
$ pip3 install imutils.0.5.3.tar.gz
第 3 步 - 执行人脸检测和跟踪 Python 脚本
提供了以下三个演示的 Python 脚本,每个演示都有一个单线程和多线程实现:
要在本教程中使用 Python 脚本,请导航到您在 SD 卡的 BOOT 分区上提取的“face_py_vart”目录:
$ cd /mnt/face_py_vart
为了获得有关如何使用每个演示 Python 脚本的帮助,请使用“-h”选项,如下所述:
$ python3 avnet_passthrough_mt.py -h
usage: avnet_passthrough_mt.py [-h] [-i INPUT] [-t THREADS]
optional arguments:
-h, --help show this help message and exit
-i INPUT, --input INPUT
input camera identifier (default = 0)
-t THREADS, --threads THREADS
number of worker threads (default = 4)
$ python3 avnet_face_detection_mt.py -h
usage: avnet_face_detection_mt.py [-h] [-i INPUT] [-d DETTHRESHOLD] [-n NMSTHRESHOLD] [-t THREADS]
optional arguments:
-h, --help show this help message and exit
-i INPUT, --input INPUT
input camera identifier (default = 0)
-d DETTHRESHOLD, --detthreshold DETTHRESHOLD
face detector softmax threshold (default = 0.55)
-n NMSTHRESHOLD, --nmsthreshold NMSTHRESHOLD
face detector NMS threshold (default = 0.35)
-t THREADS, --threads THREADS
number of worker threads (default = 4)
$ python3 avnet_face_tracking_mt.py -h
usage: avnet_face_tracking_mt.py [-h] [-i INPUT] [-d DETTHRESHOLD] [-n NMSTHRESHOLD] [-t THREADS]
optional arguments:
-h, --help show this help message and exit
-i INPUT, --input INPUT
input camera identifier (default = 0)
-d DETTHRESHOLD, --detthreshold DETTHRESHOLD
face detector softmax threshold (default = 0.55)
-n NMSTHRESHOLD, --nmsthreshold NMSTHRESHOLD
face detector NMS threshold (default = 0.35)
-t THREADS, --threads THREADS
number of worker threads (default = 4)
人脸检测
启动多线程人脸检测 Python 脚本:
$ python3 avnet_face_detection_mt.py -i 0 -d 0.55 -n 0.35 -t 4
人脸追踪
启动多线程人脸跟踪 Python 脚本:
$ python3 avnet_face_tracking_mt.py -i 0 -d 0.55 -n 0.35 -t 4
试验参数
如果您为一个独特的人脸检测到重复的 ROI,您可以尝试使用“-d 0.90”命令行参数将检测阈值detThreshold增加到更高的值。
基于质心的对象跟踪器允许检测到的人脸消失一定数量的帧,这可以在 pyimageserach/centroidtracker.py 脚本中更改。这允许暂时“丢失”的面孔在重新出现时保持其关联的“id”。在“pyimagesearch/centroidtracker.py”脚本中定义了面部被暂时丢失的帧数 maxDisappeared :
class CentroidTracker():
def __init__(self, maxDisappeared=20):
概括
本教程介绍了如何从 Xilinx Model Zoo 访问预训练的 densebox 模型以在 python 中进行人脸检测。
这个基于 python 的示例增加了一个简单的对象跟踪算法。
最后,采用多线程实现,更好地利用 CPU 和 DPU(硬件 AI 引擎),以实现更高的吞吐量。
我希望本教程将作为进一步探索的基础!
- Ultra96硬件用户指南
- Ultra96 CSI-2视频输出到Raspberry Pi摄像头输入
- Ultra96上的实时摄像头馈送网页
- 使用PYNQ的Ultra96面部识别锁栓
- 使用Tensil、TF-Lite和PYNQ在Ultra96板上运行YOLO v4 Tiny
- 用于Ultra96的夹层板96AnalogXperience
- Ultra96 FPGA上的Live NYC Subway Monitor应用程序
- 关于Ultra96的Xilinx DDS编译器IP教程
- 与Ultra96联网端口转发
- Ultra96 V2上基于标记的增强现实
- 使用Ultra96 PYNQ测定织物GSM
- Ultra96皮肤癌AI构建
- 一种融合人脸跟踪和聚类的人脸图像去重方法 7次下载
- 一起玩Ultra96之GPIO操作
- 基于Mega2560的人脸检测与定位跟踪 4次下载
- 人脸识别技术的原理是什么 人脸识别技术的特点有哪些 1111次阅读
- 中兴车用操作系统SafetyLinux在A1000平台上的适配 700次阅读
- SpringBoot+Vue实现网页版人脸登录、人脸识别 950次阅读
- 基于SeetaFace2和OpenCV实现人脸识别 2221次阅读
- 什么是人脸识别?如何使用10行代码实现人脸识别 5310次阅读
- 人脸识别技术原理与实现方式 1.9w次阅读
- 基于Arm技术的16nm MPSoC开发套件Ultra96 6099次阅读
- 用Go语言实现人脸识别,怎么做到的 7386次阅读
- 人脸识别发展历程、市场研究、核心技术、商业应用以及产业落地研究 7144次阅读
- 如何用40行代码实现人脸识别? 4699次阅读
- Python搭建人脸识别系统最有价值的40行代码 7269次阅读
- 在Python中利用dlib进行人脸检测 6501次阅读
- 滴滴人脸识别怎么破解 11.8w次阅读
- 人脸识别技术原理分析及典例详解 9014次阅读
- 人脸识别成金融业“新宠” 1035次阅读
下载排行
本周
- 1山景DSP芯片AP8248A2数据手册
- 1.06 MB | 532次下载 | 免费
- 2RK3399完整板原理图(支持平板,盒子VR)
- 3.28 MB | 339次下载 | 免费
- 3TC358743XBG评估板参考手册
- 1.36 MB | 330次下载 | 免费
- 4DFM软件使用教程
- 0.84 MB | 295次下载 | 免费
- 5元宇宙深度解析—未来的未来-风口还是泡沫
- 6.40 MB | 227次下载 | 免费
- 6迪文DGUS开发指南
- 31.67 MB | 194次下载 | 免费
- 7元宇宙底层硬件系列报告
- 13.42 MB | 182次下载 | 免费
- 8FP5207XR-G1中文应用手册
- 1.09 MB | 178次下载 | 免费
本月
- 1OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234315次下载 | 免费
- 2555集成电路应用800例(新编版)
- 0.00 MB | 33566次下载 | 免费
- 3接口电路图大全
- 未知 | 30323次下载 | 免费
- 4开关电源设计实例指南
- 未知 | 21549次下载 | 免费
- 5电气工程师手册免费下载(新编第二版pdf电子书)
- 0.00 MB | 15349次下载 | 免费
- 6数字电路基础pdf(下载)
- 未知 | 13750次下载 | 免费
- 7电子制作实例集锦 下载
- 未知 | 8113次下载 | 免费
- 8《LED驱动电路设计》 温德尔著
- 0.00 MB | 6656次下载 | 免费
总榜
- 1matlab软件下载入口
- 未知 | 935054次下载 | 免费
- 2protel99se软件下载(可英文版转中文版)
- 78.1 MB | 537798次下载 | 免费
- 3MATLAB 7.1 下载 (含软件介绍)
- 未知 | 420027次下载 | 免费
- 4OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234315次下载 | 免费
- 5Altium DXP2002下载入口
- 未知 | 233046次下载 | 免费
- 6电路仿真软件multisim 10.0免费下载
- 340992 | 191187次下载 | 免费
- 7十天学会AVR单片机与C语言视频教程 下载
- 158M | 183279次下载 | 免费
- 8proe5.0野火版下载(中文版免费下载)
- 未知 | 138040次下载 | 免费
评论
查看更多