华为海思 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) 文件与数据介绍

需要 import 的包

这里没有 caffe ,因为 caffe 模型已经训练好,训练的代码也没放上来,所以就不需要caffe来进行搭建网络,训练网络,直接用 cv 读取 caffe 模型即可

import numpy as np
import argparse
import cv2
import os

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

华为海思 AI 芯片 (Hi3559A V100) 算法开发(六) 基于 caffe 人脸识别项目 Python 实现_第1张图片

这里就代表获取宽和高

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

 

你可能感兴趣的:(项目讲解)