OpenCV机器学习人脸识别

OpenCV机器学习人脸识别一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第15天,点击查看活动详情。 人脸识别准确率低? 上一篇我们讲了使用OpenCV进行人脸识别的最基础操作。但是从最后的效果可以看出,识

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第15天,点击查看活动详情

人脸识别准确率低?

上一篇我们讲了使用OpenCV进行人脸识别的最基础操作。但是从最后的效果可以看出,识别率、效率都很低,而且误检率比较高,识别过程中,系统资源占用相当大,实在是没办法在实际场合中使用。在opencv3.4 版之前自带的人脸检测器是基于Haar算法实现的,不仅检出率低,而且脸的角度稍大一些就检测不出来。但是随着深度学习领域的发展,涌现了一大批效果相当不错的人脸检测算法。

人脸检测方式对比

  • OpenCV Haar人脸检测

    优点

    • 几乎可以在CPU上实时工作;
    • 简单的架构;
    • 可以检测不同比例的人脸。

    缺点

    • 会出现大量的把非人脸预测为人脸的情况;
    • 不适用于非正面人脸图像;
    • 不抗遮挡。
  • OpenCV DNN 人脸检测

    优点

    • 在这四种方法中是最准确的;
    • 在CPU上能够实时运行;
    • 适用于不同的人脸方向:上,下,左,右,侧面等。
    • 甚至在严重遮挡下仍能工作;
    • 可以检测各种尺度的人脸。

    缺点

    • 基本上没有什么明显的缺点
  • Dlib HoG人脸检测

    优点

    • CPU上最快的方法;
    • 适用于正面和略微非正面的人脸;
    • 与其他三个相比模型很小;
    • 在小的遮挡下仍可工作。

    缺点

    • 不能检测小脸,因为它训练数据的最小人脸尺寸为80×80,但是用户可以用较小尺寸的人脸数据自己训练检测器;
    • 边界框通常排除前额的一部分甚至下巴的一部分;
    • 在严重遮挡下不能很好地工作;
    • 不适用于侧面和极端非正面,如俯视或仰视。
  • Dlib CNN人脸检测

    优点

    • 适用于不同的人脸方向;
    • 对遮挡鲁棒;
    • 在GPU上工作得非常快;
    • 非常简单的训练过程。

    缺点

    • CPU速度很慢;
    • 不能检测小脸,因为它训练数据的最小人脸尺寸为80×80,但是用户可以用较小尺寸的人脸数据自己训练检测器;
    • 人脸包围框甚至小于DLib HoG人脸检测器。

非正面人脸检测效果对比:

OpenCV机器学习人脸识别

通过以上对比,我们可以推荐OpenCV DNN人脸识别作为首选方式

OpenCV DNN人脸检测

OpenCV提供了两个模型:1)原始Caffe实现的16位浮点型版本

net = cv2.dnn.readNetFromCaffe("deploy.prototxt", "res10_300x300_ssd_iter_140000_fp16.caffemodel")

2)TensorFlow实现的8位量化版本

net =cv2.dnn.readNetFromTensorflow("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt")

OpenCV已经为我们提供了训练好的人脸识别模型,当然我们也可以自己训练,同样可以识别其他物体,实现实物识别。

下载训练模型

从上面的模型加载我们看到Caffe需要deploy.prototxt和
res10_300x300_ssd_iter_140000_fp16.caffemodel两个文件,TensorFlow需要opencv_face_detector_uint8.pb和opencv_face_detector.pbtxt两个文件。我查到的很多帖子中都没有详细解释这些文件的来源,好在我找到了,我为大家详细描述一下:

  • 在GitHub中搜索opencv

OpenCV机器学习人脸识别

访问目录:
opencv/samples/dnn/face_detector

OpenCV机器学习人脸识别

这里有我们需要的deploy.prototxt和
opencv_face_detector.pbtxt文件,然后继续GitHub搜索opencv_3rdparty,打开如下:

OpenCV机器学习人脸识别

