資料介紹
描述
介紹
本指南提供了在 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次下載
- 人臉識別技術的原理是什么 人臉識別技術的特點有哪些 2128次閱讀
- 中興車用操作系統SafetyLinux在A1000平臺上的適配 1034次閱讀
- SpringBoot+Vue實現網頁版人臉登錄、人臉識別 1093次閱讀
- 基于SeetaFace2和OpenCV實現人臉識別 2760次閱讀
- 什么是人臉識別?如何使用10行代碼實現人臉識別 5475次閱讀
- 人臉識別技術原理與實現方式 2w次閱讀
- 基于Arm技術的16nm MPSoC開發套件Ultra96 6201次閱讀
- 用Go語言實現人臉識別,怎么做到的 7504次閱讀
- 人臉識別發展歷程、市場研究、核心技術、商業應用以及產業落地研究 7299次閱讀
- 如何用40行代碼實現人臉識別? 4806次閱讀
- Python搭建人臉識別系統最有價值的40行代碼 7311次閱讀
- 在Python中利用dlib進行人臉檢測 6593次閱讀
- 滴滴人臉識別怎么破解 11.9w次閱讀
- 人臉識別技術原理分析及典例詳解 9229次閱讀
- 人臉識別成金融業“新寵” 1073次閱讀
下載排行
本周
- 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次下載 | 免費
評論