《DNK210使用指南 -CanMV版 V1.0》第三十九章 YOLO2人臉檢測實驗

第三十九章 YOLO2人臉檢測實驗

從本章開始,將通過幾個實例介紹Kendryte K210上的KPU,以及CanMV下KPU的使用方法,本章將先介紹YOLO2網絡的人臉檢測應用在CanMV上的實現。通過本章的學習,讀者將學習到YOLO2網絡的人臉檢測應用在CanMV上的實現。

本章分為如下幾個小節:

39.1 maix.KPU模塊介紹

39.2 硬件設計

39.3 程序設計

39.4 運行驗證

39.1 maix.KPU模塊介紹

Kendryte K210片上擁有一個KPU,KPU是通用的神經網絡處理器,它可以在低功耗的情況下實現卷據神經網絡的計算,實時獲取被檢測目標的大小、坐標和種類,對人臉或者物體進行檢測和分類。

Kendryte K210片上KPU的主要特點如下所示:

1. 支持計算多層卷積神經網絡,每層卷積神經網絡的控制參數可單獨配置

2. 支持中斷模式,可配置加速器在每層卷積結束后是否產生中斷信號

3. 支持輸入圖像片上存儲,存儲容量大小為2M字節,卷積結果可由DMA讀出

4. 支持輸入輸出通道數目、輸入輸出圖像行高列寬可配置,其中通道數目范圍在1~1024之間,輸出行高列寬與輸入相同,或者是輸入處于2或者4且向下取整

5. 支持兩種卷積內核,分別為1*1和3*3,卷積步長為1,十種池化方式,包括bypass、步長為1且大小為2*2的均值、步長為1且大小為2*2的最大值、步長為2且大小為2*2的均值、步長為2且大小為2*2的最大值、步長為2且大小為2*2的左上值、步長為2且大小為2*2的右上值、步長為4且大小為4*4的均值、步長為4且大小為4*4的最大值、步長為4且大小為4*4的左上值

6. 支持兩種padding方式,分別為任意填充和取最近值

7. 支持在輸入圖像行高超過256時,自動對卷積結果進行抽樣,僅保留奇數行奇數列結果

8. 支持卷積參數、批歸一化參數、激活參數配置,AI加速器主動讀取,讀取地址可配置

9. 支持卷據參數片上存儲,存儲容量為72K字節,可以邊卷積邊讀取卷據參數,每層網絡最多可以讀取64次

10. 支持mobilenet-V1

11. 實時工作時最大支持神經網絡參數大小為5.5MiB到5.9MiB

12. 非實時工作最大支持網絡參數大小為Flash大小扣除軟件占用大小

在CanMV中可以使用CanMV提供的maix.KPU模塊操作Kendryte K210上的KPU。maix.KPU模塊對圖像進行卷積運算,并提供了一些網絡的支持,使得開發者能夠很方便地在Kendryte K210上使用CanMV實現一些需要卷積神經網絡計算的應用。

maix.KPU模塊提供了KPU構造函數,用于創建一個KPU對象,KPU構造函數如下所示:

class KPU()

通過KPU構造函數可以創建并初始化一個KPU對象。

KPU構造函數的使用示例如下所示:

from maix import KPU

kpu = KPU()

maix.KPU為KPU對象提供了load_kmodel()方法,用于從文件系統或Flash中加載網絡模型,load_kmodel()方法如下所示:

load_kmodel(path, size)

load_kmodel()方法用于為KPU對象從文件系統或Flash中加載網路模型,網絡模型加載后會被加載到內存中等待使用。

path指的是網絡模型在文件系統中的路徑或網絡模型在Flash中的起始地址。

size指的是網絡模型在Flash中的大小,當使用文件系統的方式加載網絡模型時,該參數無效。

load_kmodel()方法的使用示例如下所示:

from maix import KPU

kpu = KPU()

kpu.load_kmode("/sd/KPU/face_detect_320x240.kmodel")

maix.KPU模塊為KPU對象提供了init_yolo2()方法,用于初始化yolo2網絡模型,init_yolo2()方法如下所示:

KPU.init_yolo2(anchor=None, anchor_num=5, img_w=320, img_h=240, net_w=320, net_h=240, layer_w=10, layer_h=8, threshold=0.7, nms_value=0.4, classes=1)

init_yolo2()方法用于初始化yolo2網絡模型,同時為yolo2網絡傳入一些必要的參數,只有在使用YOLO2網絡模型時,才需要用到該方法。

anchor指的是錨點參數,錨點參數是網絡在訓練前就確定下來的一組數據,同一個網絡模型的錨點參數是固定的,錨點參數與網絡模型綁定。

