華爲海思 AI 芯片 (Hi3559A V100) 算法開發(六) 基於 caffe 人臉識別項目 Python 實現

前面我們搭建好了相關環境和最麻煩的 caffe 環境,接下來我們用 python 訓練出來基於 caffe 的人臉識別 caffemodel。成功後我們再將它轉化爲海思開發板可以使用的 wk 文件。

這裏我們先整理下我們的思路,首先 caffemodel 文件可以轉化爲海思可以讀取的 wk 文件,但只是讀取 caffemodel 文件中的網絡參數,所以我們最好使用 YOLOv3 來進行人臉識別,方便後續的算法修改。我設定的流程爲先用 PC 端的 python 進行人臉識別的開發,在 PC 端實現完整的人臉識別算法後,訓練出合適的 caffemodel 文件,再轉爲 wk 文件。在海思開發板上實現人臉識別功能。

在算法的選擇上,(算法原理到時再分別寫一篇)

人臉檢測使用 ResNet-10 + SSD

人臉識別可以使用 基於 LBPH 特徵。(使用小數據集測試,有點不準)

後面可以嘗試別的算法

(resnet model+arc head+softmax loss)

先放個在板子 Hi3559AV100 上跑通 YOLOv3 的文章

華爲海思 AI 芯片 (Hi3559A V100) 算法開發(五) 在 Hi3559 上運行 YOLOv3

Caffe 基本理念

需要了解的一些基礎概念,寫在這裏有點冗雜。分開寫到另一篇文章好了,寫好了附上鍊接

Caffe (1) 文件與數據介紹

1. 人臉檢測

1.1 數據讀取

我們先看看在 PC 端怎麼設計人臉識別算法模型,並且訓練模型,這篇文章的目標是設計一個人臉識別算法並在 PC 端跑起來

訓練的話,估計得放到下一篇文章去

這裏的讀取設置,有兩種方法,第一種是用 argparse 包,在運行文件是設定好路徑,第二種是直接在裏面寫好

先講解一下第一種數據讀取方式(如果看着有點暈,可以先百度瞭解一下這個包)

創建解析器,添加參數,字典存放

ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
	help="path to input image")
ap.add_argument("-p", "--prototxt", required=True,
	help="path to Caffe 'deploy' prototxt file")
ap.add_argument("-m", "--model", required=True,
	help="path to Caffe pre-trained model")
ap.add_argument("-c", "--confidence", type=float, default=0.5,
	help="minimum probability to filter weak detections")
args = vars(ap.parse_args())

總結一下使用方法,就是在命令欄,   

帶圖片

python detect_faces.py -i ./iron_chic.jpg -p ./models/deploy.prototxt -m ./res10_300x300_ssd_iter_140000.caffemodel

視頻流

python detect_faces_video.py -p ./models/deploy.prototxt -m ./res10_300x300_ssd_iter_140000.caffemodel

p代表什麼,m代表什麼,由自己設定,需要讀取別的數據  ,可以自己再設定一個  -i

 

第二種讀取方法:

構建圖像或視頻讀取函數

def loadData(path):
    #新建圖像數據集與類別數據集
    dataSet = []
    label = []
    # 讀取路徑下的文件名
    person_list = os.listdir(path)
    # 將一個可遍歷的數列組合爲索引序列
    for i, a_person in enumerate(person_list):
        # 將路徑與文件名組合在一起
        dir = os.path.join(path, a_person)
        # 分別對每個文件下的文件名進行讀取
        img_list = os.listdir(dir)
        # 對讀取到的文件名的圖片進行讀取
        for a_img in img_list:
            ima = cv2.imread(os.path.join(dir, a_img), 0)
            ima = cv2.resize(ima, (92, 92))
            dataSet.append(ima)
            # 將代表某個人的文件夾名的索引作爲 label
            label.append(i)
    label = np.asarray(label)
    return dataSet, label

第二種方法讀取出來的數據如下:

[[48 49 44 ... 55 55 54]
 [45 51 40 ... 51 51 51]
 [47 48 45 ... 45 51 50]
 ...
 [47 50 46 ... 45 47 45]
 [47 52 49 ... 45 47 47]
 [50 51 51 ... 47 46 46]]      1