库是空的,你可能比较懵逼一点,看一下分支

OpenCV机器学习人脸识别

看到如下两个分支,当然还有很多其他的分支是用来做其他检测的,以后用的的可以在里面找,点进去后就能看到我们要下载的模型文件了

OpenCV机器学习人脸识别

OpenCV机器学习人脸识别

GitHub下载文件就不介绍了,到这里,我们需要的模型文件都下载好了,主要的检测函数有以下四个:

  • 读取训练模型:readNetFromCaffe或者readNetFromTensorflow
  • 图片预处理:blobFormImage
  • 设置网络输入值:setInput
  • 网络预测:forward

图片预处理:blobFormImage

函数原型:def blobFromImage(image, scalefactor=None, size=None, mean=None, swapRB=None, crop=None, ddepth=None)这个是主要的函数,包含两个过程:

  • 整体像素值减去平均值(mean)
  • 通过缩放系数(scalefactor)对图片像素值进行缩放

主要参数解释

  • image:输入图像对象。
  • mean:需要将图片整体减去的平均值,在人脸识别是我们用固定数值(104.0, 177.0, 123.0),可能大家对这个比较迷惑,因为它是在模型训练是设定的,我们使用的是已经训练好的模型,直接写死即可。这个在上面图中我圈出的train.prototxt文件中可以看到。
  • scalefactor:经过像素去平均值以后,进行图片缩放,默认是1
  • size:这个参数是我们神经网络在训练的时候要求输入的图片尺寸。
  • swapRB:OpenCV中认为我们的图片通道顺序是BGR,但是我平均值假设的顺序是RGB,所以如果需要交换R和G,那么就要使swapRB=true
  • crop: 是否在调整大小后对图片进行裁剪,一般我们可以不进行裁剪

代码实现

import numpy as np
import cv2, os


def show_detections(image, detections):
    h, w, c = image.shape
    for i in range(0, detections.shape[2]):
        confidence = detections[0, 0, i, 2]
        if confidence > 0.6:
            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 + 10
            cv2.rectangle(image, (startX, startY), (endX, endY),
                          (0, 255, 0), 1)
            cv2.putText(image, text, (startX, y),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 255, 0), 2)
    return image


def detect_img(net, image):
    # 其中的固定参数,我们在上面已经解释过了,固定就是如此
    blob = cv2.dnn.blobFromImage(image, 1.0, (300, 300), (104.0, 177.0, 123.0), False, False)
    net.setInput(blob)
    detections = net.forward()
    return show_detections(image, detections)


def test_file(net, filepath):
    img = cv2.imread(filepath)
    showimg = detect_img(net, img)
    cv2.imshow("img", showimg)
    cv2.waitKey(0)


def test_camera(net):
    cap = cv2.VideoCapture('人脸识别.mp4')
    while True:
        ret, img = cap.read()
        if not ret:
            break

        showimg = detect_img(net, img)
        cv2.imshow("img", showimg)
        cv2.waitKey(1)


if __name__ == "__main__":
    net = cv2.dnn.readNetFromCaffe("deploy.prototxt", "res10_300x300_ssd_iter_140000_fp16.caffemodel")
    # net =cv2.dnn.readNetFromTensorflow("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt")
    # file_path = 'data/380.png'
    # test_file(net, file_path)
    test_camera(net)

OpenCV Haar & OpenCV DNN

Haar检测结果

因为不能上传多个视频,这里只上传几张Haar未检测出来的图片

OpenCV机器学习人脸识别

DNN检测结果

screenshots.gif

以上图片使用Haar无法识别人脸,使用DNN完全可以识别。如果我们使用OpenCV提供的训练模型进行人脸识别,基本上函数调用及参数就是以上的值,而且识别率99%以上。

总结

OpenCV为我们提供的DNN人脸检测,不管从效率、准确度等方面都是很不错的,拥有实际环境使用的价值,而且使用简单。到这里人脸识别这块我们就先告一段落。

今天的文章OpenCV机器学习人脸识别分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/18588.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注