anchor_num指的是錨點的數量,固定為len(anchor)//2,即錨點參數數據大小的一半。

img_w和img_h指的是輸入圖像的寬度和高度,這決定了畫框的邊界,如果輸入圖像是由一張小尺寸的圖像擴充來的,可以將這兩個參數設置為原圖的寬度和高度。

net_w和net_h指的是模型需要的圖像的寬度和高度,這是在網絡模型訓練前就確定好的,與網絡模型綁定。

layer_w和layer_h指的是網絡模型的層寬和層高,這是在網絡模型訓練前就確定號的,與網路模型綁定。

threshold指的是概率閾值,在網絡識別到物體后,之后當被識別物體的可信度大于概率閾值,才會輸出該結果,取值范圍為[0, 1],默認為0.7。

nums_value指的是box_iou門限,為了防止同一個物體被框出多個框,當在同一個物體上框出兩個框時,這兩個框的交叉區域占兩個框總占用面積的比例如果小于這個參數值,就取其中概率最大的一個框,默認為0.4。

classes指的是網絡要分辨目標的類數,這是在網絡模型訓練前就確定好的,與網絡模型綁定,默認為1。

init_yolo2()方法的使用示例如下所示:

from maix import KPU

import image

anchor = (0.1075, 0.126875, 0.126875, 0.175, 0.1465625, 0.2246875, 0.1953125, 0.25375, 0.2440625, 0.351875, 0.341875, 0.4721875, 0.5078125, 0.6696875, 0.8984375, 1.099687, 2.129062, 2.425937)

names = ['face']

kpu = KPU()

kpu.load_kmode("/sd/KPU/face_detect_320x240.kmodel")