前面爲數據,後面爲 label

1.2 讀取神經網絡算法

這一步有一個函數十分的方便

net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"])

這樣就成功的將訓練好的 Res-10 + SSD 算法模型加載進來

(訓練的代碼後面再掛出來)

讀取神經網絡相當於省掉了人臉檢測的模型訓練步驟,但人臉識別還是需要訓練的。

 

 

2. 訓練基於 LBPH 的人臉分類器

① 創建 LBPH 人臉分類器,並訓練與保存

這裏如果理論不太懂的話,可以看我的另一篇博文  LBPH

dataSet, label = loadData(r'./img') # 加載人臉圖像, 類別
lbfh = cv2.face.LBPHFaceRecognizer_create() # 創建LBPH人臉分類器
lbfh.train(dataSet, label) # 訓練模型
lbfh.save('./my_lbph.xml') # 保存模型

 

② 二次運行,讀取模型與更新模型

第二次運行的話,就可以把第一步註釋掉

創建人臉分類器,並加載模型參數到分類器內

讀取數據並再訓練,保存模型。不需要的話,可以註釋掉

getLabels 用於讀取標籤
lbfh = cv2.face.LBPHFaceRecognizer_create() # 下次運行時,無需訓練之間創建LBPH,然後read即可
lbfh.read('./my_lbph.xml') # 重載模型
dataSet, label = loadData('./img')
lbfh.update(dataSet, label) # 還提供了再訓練方法
lbfh.save('./my_lbph.xml')
lbs = lbfh.getLabels() # 還可以展示所有已訓練的圖像的各個類別
print(lbs)

 

3. 創建攝像頭並使用人臉檢測+人臉識別算法

創建攝像頭

cap = cv2.VideoCapture(0)  # 創建攝像頭

畫面存儲變量

result = None

置信度

CF = 0.3

讀取圖片並修改圖片大小爲 300*300

這裏就代表獲取寬和高

while 1:
    _, frame = cap.read()
    frame = cv2.resize(frame, (300, 300))
    (h, w) = frame.shape[0:2]
    print((h, w))

將圖像輸入到神經網絡算法中

其中的 blobFromImage 主要用於對圖像進行預處理

blobFromImage

blobFromImage 詳情

並將數據輸入

    blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0,  # 送入網絡
                                 (300, 300), (104.0, 177.0, 123.0))
    net.setInput(blob)
    detections = net.forward()  # 網絡前向預測

對識別置信度高於 CF 的物體進行顯示

並給出起始座標 X Y ,終點座標 X Y

並摳出人臉,保存到 testImg

將人臉轉化爲灰度圖,切換大小與數據庫人臉一致

對人臉進行身份檢測

將身份信息掛上

    for i in range(0, detections.shape[2]):

        confidence = detections[0, 0, i, 2]
        print(confidence)
        # filter out weak detections by ensuring the `confidence` is
        # greater than the minimum confidence
        if confidence < CF:  # 置信度閾值
            continue
        box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
        (startX, startY, endX, endY) = box.astype("int")
        testImg = frame[startY:endY, startX:endX]  # 將人臉摳出
        if testImg.shape[0] * testImg.shape[1] == 0:
            continue
        #
        testImg = cv2.cvtColor(testImg, cv2.COLOR_BGR2GRAY)
        testImg = cv2.resize(testImg, (IMAGE_SIZE, IMAGE_SIZE))
        # predict face ID
        result = lbfh.predict(testImg)  # (id, a_float)
        text = "{:.2f}%-{}".format(confidence * 100, result)
        y = startY - 10 if startY - 10 > 10 else startY + 10
        cv2.rectangle(frame, (startX, startY), (endX, endY),
                      (0, 0, 255), 2)
        cv2.putText(frame, text, (startX, y),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)

 

顯示窗口,並設定退出快捷鍵

    # show the output frame
    cv2.imshow("Frame", frame)
    key = cv2.waitKey(1) & 0xFF

    # if the `q` key was pressed, break from the loop
    if key == ord("q"):
        break

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章