使用OpenCV+DNN来实作人脸辨识

前言: 基于正在学习 Face detection with OpenCV and deep learning

为期17天的教材课程, 希望透过此平台纪录一下第一天所学到的东西, 并透过额外网路搜寻整理所学到的知识。

DNN模组介绍:

在OpenCV3.3版本释出中把DNN模组从扩充套件移入到了OpenCV的正式释出模组中,目前DNN模组最早来自Tiny-dnn,可以载入预先训练好的Caffe模型资料,OpenCV做了近一步扩充套件支援所有主流的深度学习框架训练生成与汇出模型资料载入,常见的有如下:

Caffe

TensorFlow

Torch/PyTorch

OpenCV中DNN模组已经支援与测试过这些常见的网路模型

AlexNet

GoogLeNet v1 (also referred to as Inception-5h)

ResNet-34/50/…

SqueezeNet v1.1

VGG-based FCN (semantical segmentation network)

ENet (lightweight semantical segmentation network)

VGG-based SSD (object detection network)

MobileNet-based SSD (light-weight object detection network)

face_detector介绍:

当使用OpenCV提供的DNN模组以及载入预先训练好的Caffee模型资料, 另外还需要两份资料:

    1. The .prototxt
    1. file(s) which define the

model architecture

    1. (i.e., the layers themselves)
    1. The .caffemodel
    1. file which contains the

weights

    1. for the actual layers

当使用通过Caffee训练的模型进行深度学习时, 这两份文件都是不可少的! 前者是定义模型架构,主要是各layer的编排,后者则是包含各层layer权重设定的二进位档案。

OpenCV的深度学习人脸辨识是基于Single Shot Detector(SSD)框架以及深度残差网路(ResNet), 有兴趣的朋友可以再自行深入了解ResNet模型。此篇主要介绍是OpenCV透过支援载入预先训练好的Caffee模型, 实作出影像辨识。

可能这时候会有人问如果想要使用自己的数据来训练模型要怎幺做, 那就要参考 how_to_train_face_detector

事前準备档案:

.prototxt

    1. :

https://github.com/opencv/opencv/blob/master/samples/dnn/face_detector/deploy.prototxt

.caffeemodel

    1. :

https://github.com/sr6033/face-detection-with-OpenCV-and-DNN/blob/master/res10_300x300_ssd_iter_140000.caffemodel

Python程式码介绍:

#载入需要的套件
import numpy as np
import argparse
import cv2

透过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())

待会执行时需要给予三种参数值

— image : The path to the input image.

— prototxt : The path to the Caffe prototxt file.

— model : The path to the pretrained Caffe model.

另一个可选择的参数是 — confidence, 可以覆写原本的预设值0.5

载入要使用的model并且从照片中产生blob, 网路上查了一下可以理解Blob为经二值化(Binary Thresholding)处理后的图像色斑。

透过cv2.dnn.blobFromImage()函式对图像进行预处理, 包含设定blob维度和使用正规化进行缩减值, 返回一个4通道的的blob用于神经网路输入。

net = cv2.dnn.readNetFromCaffe(args["prototxt"], args["model"])
image = cv2.imread(args["image"])
(h, w) = image.shape[:2]
blob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0,(300, 300), (104.0, 177.0, 123.0))

接下来我们要应用人脸侦测, 将处理过的blob带入到net网路模型中, forward()能取得跑完模型的结果, 方法为透过向前传递法, DNN就是把input透过超过一层的hidden layer产生计算结果能对应出output各个的机率值, 即所谓feedforwarding。

net.setInput(blob)
detections = net.forward()

forward()函式说明

Net_forward(self, blobs=None, start=None, end=None, **kwargs) method of caffe._caffe.Net instance

Forward pass: prepare inputs and run the net forward.

Parameters

— — — — —

1. blobs : list of blobs to return in addition to output blobs.

2. kwargs : Keys are input blob names and values are blob ndarrays.For formatting inputs for Caffe, see Net.preprocess().If None, input is taken from data layers.

3. start : optional name of layer at which to begin the forward pass

4. end : optional name of layer at which to finish the forward pass(inclusive)

Returns

— — — –

outs : {blob name: blob ndarray} dict.

再来就是针对刚刚得到的detections跑回圈:

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

先提取与预测相关的置信度(即机率), 与一开始提到的 可选项的参数confidence做比较, 预设是找出比0.5置信度大的点, 划出方格来标示出图像中最有可能的人脸位置,并标上对应的机率为多少, 程式码如下:

confidence = detections[0, 0, i, 2]if confidence > args["confidence"]:box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
text = "{:.2f}%".format(confidence * 100)
y = startY - 10 if startY - 10 > 10 else startY + 10cv2.rectangle(image, (startX, startY), (endX, endY),
(0, 0, 255), 2)cv2.putText(image, text, (startX, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)

最后结束迴圈, 印出含有跑完DNN认为是人脸的图像以及机率。

cv2.imshow("Output", image)
cv2.waitKey(0)

另外影像辨识人脸也跟这个程式码雷同, 主要是image改成frame的形式做处理。

实际测试:

总结:

之前有参赛过Kaggle竞赛, 对于训练模型来说会有一些概念, 所以再看到DNN时不至于来的陌生, 虽然也才刚接触OpenCV, 但它提供的DNN模组结合已经训练过的模型来做人脸辨识, 马上就能体验到人脸辨识的功能, 甚至找了几张人脸比例较特殊的图像都还有不错的辨识结果, 后来还修改了confidence的参数值调大调小的确得到了不同的结果呢!

接下来如果有时间会想要深入了解模型架构, 自己定义layers以及权重, 从中学习整体设计全貌以及看能用什幺方式提升效能。

初次使用Medium平台撰写技术分享的心得, 希望读者能够给予改进地方, 以及如果有说明的不清楚还请多多包涵。

参考网址:

https://github.com/opencv/opencv/tree/master/samples/dnn/face_detector

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章