kpu.init_yolo2(anchor, anchor_num=len(anchor) // 2, img_w=320, img_h=240, net_w=320, net_h=240, layer_w=10, layer_h=8, threshold=0.5, nms_value=0.2, classes=len(names))

maix.KPU模塊為KPU對象提供了run_with_output()方法,用于將圖像送入KPU進行運算,并獲取運算結果,run_with_output()方法如下所示:

KPU.run_with_output(input, getlist, get_feature)

run_with_output()方法用于將圖像送入KPU進行運算,并獲取運算結果,且能夠指定返回結果的數據類型。

input指的是輸入的圖像,需要是Image對象,因此可以是攝像頭的輸出圖像,或是文件系統中的圖像文件。

getlist指的是是否返回浮點數列表,當為True時,返回浮點數列表,默認為False。

get_feature指的是是否返回L2歸一化后的浮點特征值(最大允許256),當為True時,返回L2歸一化后的浮點特征值,默認為False。

run_with_output()方法的使用示例如下所示:

from maix import KPU

import image

img = image.Image(size=(320, 240))

anchor = (0.1075, 0.126875, 0.126875, 0.175, 0.1465625, 0.2246875, 0.1953125, 0.25375, 0.2440625, 0.351875, 0.341875, 0.4721875, 0.5078125, 0.6696875, 0.8984375, 1.099687, 2.129062, 2.425937)

names = ['face']

kpu = KPU()

kpu.load_kmode("/sd/KPU/face_detect_320x240.kmodel")

kpu.init_yolo2(anchor, anchor_num=len(anchor) // 2, img_w=320, img_h=240, net_w=320, net_h=240, layer_w=10, layer_h=8, threshold=0.5, nms_value=0.2, classes=len(names))

kpu.run_with_output(input=img, getlist=False, get_feature=False)

maix.KPU模塊為KPU對象提供了regionlayer_yolo2()方法,用于進行YOLO2運算,并獲取其運算結果,regionlayer_yolo2()方法如下所示:

KPU.regionlayer_yolo2()

regionlayer_yolo2()方法用于進行YOLO2運算,并返回一個二維列表,每個子列表表示識別到的一個物體的信息,包含了物體在輸入圖像上左上角的X坐標、Y坐標、寬度、高度,以及class的類別序號,以及置信度。

regionlayer_yolo2()方法的使用示例如下所示:

from maix import KPU

import image

img = image.Image(size=(320, 240))

anchor = (0.1075, 0.126875, 0.126875, 0.175, 0.1465625, 0.2246875, 0.1953125, 0.25375, 0.2440625, 0.351875, 0.341875, 0.4721875, 0.5078125, 0.6696875, 0.8984375, 1.099687, 2.129062, 2.425937)

names = ['face']

kpu = KPU()

kpu.load_kmode("/sd/KPU/face_detect_320x240.kmodel")

kpu.init_yolo2(anchor, anchor_num=len(anchor) // 2, img_w=320, img_h=240, net_w=320, net_h=240, layer_w=10, layer_h=8, threshold=0.5, nms_value=0.2, classes=len(names))

kpu.run_with_output(input=img, getlist=False, get_feature=False)

objs = kpu.regionlayer_yolo2()

for obj in objs:

? ? print("Rect: %d, %d, %d, %d" % (obj[0], obj[1], obj[2], obj[3]))

? ? print("Class number: %d" % (obj[4]))

print("Prob: %.2f" % (obj[5]))

maix.KPU模塊為KPU對象提供了feature_compare()方法,用于進行特征比對,feature_compare()方法如下所示:

KPU.feature_compare(feature_0, feature_1)

feature_compare()方法用于對兩組特征進行特征比對,比對兩組特征數據并給出相似度得分,得分越高表示兩組特征的相似度也就越高。

feature_0和feature_1指的是兩組特征數據,浮點列表,最大值為256。

feature_compare()方法會返回兩組比較特征的相似度得分值。

feature_compare()方法的使用示例如下所示:

feature = kpu.run_with_output(img, get_feature = True)

score = kpu.feature_compare(record_feature, feature)

print(score)

39.2 硬件設計

39.2.1 例程功能

1. 獲取攝像頭輸出的圖像,并送入KPU進行YOLO2的人臉檢測模型運算,后將運算結果和攝像頭輸出的圖像一起顯示在LCD上。

39.2.2 硬件資源

本章實驗內容,主要講解maix.KPU模塊的使用,無需關注硬件資源。

39.2.3 原理圖

本章實驗內容,主要講解maix.KPU模塊的使用,無需關注原理圖。

39.3 程序設計

39.3.1 maix.KPU模塊介紹

有關maix.KPU模塊的介紹,請見第39.1小節《maix.KPU模塊介紹》。

39.3.2 程序流程圖

圖39.3.2.1 YOLO2人臉檢測實驗流程圖

39.3.3 main.py代碼

main.py中的腳本代碼如下所示:

import lcd

import sensor

import gc

from maix import KPU

lcd.init()

sensor.reset()

sensor.set_framesize(sensor.QVGA)

sensor.set_pixformat(sensor.RGB565)

sensor.set_hmirror(False)

anchor = (0.1075, 0.126875, 0.126875, 0.175, 0.1465625, 0.2246875, 0.1953125, 0.25375, 0.2440625, 0.351875, 0.341875, 0.4721875, 0.5078125, 0.6696875, 0.8984375, 1.099687, 2.129062, 2.425937)

names = ['face']

# 構造KPU對象

face_detecter = KPU()

# 加載模型文件

face_detecter.load_kmodel("/sd/KPU/face_detect_320x240.kmodel")

# 初始化YOLO2網絡

face_detecter.init_yolo2(anchor, anchor_num=len(anchor) // 2, img_w=320, img_h=240, net_w=320, net_h=240, layer_w=10, layer_h=8, threshold=0.5, nms_value=0.2, classes=len(names))

while True:

? ? img= sensor.snapshot()

? ? # 進行KPU運算

? ?face_detecter.run_with_output(input=img, getlist=False, get_feature=False)

? ? # 進行YOLO2運算

? ?faces = face_detecter.regionlayer_yolo2()

? ? for face in faces:

? ?? ? img.draw_rectangle(face[0], face[1], face[2], face[3], color=(0, 255, 0))

? ?? ? img.draw_string(face[0] + 2, face[1] + 2, "%.2f" % (face[5]), color=(0, 255, 0))

? ?? ? img.draw_string(face[0] + 2, face[1] + 10, names[face[4]], color=(0, 255, 0))

? ? lcd.display(img)

? ? gc.collect()

可以看到一開始是先初始化了LCD和攝像頭。

接著是構造一個KPU對象,并從文件系統中加載YOLO2人臉檢測網絡需要用到的網絡模型,并初始化YOLO2網絡。

然后便是在一個循環中不斷地獲取攝像頭輸出的圖像,并將其送入KPU中進行運算,然后再進行YOLO2網絡運算,最后便得到網絡識別出人臉在輸入圖像上的一些信息,將這些信息繪制到圖像上后,在LCD上顯示圖像。

39.4 運行驗證

將DNK210開發板連接CanMV IDE,點擊CanMV IDE上的“開始(運行腳本)”按鈕后,將攝像頭對準人臉,讓其采集到人臉圖像,隨后便能在LCD上看到攝像頭輸出的圖像,同時圖像中的人臉均被綠色的矩形框框出,并在矩形框內的左上角標出了人臉的置信度,如下圖所示:

圖39.4.1 LCD顯示YOLO2人臉檢測結果
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容