Advertisement

python machine learning model_python3 Machine Learning 进行人脸识别

阅读量:

人脸识别准确率低?

上一回我们介绍了基于OpenCV的人脸识别基础技术。然而通过测试发现该方法在准确率和速度方面均存在不足之处且误检率偏高。由于在识别过程中系统资源消耗过大导致无法将其应用于实际场景中。先前版本中的脸部检测工具主要依赖于Haar特征算法实现而其检测精度较低且难以适应不同角度的脸部表情变化随着深度学习的发展出现了多款性能较为出色的脸部检测算法

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

  1. 该系统会在处理非真脸样本时产生显著数量的误报现象;
  2. 本算法仅针对标准正面对接的图像设计;
  3. 该方法缺乏对遮挡条件下的鲁棒性支持。

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

该系统无法检测小脸特征(基于80×80像素的数据集设计),但用户可以通过提供较小尺寸的人脸数据自行训练检测器;边界框通常会遮挡额头及下巴部分;遇到严重遮挡时效果欠佳;该算法不具备处理侧视或正视方向外的角度拍摄照片的能力。

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

  1. 该算法在CPU端的运行效率较低;
  2. 该系统无法识别小尺寸的脸部特征。具体而言,由于其训练数据仅支持至少80×80像素的人脸图像,在实际应用中若使用更小尺寸的人脸数据进行自定义训练,则可能无法达到预期效果;
  3. 生成的人脸边界框规模甚至小于DLib HoG的人脸检测器输出。

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

0fc3f14d3e45bc93b026572564d395f0.png

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

OpenCV DNN人脸检测

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

该代码行从OpenCV的dnn模块加载指定的部署文件和权重文件到神经网络对象net中。

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

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

该库为人脸识别提供了现成的训练模型,并非仅限于这一用途;同时允许我们自行进行模型训练,并非仅仅依赖外部数据;此外还可以进行多物体识别任务;并不仅仅局限于单物体分类场景;通过该方法我们可以实现多物体识别任务;进而达到实物鉴别效果

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

在GitHub上我们可以找到这些必要的deploy.prototxt和opencv_face_detector.pbtxt文件,并进一步前往opencv_3rdparty目录查找所需资源的具体路径

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

当我浏览到这两个分支时,默认还有其他专门用于执行不同检测的任务存在其中。如果需要进一步操作,则可以在这些选项中选择相应的功能。点击其中一个后即可预览并下载所需的具体模型文件。

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

关于在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:输入图像对象。

为了实现图像整体减去均值的过程,在人脸识别任务中我们通常会采用预设固定的数值参数(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":

network = cv2.dnn.loadFromString("deploy.prototxt", "res1x32x32_ssd_iter_148757_fp16.caffemodel")

net = OpenCV's deep learning API.loadModelFrom('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未检测出来的图片

51a697462b356eeff5272977949fab0c.png

DNN检测结果

以上图片中,Haar算法难以识别面部特征;而基于深度神经网络(DNN)的方法则展现出显著的优势。当采用OpenCV提供的训练模型进行人脸识别时,通常涉及的函数调用和参数设置与上文描述一致,并且该方法具有极高的准确率。

总结

该系统通过OpenCV实现了基于深度神经网络的人脸检测功能,在效率和准确性等方面表现出色,并在实际应用场景中具有较高的适用性,并且操作简便。至此,在人脸识别技术方面我们已做初步探讨。感谢作者分享-http://bjbsair.com/2020-04-07/tech-info/30754.html

人脸识别准确率低?

上篇文章我们介绍了使用OpenCV实现人脸识别的基本步骤。通过测试分析发现,在实际应用中该方法存在显著局限性:识别率和运算效率较低且误检率较高。具体而言,在识别过程中由于系统资源消耗较大导致运行效率低下。此外,在OpenCV 3.4版本之前的默认人脸识别算法基于Haar特征检测器实现其局限性主要体现在检测速度和准确率方面。随着深度学习技术的发展许多新型高效的人脸识别算法应运而生并展现出良好的应用前景

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

  1. 存在大量将非人脸预测为人脸的情况。
  2. 不具备处理非正面的人脸图像的能力。
  3. 敏感于遮挡。

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

该系统无法识别较小的脸型。值得注意的是,尽管最小人脸尺寸被设定为80×80像素,但系统同时允许用户根据实际需求自行调整训练数据的大小。此外,在处理较为复杂的场景时(如边界模糊或光线不佳),其性能可能会有所下降。特别地,在存在严重的遮挡(如头部被衣物覆盖)或特定视角(如侧视或极度非正面方向)的情况下,其效果会受到影响。

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

该系统在处理高分辨率视频时会显著消耗计算资源;该算法在实际应用中存在局限性:无法识别小尺寸的脸部特征;基于提供的训练数据集最小的人脸尺寸设定为80×80像素(约为普通面部宽度的三分之一),尽管用户可自行调整输入人脸尺寸用于模型再训练以提升检测能力;该算法所生成的人脸包围框其检测精度略低于OpenCV’s DLib HoG方法(一种经典的开源人脸识别算法)。

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

0fc3f14d3e45bc93b026572564d395f0.png

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

OpenCV DNN人脸检测

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

net = OpenCV库.dnn.readNetFromCaffe("配置文件路径", "预训练模型路径")

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

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

OpenCV已经 offer 了训练好的人脸识别模型;此外我们还可以自行训练这些模型进而实现对其他物体的识别。

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

这里是我们所需要的deploy.prototxt和opencv_face_detector.pbtxt文件,请在GitHub上搜索opencv_3rdparty,并查看以下链接:

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

当我注意到如下两个分支时,默认还会有其他的分支用于执行不同的检测任务。如果有需要的话可以在里面查找。点击后即可预览所需的模型文件。

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

对于GitHub上的文件下载不再赘述。至此,在线获取所需模型文件已完成。我们主要关注了以下四种关键检测函数:

读取训练模型:通过调用caffe.Net或tensorflow.Graph.load_graph_def加载相应的训练模型图片预处理:生成图像批设置网络输入值:设置输入张量网络预测:执行前向传播

图片预处理:blobFormImage

该Python函数定义为blobFromImage(image,scalefactor=size(None),size=size(None),mean=size(None),swapRB=size(None),crop=size(None),ddepth=size(None))”。该函数涵盖两个核心功能:一是图像特征提取过程;二是数据增强操作流程。

整体像素值减去平均值(mean)

通过缩放系数(scalefactor)对图片像素值进行缩放

主要参数解释:

image:输入图像对象。

mean:应从图像中减去的均值部分,在人脸识别任务中我们采用固定数值(104.0, 177.0, 123.0)。或许很多人会对这一设定感到困惑,因为它是在模型训练过程中预先设定好的参数,并非实时调整。我们可以直接引用已经训练好的模型参数进行应用。如上文所示,在train.prototxt文件中标明了这一均值参数的位置。

scalefactor:经过像素去平均值以后,进行图片缩放,默认是1

size:这个参数是我们神经网络在训练的时候要求输入的图片尺寸。

关于swapRB参数:OpenCV默认将图像通道顺序定义为BGR格式。然而,在我的均值计算假设中,默认采用的是RGB的排列方式。因此,在需要交换红绿通道的情况下,默认就需要将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.loadModel('opencv_face_detector_uint8.pb', 'opencv_face_detector')

file_path = 'data/380.png'

test_file(net, file_path)

test_camera(net)

OpenCV Haar & OpenCV DNN

Haar检测结果

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

51a697462b356eeff5272977949fab0c.png

DNN检测结果

以上图片采用Haar特征难以识别面部表情,而基于深度神经网络(DNN)则可轻松完成这一任务。基于以下方法:利用OpenCV训练的人脸识别模型其函数调用方式及所需参数与前述相同,并且该方法具有极高的准确率

总结

OpenCV为我们提供了基于深度神经网络的人脸检测功能...无论在效率、准确性等多方面都表现出色...并且操作简便...至此,在人脸识别领域我们就完成了一个阶段性的总结

人脸识别准确率低?

上一篇我们介绍了使用OpenCV进行人脸识别的基础知识。然而通过最终的表现可以看出,在准确率和运行速度方面都存在明显不足,并且误检率偏高。在OpenCV 3.4 早期版本中自带的人脸检测器主要基于Haar算法实现,在检测速率和检出率方面均表现不佳。但随着深度学习技术的发展到如今,已经涌现出了众多性能卓越的人脸检测算法

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

会导致将大量非真实的人脸识别为真实的人脸;该方法不具备处理非正面或侧向人脸的能力;该算法存在对遮挡的敏感性问题

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

缺点1) 无法识别小脸(因为其基于最小人脸尺寸的要求为80×80),然而用户可以通过使用较小尺寸的脸像数据单独训练检测器;2) 边界框通常会忽略掉前额及下巴的部分区域;3) 在严重的遮挡情况下效果不佳;4) 该方法不适用于侧向和极端非正面方向的检测(如俯视或仰视)。

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

1)运行速度较慢;
2)无法处理小尺寸的脸部;这是因为基于提供的训练数据集最小的人脸尺寸设定为80\times 80像素;然而该系统允许用户根据自身需求重新定义最小人脸尺寸,并自行进行模型训练;
3)所生成的人脸框定位精度可能低于Dlib HoG算法。

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

0fc3f14d3e45bc93b026572564d395f0.png

通过以上对比,我们可以推荐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.loadNetFromTensorflow('32-bit unsigned integer.pb', 'protobuf text format.pbtxt')

OpenCV包含了一套经过专业训练的人脸识别模型库,在此基础之上我们可以进一步进行个性化开发实现更多功能。与此同时通过自主设计算法系统能够实现对各类物体图像的精准解析从而大大提升了整体识别效率和准确性。

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

此处我们有所需的deploy.prototxt和opencv_face_detector.pbtxt文件,请访问以下链接继续在GitHub上搜索opencv_3rdparty资源库

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

在查看项目源代码时,默认会显示两个主要分叉结构,在此之外还有其他分支用于执行其他检测任务。如果需要这些功能的话,在这里就可以找到所需的功能模块。点击后即可预览并下载所需的模型文件

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

在GitHub平台中获取文件的过程无需赘述,在此之前已经完成了必要的模型文件下载工作,请关注主要的检测函数有哪些

加载训练模型:采用Caffe或Tensorflow框架进行模型加载;图像预处理:应用blob化方法对图像进行预处理;初始化神经网络输入:将数据传递至神经网络输入层;执行推理:通过调用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 is loaded from cv2.dnn by reading the face detector model files, "opponent face detector uint8 pb" and "opponent face detector pb txt".

file_path = 'data/380.png'

test_file(net, file_path)

test_camera(net)

OpenCV Haar & OpenCV DNN

Haar检测结果

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

51a697462b356eeff5272977949fab0c.png

DNN检测结果

对于这些图像来说,在没有经过深度神经网络(DNN)训练的情况下,在仅依靠Haar特征时是难以实现识别人脸的;然而完全可以通过深度神经网络实现这一目标。如果我们要利用OpenCV提供的预训练模型来进行人脸识别,则在实际应用中通常只需要关注这些函数及其参数设置即可,并且其识别率能够达到99%以上。

总结

OpenCV所推出的深度神经网络(DNN)基于的人脸检测技术,在图像处理领域表现尤为出色。无论在效率、准确性等方面都表现出色,并且该技术在实际应用场景中具有显著的应用价值。此外且操作简便至在这里人脸识别这块我们就先告一段落至此,在人脸识别领域我们已做初步探讨并完成本节内容总结感谢作者分享-http://bjbsair.com/2020-04-07/tech-info/30754.html

人脸识别准确率低?

上一篇我们介绍了使用OpenCV进行人脸识别的核心内容。然而通过测试可以看出该系统的识别准确率和运行速度都较低并且误检率较高这使得其在实际应用中存在明显局限性特别是在OpenCV 3.4版本之前的系统中默认采用基于Haar算法的人脸检测器其在角度较大的情况下无法达到预期效果。随着深度学习技术的进步在人脸识别领域取得了显著进展

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

The system may lead to a significant number of false positives in face detection, erroneously identifying non-facial regions as faces. Additionally, it lacks the capability to process images of faces that are not oriented frontally. Furthermore, the algorithm exhibits limited robustness against occlusions.

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

不足之处在于无法识别较小的脸型。由于其训练数据仅限于最小尺寸为80×80的人脸。然而用户若希望使用更小尺寸的照片进行自定义训练,则可这么做。
通常情况下边界框会截取前额及下巴的部分区域。
当受到强烈遮挡时其性能会明显下降。
该系统目前仅适用于正对镜头的方向拍摄的照片,并不支持侧面或极端角度(如俯拍或仰拍)的照片。

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

该问题的缺点在于其CPU运行速度较慢。无法识别较小的人脸特征是因为训练数据中最小的脸型尺寸被设定为80×80像素。然而,用户可以通过使用更小尺寸的脸像数据来自定义检测器。其 bounding box 的规模甚至小于 DLib HoG 的 face detector.

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

0fc3f14d3e45bc93b026572564d395f0.png

通过以上对比,我们可以推荐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. load-opponent-detection-model('opponent_face_detector_uint8.pb', 'opencv_face_detector.pbtxt')

OpenCV为我们的应用提供了现成的人脸识别模型,并且支持自定义训练;同时我们还可以自行进行模型训练;此外还可以识别各种其他物体;从而完成实物识别任务。

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

这里包含有我们所需的deploy.prototxt和opencv_face_detector.pbtxt文件。之后进行GitHub搜索opencv_3rdparty,并将其打开。

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

在当前项目中查看了这两个关键分支。剩余的分支主要用于执行其他类型的检测。这些相关资源可以在其中查找。点击后即可预览并下载所需模型文件

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

关于在GitHub上下载文件的内容已经不做详细说明了。至此,在此之前我们已经成功下载并存储了必要的模型文件。主要的检测函数有以下四个:

读取训练模型:加载预训练模型或者从Tensorflow加载图片;图片预处理:将图像转换为blob形式;设置网络输入值:初始化输入缓冲区;网络预测:执行推理过程

图片预处理:blobFormImage

该函数实现了基于图像的小块操作功能。其核心功能模块包括以下两个核心步骤:首先通过指定缩放因子对输入图像进行尺寸调整;其次根据预设均值向量对处理后的图像数据进行归一化处理。

整体像素值减去平均值(mean)

通过缩放系数(scalefactor)对图片像素值进行缩放

主要参数解释:

image:输入图像对象。

mean:从图片中减去一个平均值是必要的步骤,在人脸识别任务中我们通常会采用固定数值(104.0, 177.0, 123.0)来进行标准化处理。这可能会让一些用户感到困惑,因为该数值是在模型训练过程中预先设置好的,并且已经被优化到最佳状态了。由于我们已经完成模型训练并获得了良好的性能指标,在实际应用中可以直接引用已有的配置文件进行部署。这些参数的具体信息可以在train.prototxt文件中找到详细的说明和设置方法

scalefactor:经过像素去平均值以后,进行图片缩放,默认是1

size:这个参数是我们神经网络在训练的时候要求输入的图片尺寸。

swapRB = true;因为OpenCV默认将图像通道设置为BGR格式;而我的均值计算基于RGB排列;因此,在需要交换红绿通道的情况下;我们应设置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 is assigned the result of cv2.dnn.load("deploy.prototxt", "res1_3...").

从TensorFlow加载预训练模型到OpenCV中的深度神经网络模块

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未检测出来的图片

51a697462b356eeff5272977949fab0c.png

DNN检测结果

对于这些图片来说,在使用Haar特征时难以辨识其面部特征。相比之下,在采用深度神经网络(DNN)进行处理后,则能够显著提高识别效果。假设我们利用OpenCV官方提供的预训练模型来进行人脸识别,则其中所需的主要函数及其参数设置与上文所述基本一致。其中所需主要函数及其参数设置与上文所述基本一致,并且该方法的准确率达到99%以上。

总结

OpenCV所推出的DNN人脸检测技术,在效率与准确性等多个方面都表现出色,并且具备实用价值。操作简便是我们对这一技术的评价。阶段性地介绍完。感谢作者分享-http://bjbsair.com/2020-04-07/tech-info/30754.html

人脸识别准确率低?

我们将上一节的内容聚焦于OpenCV实现的人脸识别基础。经测试分析发现,在实际应用中该方法的表现不尽如人意——准确率和速度指标均不高;此外误报率明显高于预期;计算资源消耗较大,在实际场合中难以满足现实中的应用需求。早期版本中的默认人脸识别算法基于Haar特征提取方法,在检测能力上存在明显局限:一方面检出率较低;另一方面该算法对较大角度的脸难以实现有效的识别功能。然而随着深度学习技术的发展与进步,在这一领域涌现出了众多性能优异的新一代 face detection 算法

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

  1. 非人脸被预测为真实人脸的数量显著增加的情况;2) 无法处理侧脸或倒置的人脸图像;3) 对遮挡不敏感的情况。

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

它的一个主要缺陷是无法识别小型脸部特征(因为其基于的最小人脸尺寸设定为80×80像素),然而幸运的是用户可以通过使用更小尺寸的脸像数据来自定义训练集。第二个问题是边界框通常会遮蔽前额和下巴的部分区域。第三个问题是当面临严重的遮挡时(如蒙面或被物体挡住),检测效果会显著下降。第四个问题在于该方法不适于处理侧面或非正面角度的情况。

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

  1. 运算效率较低;
  2. 无法识别小尺寸的脸部。由于系统设计时设定的最小人脸尺寸为80×80像素,尽管如此但用户可以通过调整输入的人脸大小来进行自定义训练以提高检测精度;
  3. 所包围的区域面积比DLib HoG检测器的小。

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

0fc3f14d3e45bc93b026572564d395f0.png

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

OpenCV DNN人脸检测

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

net = cv2.dnn.readNetFromCaffe("deploy.prototxt", "res1..."

net = cv2.dnn.loadModel('deploy_prototxt', 'res1...')

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

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

OpenCV现提供现成的人脸识别模型为用户提供。通过自我训练系统还可以进一步优化性能并实现这一目标。

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

这里包含了所需的deploy.prototx以及opencv_face_detector.pbtxt文件,请接着在GitHub上搜索opencv_3rdparty,并访问以下链接

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

查看此处提供的两个主要分支的同时还有其他几个专门用于执行不同检测的任务分支

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

从 GitHub 处获取文件不再介绍;到这里后, 相应的模型文件已全部下载完成;主要有以下四种功能模块的具体实现:

加载训练模型: 使用Caffe框架或者Tensorflow框架加载训练数据集图片预处理: 对图像进行格式化准备设置网络输入值: 将当前数据传递给神经网络执行前向传播步骤

图片预处理:blobFormImage

功能原型如下所示:
该功能原型名为blobFromImage(image参数、scalefactor参数等),属于核心组件。
该模块涉及两大关键步骤:
包括修改图像尺寸、调整均值值、交换颜色通道及裁剪选项等。

整体像素值减去平均值(mean)

通过缩放系数(scalefactor)对图片像素值进行缩放

主要参数解释:

image:输入图像对象。

Mean: Subtracting the mean value from images is a crucial preprocessing step in face recognition tasks. In this context, we utilize predefined values of (104.0, 177.0, 123.0), which might be confusing for some people since these values are typically set during model training. We can directly implement these values without further adjustments as they are already optimized for our specific use case. This information can be found in the train.prototxt file attached above.

scalefactor:经过像素去平均值以后,进行图片缩放,默认是1

size:这个参数是我们神经网络在训练的时候要求输入的图片尺寸。

其中 swapRB:OpenCV默认将图像通道设置为 BGR 格式;然而我的均值计算假设图像通道为 RGB 顺序;因此,在需要交换红绿通道的情况下,则需设置 swapRB 为真。

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.loadModel("deploy.prototxt", "res1...").

net = cv2.dnn.loadModelOf("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未检测出来的图片

51a697462b356eeff5272977949fab0c.png

DNN检测结果

同样的图片,在应用Haar方法时无法有效识别人脸;相比之下,DNN能够实现精准的人脸识别能力。如果我们采用OpenCV提供的预训练模型来进行人脸识别,其中涉及的主要函数调用及其所需参数大致与之前描述的一致,其准确率通常能达到99%以上。

总结

OpenCV支持基于深度神经网络的人脸检测技术,在效率与准确性等多个维度上表现优异,并且具有实用价值。该技术操作简便,在实际应用场景中展现出良好的应用前景。至此我们对人脸识别相关内容进行总结并告一段落感谢作者的技术分享访问链接获取更多信息

人脸识别准确率低?

在上一篇推送中,我们详细介绍了如何利用OpenCV进行人脸识别人的基础知识。然而通过测试发现该系统在识别准确率和处理速度方面均表现欠佳;特别是在误检方面存在明显问题同时由于其对系统资源要求过高难以满足现实应用中的需求

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

缺点1)存在将大量非人脸图像误判为人脸的现象;2)仅能识别正面方向的人脸图像;3)不具备抗遮挡能力。

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

该系统无法识别较小尺寸的脸部图像,这是因为其训练集仅包含最小80×80像素的人脸数据;同时,在检测阶段用户可能根据自身需求调整输入的人脸尺寸;此外,在处理边界框时可能会忽略额头及下巴区域的部分内容;最后,在存在大规模遮挡的情况下系统的能力会显著下降。

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

  1. 运行缓慢;
  2. 该算法仅适用于最小人脸尺寸为80×80的情况;然而,若需使用更小尺寸的人脸数据进行训练以提升检测精度,则可自行调整训练数据。
  3. 该方法的人脸包围框具有超越现有的DLib HoG算法的优势。

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

0fc3f14d3e45bc93b026572564d395f0.png

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

OpenCV DNN人脸检测

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

使用OpenCV的dnn模块中的函数loadNetFromCaffe加载配置文件deploy.prototxt和模型res1, 该模型采用fp16格式。

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

net = cv2.dnn.loadModel('opencv_face_detector_uint8.pb', 'opencv_face_detector.pbtxt')

OpenCV为我们提供了一个经过精心训练的人脸识别模型;另外我们可以自行进行相关模型的训练;此外还可以实现完整的物体识别功能。

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

这些涉及部署所需的deploy.prototxt和opencv_face_detector.pbtxt两个模型文件,请接着在GitHub上搜索opencv_3rdparty项目

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

当我观察到这两个分支时(注:原文"当然还有很多其他的分支"已合并为"但事实上还有其他分支"),但事实上还有其他分支专门用于执行其他类型的检测。在之后的情况下(注:原文"以后用的的"已优化为简洁表达),如果点击这些分支,则会预览所需下载的模型文件。

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

GitHub不再赘述通过该平台获取文件的具体方法。至此,我们所需的模型文件均已成功下载.主要的检测函数有以下四个:

加载训练模型:使用loadNetFromCaffe或loadNetFromTensorflow导入训练好的 caffe 模型或 tensorflow 模型;将图片以blob形式进行预处理;给网络设置输入值通过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.load("deploy.prototxt", "res10_300x300_ssd_iter_140000_fp16.caffemodel")

net = cv2.dnn.readNetFromTensorFlow("opencv_face_detector_uint8pb", "opencv_face_detector_pbtxt")

file_path = 'data/380.png'

test_file(net, file_path)

test_camera(net)

OpenCV Haar & OpenCV DNN

Haar检测结果

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

51a697462b356eeff5272977949fab0c.png

DNN检测结果

以上图片难以识别人脸特征,默认依赖于DNN算法即可实现精准识别。被建议采用以下方法进行基于OpenCV的人脸识别流程:首先进行数据准备与预处理;其次构建深度学习模型;最后配置训练参数以达到最佳识别效果。通常涉及以下几个关键步骤:数据准备、模型构建以及参数配置;此外该方法具有极高的准确率(超过99%)

总结

OpenCV所呈现的人脸检测技术采用的深度神经网络(DNN)方案无论在运行效率、识别精度还是适用性方面都表现出色,并且具备实际应用场景的优势。操作简便至此为止。值得借鉴的是值得参考的案例来源链接:http://bjbsair.com/2020-04-07/tech-info/30754.html

人脸识别准确率低?

在上一篇中,我们介绍了如何利用OpenCV实现人脸识别的基本步骤。然而,在实验结果中可以看出的是:该方法在准确率和处理速度均不高,并且误检率偏高;此外,在识别过程中系统资源占用过高难以满足实际应用需求。具体而言,在opencv3.4版本之前基于Haar算法的人脸检测功能仅能提供较低性能的解决方案;而随着深度学习技术的进步,则出现了多个具有显著性能提升的人脸检测方案。

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

该系统存在以下缺陷:首先,在实际应用中可能会出现将大量非真实的人脸特征误判为真实的人脸的情况;其次,在面对非正面方向的脸像时其识别能力显著下降;最后该算法无法有效识别在物体遮挡下的人脸特征

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

缺点如下:

  1. 无法识别较小的脸型
    最低要求的人脸尺寸设定为80×80像素
    但允许用户使用更小尺寸的数据来自行训练
  2. 边界框通常会遮挡额头及下巴的部分区域
  3. 当存在严重的遮挡时(如被衣物覆盖或被其他物体阻挡),检测效果可能受到影响
  4. 尤其不适合处理侧视和非正面角度的情况
    例如俯视或仰视的角度

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

  1. 运行速度较慢;
  2. 无法识别小尺寸的脸。需要注意的是,在当前模型中,默认的最低训练尺寸设定为80×80像素。然而,如果用户希望使用更小尺寸的照片进行训练,则需自行搭建相应的数据集。
  3. 该方法所生成的bounding box的范围甚至比现有的DLIB-HOG方法更为紧凑。

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

0fc3f14d3e45bc93b026572564d395f0.png

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

OpenCV DNN人脸检测

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

通过调用cv2.dnn.loadNet函数加载配置文件路径为'deploy.prototxt'、模型路径为'resnet-19的FP16格式SSD迭代次数为14万的caffemodel'

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

net = OpenCV库中的深度神经网络模块调用读取TensorFlow格式的模型文件和配置文件路径

OpenCV已经包含了训练好的人脸识别模型库,并且系统也允许我们自行进行训练工作,在此基础之上还可以识别人体外的物体并实现对现实环境中的物体识别

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

这里包含需要获取的deploy.prototxt和opencv_face_detector.pbtxt两个模型文件。然后,在GitHub上进一步搜索opencv_3rdparty,请参考以下路径:

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

当我浏览到这两个分支时,当然还有很多其他用途的存在。这些其他用途主要用于执行不同类型的任务。之后访问时,在其中查找即可查看到我们所需下载的模型文件。

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

GitHub不再介绍获取文件的具体方法, 至此, 我们已经成功下载了所需的模型参数, 其中包含四个关键的功能模块.

加载训练好的模型通常采用的方法包括caffe和TensorFlow两种工具。在图像预处理阶段所采用的方法是基于卷积神经网络的blob形式转换。当设置神经网络的输入数据时,默认会使用来自上一层的输出结果。通过调用forward方法完成整个神经网络的前向传播计算。

图片预处理:blobFormImage

函数定义:def blobFromImage(image,scalefactor= None,size= None(mean= None,scaleFactor= None,crop= None,ddepth= None)该函数的主要作用是涵盖两个步骤。

整体像素值减去平均值(mean)

通过缩放系数(scalefactor)对图片像素值进行缩放

主要参数解释:

image:输入图像对象。

均值计算:在进行人脸识别任务时应从图片整体中减去的平均值。其中,在人脸识别任务中我们采用固定的数值(例如:104.0、177.0、123.0),这些数值是在模型训练过程中预先设定好的。因为这些数值是在模型训练过程中预先设定好的,并且已经进行了标准化处理。而我们所使用的已经是经过训练好的模型,并不需要再进行额外的优化或调整。这些参数可以直接固定下来使用,并可以在train.prototxt文件中找到详细的说明和设置方法

scalefactor:经过像素去平均值以后,进行图片缩放,默认是1

size:这个参数是我们神经网络在训练的时候要求输入的图片尺寸。

swapRB:OpenCV默认使用BGR通道顺序(...)而我的平均值计算基于RGB顺序(...),因此在需要交换红绿通道时,请将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")

该网络通过OpenCV的DNN模块从特定的 Prototxt 文件和预训练模型中进行加载。

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未检测出来的图片

51a697462b356eeff5272977949fab0c.png

DNN检测结果

此外,在依赖深度神经网络(DNN)的情况下能够实现精准的人脸识别功能;如果采用OpenCV内置的训练模型进行操作,则通常涉及的函数调用和参数配置与前文中所述相同;具体而言,在实际应用中我们能够观察到该算法在测试集上的极高的准确率(一般在99%以上)。

总结

OpenCV所呈现的人脸检测方案无论在效率和准确性方面都表现出色,并具备实际应用价值。此外该方案操作简便至此我们对人脸识别部分做一个总结性的介绍感谢作者的分享链接如下http://bjbsair.com/2020-04-07/tech-info/30754.html

人脸识别准确率低?

上篇介绍了基于OpenCV的人脸识别基础操作。但经测试后发现识别率和处理效率均偏低,并且误检率较高,在实际应用中明显制约了其可行性。值得注意的是,在OpenCV 3.4版本之前的默认人脸识别算法基于Haar特征提取方法实现,该方法不仅检出率较低而且对人脸姿态的变化较为敏感。然而随着深度学习技术的发展迅速推进,在这一领域已出现了诸多性能优越的深度学习检测算法

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

该系统会存在将大量非真实人脸标记为真实人脸的问题;该方法无法处理非正面、侧向或其他角度的人脸图像;该算法不具备抗遮挡能力

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

缺点包括:

  1. 检测器无法识别较小的脸型(因为其训练数据设定最低人脸尺寸为80×80像素),但用户若希望使用更小尺寸的数据进行自定义训练也是可行的;
  2. 边界框通常会遮挡额头及下巴的部分区域;
  3. 当存在严重的遮挡时其表现会受到影响;
  4. 该系统尤其不适合侧向和非正视方向的情况(例如俯拍或仰拍)。

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

  1. 该算法在CPU上的运行效率较低;
  2. 该系统仅支持最小80×80像素的人脸检测,并不支持更小尺寸的输入;然而用户若希望使用更小尺寸的数据进行训练,则需要自行调整训练集;
  3. 所生成的包围框规模甚至小于现有的DLib HoG方法。

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

0fc3f14d3e45bc93b026572564d395f0.png

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

OpenCV DNN人脸检测

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

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

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

网络模型=通过OpenCV的深度神经网络模块从TensorFlow加载OpenCV的人脸检测PB文件(uint8)并解析相应的PBXML文本文件

OpenCV为...提供...的人脸识别模型;同时我们也可以自行进行模型训练;此外还可以识别人体及其他物体;实现实物识别。

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

在本处有部署文件deploy.prototxt和opencv_face_detector.pbtxt需要的。接着在GitHub上搜索opencv_3rdparty并执行以下操作:请按以下步骤操作。

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

观察到有两个子路径,并且还有一些其他的子路径专门用于执行其他类型的检测。以后可以在里面查找这些资源,并且点击后即可预览到要下载的那个模型文件。

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

GitHub不再对文件进行详细说明。至此为止,我们已成功获取所需模型文件,其中涉及的关键检测功能共有四个

读取训练模型:采用readNetFromCaffe或readNetFromTensorflow进行模型加载。图片预处理:通过blobFormImage执行图像转换。设置网络输入值:设定输入参数。网络预测:执行前向传播操作。

图片预处理:blobFormImage

该函数名为blobFromImage(),它主要用于执行特定的任务。该函数具体包括以下两个核心步骤:

整体像素值减去平均值(mean)

通过缩放系数(scalefactor)对图片像素值进行缩放

主要参数解释:

image:输入图像对象。

mean:需从图片整体中减去一个平均值,在人脸识别任务中我们采用固定的均值参数(104.0, 177.0, 123.0),其中有些用户对此感到困惑。因为这些均值参数是预先设定好的,并且我们使用的是已经训练好的模型无需更新即可应用。这些均值参数可以在如上所述的train_prototxt文件中找到

scalefactor:经过像素去平均值以后,进行图片缩放,默认是1

size:这个参数是我们神经网络在训练的时候要求输入的图片尺寸。

为了实现图像处理功能,在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通过OpenCV库中的dnn模块读取指定的caffemodel文件

模型网络通过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未检测出来的图片

51a697462b356eeff5272977949fab0c.png

DNN检测结果

以上图片中基于Haar特征的方法难以识别面部特征( facial features ),而基于深度神经网络( DNN )的方法能够轻松实现这一目标( achieve this goal )。在实践应用中( practical applications ),如果我们采用OpenCV官方提供的训练模型来执行人脸识别任务( face recognition task ),这些基本操作和参数设置通常与上述方法一致( consistent with the aforementioned methods )。此外,在实际测试中( practical testing )这一方法通常能够达到接近完美的准确率( accuracy of about 99% or higher )。

总结

基于OpenCV平台实现的人脸检测技术采用的是深度神经网络模型,在运行效率和检测精度等关键指标上表现出色,并且具备良好的实用价值。至此,在人脸识别领域我们完成了初步探讨。感谢作者分享-http://bjbsair.com/2020-04-07/tech-info/30754.html

人脸识别准确率低?

在上一篇内容中,我们介绍了如何利用OpenCV进行基本的人脸识别操作。值得注意的是,在测试结果中发现该方法在实际应用中的表现不尽如人意:识别准确率和处理速度均较低;此外还存在较高的误检率问题;在具体实施过程中还发现系统的资源消耗较大,在实际场合应用时会遇到诸多限制;值得提及的是,在opencv3.4版本之前,默认的人脸检测功能基于Haar算法实现的其准确性及角度适应性均存在问题;然而随着深度学习技术的进步逐渐出现了诸多性能优越的人脸检测算法

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

主要缺点在于存在大量将非真实人脸误判为真实人脸的情况;该方法仅能识别标准正面对接的照片;且对被遮挡的人脸图像识别效果较差

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

该检测器存在以下不足之处:

  1. 无法识别小型面部特征(因其训练数据中的最小人脸尺寸设定为80×80像素),然而用户也可以使用更小尺寸的脸像数据进行自定义训练;
  2. 边界框通常会遮挡住额头及下巴的部分区域;
  3. 当存在严重的遮挡时(例如俯拍或仰拍的角度),其性能会有所下降;
  4. 不适合处理侧向或极度非正面的方向。

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

问题在于CPU运行速度较慢。无法检测小脸是因为其训练数据的最小尺寸限定在80×80像素。不过用户可以通过自行训练不同尺寸的人脸数据来优化检测器的性能。其识别范围的大小不超过Dlib HoG的人脸检测算法。

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

0fc3f14d3e45bc93b026572564d395f0.png

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

OpenCV DNN人脸检测

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

net = cv2.dnn.loadModel('deploy.prototxt', 'res1')

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

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

OpenCV为我们提供了经过训练的人脸识别模型。同时,我们也可以自行进行相关训练工作。不仅能够识别人脸和其它物体,并能实现实物的自动识别。

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

在这些资源中包含了所需的deploy.prototxt和opencv_face_detector.pbtxt文件,请接着在GitHub上进行搜索以获取opencv_3rdparty资源,并打开如下链接。

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

遇到这两个分支后,在这里还有一些其他的分支用来执行其他检测。
当需要使用时,在这里可以查找一些资料。
点击进去后就可以查看要下载的那个模型文件了

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

关于GitHub上的文件下载已不再赘述。至此,我们所需的模型文件均已成功下载完成,主要涉及的关键检测函数有四个:

读取训练模型:loadNetFromCaffe或loadNetFromTensorflow执行图像预处理

图片预处理: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.loadModel("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未检测出来的图片

51a697462b356eeff5272977949fab0c.png

DNN检测结果

这些图片通过Haar算法难以实现有效的脸部识别功能,在这种情况下完全依赖深度神经网络(DNN)技术来进行准确的人脸识别。当我们在利用OpenCV提供的训练模型时,默认会涉及的基本函数调用和参数设置与上述内容一致,并且能够达到极高的准确率。

总结

OpenCV所推出的DNN人脸检测技术,在效率与准确性方面均表现出色,并具备实用场景中的应用价值。此外该技术操作简便-到这里我们对人脸识别相关的内容已作总结完毕-感谢原作者的文章分享:http://bjbsair.com/2020-04-07/tech-info/30754.html

人脸识别准确率低?

我们在上文中介绍了利用OpenCV实现人脸识别的基础步骤。经测试发现该方法在识别率和效率方面表现欠佳,在实际运行过程中会遇到较大的问题:识别率较低且误检率较高;其中系统资源消耗较高导致无法满足实际应用需求。早期版本(如OpenCV 3.4)中的人脸检测器主要依赖于Haar特征提取技术:不仅检出率低而且对较大角度的脸部难以完成检测;然而随着深度学习技术的进步出现了多款性能卓越的人脸检测算法

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

  1. 存在大量将非人脸区域误判为人脸的情况;
  2. 该方法无法处理非正面方向的面部图像;
  3. 该方法不具备对抗各种遮挡场景的能力。

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

缺陷在于无法识别较小的面部特征;尽管如此仍可通过使用更小尺寸的人脸图像来自定义检测器;由于其训练数据集中的最小人脸尺寸设定为80×80像素;边界框设计时往往会忽略掉额头及下巴的部分区域;当面临严重的遮挡情况时(如被衣物覆盖或环境光线不足)其性能会有所下降;该方法主要针对的是正对镜头的人脸方向并不适用于侧向或高度倾斜(如俯视或仰视)的情况

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

  1. 运行缓慢;
  2. 由于设置的最小尺寸规定为80×80,则该系统无法检测到小于该尺寸的小脸;但若用户具备相关数据集,则可自行设计并训练出更为高效的检测器。
  3. 其的人脸包围框甚至比DLib HoG...低。

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

0fc3f14d3e45bc93b026572564d395f0.png

通过以上对比,我们可以推荐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.parseNetTF("opencv_face_detector_uint8.pb", "opencv_face_detector.pbtxt")

OpenCV为我们提供了成熟的人脸识别模型支持。当然我们可以自行进行相关技术开发。能够识别人体生物体的同时也能实现物体识别。

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

这里包含所需的deploy.prototxt与opencv_face_detector.pbtxt两个文件,请完成上述操作后访问以下链接:

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

在查看当前项目时,在项目的结构中可以看到两个明显的分支。当然同时还有一些其他专门用于执行不同检测的任务。此外,在项目中还可以找到一些隐藏的功能模块。如果需要使用这些功能模块,则可以直接进入相关子节点进行操作,并在那里预览并下载所需的模型文件。

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

GitHub不再做介绍。这里已经下载完成并准备好了必要的模型文件。主要的检测函数共有四个:

读取训练模型:通过调用readNetFromCaffe或者readNetFromTensorflow加载训练好的模型;图片预处理:执行图像预处理以准备输入数据;设置网络输入值:将预处理后的图像数据传递给神经网络;网络预测:执行前向传播以获得预测结果

图片预处理:blobFormImage

函数定义:def blobFromImage(image, scalefactor=None, size=None, mean=None, swapRB=None, crop=None, ddepth=None),该函数的主要功能包括图像处理相关的操作,并由两个步骤组成:首先对输入图像进行缩放处理;其次根据指定参数执行特定的操作以提取所需信息或生成目标结果

整体像素值减去平均值(mean)

通过缩放系数(scalefactor)对图片像素值进行缩放

主要参数解释:

image:输入图像对象。

为了满足人脸识别的需求,在实际操作中我们需要计算图片整体的平均值作为均值进行归一化处理。其中该数值是由模型训练阶段预先确定的一个固定向量(具体数值为[104.0,\ 177.0,\ 123.0]),这一设定主要是基于模型训练阶段的要求来决定的。由于该向量已经被预先计算好并存储好,在实际应用中我们只需要直接调用即可完成相关操作,在代码实现中我们可以将其直接赋值给相应的变量即可完成处理

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 = OpenCV's deep learning module.loadFaceDetectorModel("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未检测出来的图片

51a697462b356eeff5272977949fab0c.png

DNN检测结果

这些图片无法通过Haar算法识别人脸;但完全可以通过深度神经网络实现人脸识别效果的提升。当我们利用OpenCV提供的训练好的模型来进行人脸识别时,在大多数情况下只需要调用相应的函数并输入与原始数据集相同的参数配置即可完成任务,并且其准确率通常超过99%

总结

OpenCV所推出的DNN人脸检测方案,在效率与准确性等多个方面表现优异,并具备实际应用场景的价值。此外该方案操作简便。至此,在人脸识别领域我们暂告一段落。感谢作者分享-http://bjbsair.com/2020-04-07/tech-info/30754.html

人脸识别准确率低?

在上一篇内容中, 我们深入探讨了如何利用OpenCV进行人脸识别人的基础操作。结果显示, 该方法虽然能在一定程度上实现识别人, 但在实际应用中存在诸多局限性: 一方面, 识别准确率和运行速度较低; 另一方面, 误检率较高, 显著影响了系统的可靠性; 再者, 在识别过程中发现系统资源消耗较大, 导致无法满足现实场景中的应用需求。值得注意的是, OpenCV 3.4版本之前的默认人脸识别算法基于Haar特征提取技术构建, 其表现尚有待提升: 检测到的准确率较低, 并且当面部表情变化较大时难以捕捉到面部特征。然而随着深度学习技术的快速发展, 出现了一系列性能卓越的人脸检测算法

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

  1. 存在将大量非人脸图像误判为人脸的情况;
  2. 不具备对非正面方向的人脸图像识别能力;
  3. 对存在遮挡的图像识别效果较差。

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

缺点1)无法识别小脸(因系统基于最小人脸尺寸设定为80×80),但允许用户使用更小尺寸的脸像自行训练检测器;2)边界框常会遮盖额头及下巴的部分;3)在存在严重的遮挡时表现不佳;4)尤其不适合侧视和高度非正面角度(如俯拍或正视时),效果欠佳。

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

  1. 计算速度较慢;
  2. 无法识别小尺寸的脸部;由于训练数据的最小人脸尺寸设定为80×80像素,在此限制下该系统无法直接处理较小尺寸的脸部图像;然而用户若希望处理更小尺寸的脸部,则需自行调整或重新训练相关参数;
  3. 该系统生成的 bounding box 的规模甚至比 DLib-HoG 检测器还要小。

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

0fc3f14d3e45bc93b026572564d395f0.png

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

OpenCV DNN人脸检测

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

net = cv2.dnn.load(net, "deploy.prototxt", "res1 99999_resized.caffemodel")

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

network = cv2.dnn.loadModel('opencv_face_detector_uint8.pb', 'opencv_face_detector.pbtxt')

OpenCV为用户提供了一系列训练好的人脸识别模型;我们还可以自行进行数据准备和模型训练;通过这种方法能够识别人体内的各种物体,并实现实物识别这一目标。

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

此位置存放着所需部署文件,请查看以下路径:deploy.prototxt 和 opencv_face_detector.pbtxt。接着在GitHub上搜索opponent_3rdparty,请访问以下链接:

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

当前可查看的主要有两个分支,在此目录下即可找到其余相关分支用于其他检测功能。若有需要,在此目录下即可找到所需模型文件位置。点击后即可预览目标模型文件位置。

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

GitHub不再介绍如何从该平台获取文件;目前而言,我们已经成功获取所需的模型文件;此外,主要涉及的检测函数共有四个

加载训练模型:使用Caffe框架或TensorFlow框架加载图片预处理:生成特征图设置网络输入值:配置神经网络输入数据网络预测:进行前向传播推断

图片预处理:blobFormImage

函数定义:def \ blobFromImage(image,scalefactor=None,size=None(mean=None,swapRB=None,crop=None,ddepth=None)) 这是一个核心组件,在图像处理中负责提取感兴趣区域并进行缩放处理。该模块主要包括两步操作:首先对输入图像进行尺寸转换;其次通过均值替换消除颜色偏移并执行裁剪操作以优化输出结果的质量

整体像素值减去平均值(mean)

通过缩放系数(scalefactor)对图片像素值进行缩放

主要参数解释:

image:输入图像对象。

均值:应在图像处理过程中减去预定义的平均值,在人脸识别任务中通常采用固定数值(104.0, 177.0, 123.0)。这可能引起一些困惑的原因在于这些数值是在模型训练设置时确定的。我们直接引用已训练好的参数配置即可。这些参数的具体位置已在train.prototxt注释中标明位置即可查看。

scalefactor:经过像素去平均值以后,进行图片缩放,默认是1

size:这个参数是我们神经网络在训练的时候要求输入的图片尺寸。

swapRB:OpenCV认为我们的图像通道顺序为BGR;而我们所采用的均值计算假设图像通道顺序为RGB;因此,在需要交换红绿通道的情况下就需要将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_149, 58, 67.caffemodel")

该网络通过OpenCV深度神经网络接口从指定的Deploy prototxt文件和Res10_3×3模型加载

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未检测出来的图片

51a697462b356eeff5272977949fab0c.png

DNN检测结果

对于上述图片而言,在采用Haar特征时难以实现有效的脸部识别。然而基于深度神经网络(DNN)的方法则能够轻松实现对脸部的识别。当我们在实际应用中采用OpenCV提供的训练模型来进行脸部识别时,则可以认为这些函数调用及参数的具体取值与前述内容基本一致,并且可以预期达到99%以上的准确率。

总结

OpenCV为我们提供了基于深度神经网络(DNN)的人脸检测方案。无论在效率、准确度等方面表现都十分出色,并且具备实际应用价值。操作简便至此,在人脸识别领域我们已进行初步探讨并暂定此部分为一个阶段总结。感谢作者分享-http://bjbsair.com/2020-04-07/tech-info/30754.html

人脸识别准确率低?

上期节目我们介绍了使用OpenCV实现人脸识别的基本操作流程。然而通过实验结果可以看出,在识别率和处理速度方面仍存在明显不足,并且误检率偏高。特别是在实际应用中发现系统资源消耗过大导致功能无法正常运转。值得注意的是,在OpenCV 3.4版本之前的默认人脸识别算法基于Haar特征提取方法其检测精度较低且对人脸角度变化较为敏感难以满足复杂场景下的检测需求。随着计算机视觉领域的快速发展基于深度学习的人脸检测算法逐渐展现出更强的优势。

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

缺点1)存在较高的误报率,在一定范围内将大量非真实人脸被误判为真实人脸;2)该方法无法处理处于非正面姿态或表情变化下的复杂场景;3)该算法对于不同类型的遮挡物较为敏感

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

缺点1)无法检测小型脸部因为其设计基于最小80×80像素的人脸数据集然而用户若使用更小尺寸的脸像数据同样可以自行定制检测器;2)边界框通常会遮挡额头及下巴的部分区域;3)当存在严重的遮挡时其识别效果会显著降低;4)该系统目前主要适用于正向拍摄且不建议用于侧面或极度非正面的角度如俯拍或仰拍。

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

该方法在处理速度方面存在不足;由于训练数据仅包含最小尺寸为80×80的脸部图像,则该系统无法有效识别较小尺寸的人脸;而其生成的 bounding box even smaller than those produced by the DLib HoG detector

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

0fc3f14d3e45bc93b026572564d395f0.png

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

OpenCV DNN人脸检测

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

net = cv2.dnn.loadModelFrom caffe('deploy.prototxt', 'res1, 3, 3_ssd_iter_14, 255.f16.caffemodel')

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

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

OpenCV不仅支持提供现成的人脸识别模型(facial recognition model),同时我们也可以自行进行模型训练来识别人体及其他物体(objects),进而实现对实物(real-world objects)的识别(recognition)。

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

在指定位置放置了所需的deploy.prototxt和opencv_face_detector.pbtxt文件。随后,在GitHub上执行相应的搜索操作以获取所需资源。

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

查看一下如下两个分支吧,在其中能找到很多其他的一些分支是用来做其他检测使用的。使用的时候可以直接在里面找到我们需要下载的那个模型文件。

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

GitHub不再做介绍的情况下,在这里我们已经成功地将所有所需模型文件进行了下载。目前系统中运行的核心检测函数共有四个。

获取训练模型:采用readNetFromCaffe或readNetFromTensorflow进行图像预处理:形成blob图像配置网络输入值:设置输入层执行网络预测:进行前向传播

图片预处理:blobFormImage

函数原型:def blobFromImage(image, scalefactor=None, size=None, mean=None, swapRB=None, crop=None, ddepth=None)是该函数的主要功能,涉及两个核心步骤:

整体像素值减去平均值(mean)

通过缩放系数(scalefactor)对图片像素值进行缩放

主要参数解释:

image:输入图像对象。

为了从图片中整体扣除其均值以达到标准化效果,在人脸识别领域中这一过程通常采用一组预设参数(104.0, 177.0, 123.0)作为参考标准。这些数值源自于模型在训练阶段的设置,并且由于已经针对特定场景进行了优化,在实际应用中可以直接复制使用以避免重复计算带来的误差影响。这些参数的具体位置可以在train.prototxt文件中找到相应的说明部分。

scalefactor:经过像素去平均值以后,进行图片缩放,默认是1

size:这个参数是我们神经网络在训练的时候要求输入的图片尺寸。

swapRB:OpenCV默认将图像通道顺序设为BGR,在我的均值计算则基于RGB顺序。因此,在需要交换红绿通道的情况下,请设置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.loadNetwork("deploy.prototxt", "res10_300x300_ssd_iter_140000_fp16.caffemodel")

net = cv2.dnn.loadModel("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未检测出来的图片

51a697462b356eeff5272977949fab0c.png

DNN检测结果

以上图片中基于Haar算法难以辨识面部表情特征(expression),而基于深度神经网络(DNN)则能够充分支持多维度的人脸识别功能(facial recognition)。如果采用OpenCV官方提供的训练模型进行实际应用,则涉及的函数调用和参数设置都基于上述设定(configuration)。这种配置下不仅能够实现高效的图像处理(image processing),还能保证超过99%的准确率(accuracy)。

总结

OpenCV支持的人工智能DNN人脸识别系统在性能和精度方面均表现出色,并且具有广泛的实际应用场景。该系统操作简便,在实际应用中展现出良好的效果。感谢作者分享:http://bjbsair.com/2020-04-07/tech-info/30754.html

人脸识别准确率低?

上一篇我们介绍了利用OpenCV实现人脸识别的基础流程。然而通过测试结果可以看出,在实际应用中该方法存在显著的问题:其识别准确率和处理速度均较低,并且误检率较高;此外由于系统在识别过程中带来了较大的计算资源消耗,并且难以满足实际需求;该模块基于Haar算法实现,并且在检测准确率方面表现欠佳,并且对人脸角度的变化较为敏感;伴随着深度学习技术的进步,在人脸识别领域涌现了许多性能卓越的新算法

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

  1. 大量将非人脸图像误判为人脸;
  2. 无法处理非正面的人脸图像;
  3. 不具备抗遮挡能力。

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

该系统无法有效识别小型面部特征(因为其训练数据设定最低人脸尺寸为80×80像素),但用户可自行采集小尺寸人脸图像进行本地模型训练以提升检测精度。此外,在复杂场景中(如头部被遮挡),边界框可能未能精确识别出面部区域(尤其是在除去额头部分以及部分下巴区域)。系统在存在严重遮挡时表现欠佳(尤其是当面部处于侧向或极端非正面方向的人脸图像时)。该系统不适用于侧面及高度倾斜的脸部视角(例如俯视或仰视角度)。

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

1)该算法在CPU运行方面表现出较低效率;
2)该系统无法有效检测小尺寸的脸部特征;其设计限定最小人脸尺寸为80×80像素;但用户可自行调整输入图像分辨率以优化性能;
3)该方法所生成的人脸包围框尺寸甚至低于基于DLib HoG的技术标准。

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

0fc3f14d3e45bc93b026572564d395f0.png

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

OpenCV DNN人脸检测

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

使用cv2库中的dnn模块加载配置文件至模型中;部署协议文件到模型中

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

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

使用OpenCV的dnn模块解析TensorFlow模型来读取两个pb文件:'opencv_face_detector_uint8.pb'和'opencv_face_detector.pbtxt'

OpenCV已经预设了训练好的人脸识别模型。同时我们可以进行自定义训练。除了识别其他物体之外,还可以实现实物识别。

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

在当前目录中存在 deploy.prototxt 和 opencv_face_detector.pbtxt 两个文件,请继续通过 GitHub 平台搜索 opponent_3rdparty 资源库。接下来,请点击以下链接打开该资源包

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

查看当前这两个子分支的情况时,请注意它们之外还有其他的一些子分支专门用于执行不同的检测任务。这些子分支中的每一个都可以用来查找所需模型文件的位置,在其中找到后即可下载相应的模型文件。

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

GitHub download files are no longer going to be discussed here. Moving forward, all necessary model files have been successfully downloaded and are ready for use. Among these, the core detection functions include four key components.

加载训练模型:使用Caffe框架加载模型或调用TensorFlow接口加载模型;构建图像批;为网络设定输入值;执行前向传播操作

图片预处理: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;因此,在需要交换红绿(Red-Green)通道的情况下,默认就需要将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.loadOpenCVModel('deploy.prototxt', 'res10_3xx...')

net = 通过 OpenCV DNN 库的 read 函数读取 " winterized Protocol Buffers 文件" 和 " Protocol Buffers 文件"

file_path = 'data/380.png'

test_file(net, file_path)

test_camera(net)

OpenCV Haar & OpenCV DNN

Haar检测结果

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

51a697462b356eeff5272977949fab0c.png

DNN检测结果

对于上述图片而言,在仅依赖于Haar特征时难以识别。然而,在利用深度神经网络(DNN)进行处理时能够实现高度准确的人脸识别。如果我们在基于OpenCV提供的预训练模型构建的人脸识别系统中采用以下配置,则可以实现高效的处理流程:其中函数调用及所需参数通常与上述配置保持一致,并且其准确率达到99%以上。

总结

基于深度神经网络(DNN)的人脸检测技术,在OpenCV平台中为我们提供了这一功能模块。无论在运行效率、检测精度等方面都表现卓越,并且在实际应用场景中展现出显著的应用价值。操作简便地到这里人脸识别这块我们就先告一段落。感谢作者分享-http://bjbsair.com/2020-04-07/tech-info/30754.html

人脸识别准确率低?

在上一篇中介绍了利用OpenCV实现人脸识别的基础步骤。然而通过测试发现识别人脸的准确率和速度较慢,并且误检率偏高,在此之前 getDefault 的人脸检测工具基于Haar特征提取方法开发,在识别过程中系统对资源需求较高,并且当面部朝向较大时难以被正确识别。此外发现虽然有一定性能但依然存在不足随着深度学习技术的进步出现了众多性能优越的新颖人脸检测算法

人脸检测方式对比

OpenCV Haar人脸检测

优点

1)几乎可以在CPU上实时工作;

2)简单的架构;

3)可以检测不同比例的人脸。

  1. 将大量非真实的人脸图像误判为真实的人脸;2) 不具备处理侧向或非正面方向的脸部图像的能力;3) 对强光、阴影等外部干扰具有较差的鲁棒性。

OpenCV DNN 人脸检测

优点

1)在这四种方法中是最准确的;

2)在CPU上能够实时运行;

3)适用于不同的人脸方向:上,下,左,右,侧面等。

4)甚至在严重遮挡下仍能工作;

5)可以检测各种尺度的人脸。

缺点基本上没有什么明显的缺点

Dlib HoG人脸检测

优点

1)CPU上最快的方法;

2)适用于正面和略微非正面的人脸;

3)与其他三个相比模型很小;

4)在小的遮挡下仍可工作。

该系统在以下方面存在不足:
1)无法识别小脸:该系统最低人脸尺寸设定为80×80像素。不过用户若希望使用更小尺寸的数据进行本地化训练也是可行的。
2)边界框覆盖范围有限:边界框通常会遮挡额头及下巴的部分区域。
3)复杂场景处理能力有限:当存在严重的遮挡时其性能会有所下降。
4)适用场景有限:尤其不适合侧视或极度非正面的方向(如俯视或仰视)。

Dlib CNN人脸检测

优点

1)适用于不同的人脸方向;

2)对遮挡鲁棒;

3)在GPU上工作得非常快;

4)非常简单的训练过程。

  1. CPU运行效率较低;2) 该系统无法处理小尺寸的脸部图像,因为其训练数据设定最低人脸尺寸为80×80像素;然而用户可以通过使用更小尺寸的人脸数据来自定义检测器;3) 该系统生成的人脸包围框尺寸甚至小于DLib HoG算法所采用的人脸检测器。

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

0fc3f14d3e45bc93b026572564d395f0.png

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

OpenCV DNN人脸检测

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

net = OpenCV.dnn.loadModel("deploy.prototxt", "res1₀₃₀₀ₓ₃₀₀ₛₛᵢₜér₁₄₀₀₀₀₀_fᵖ¹⁶.caffemodel")

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

网络参数通过OpenCV的深度神经网络接口从TensorFlow加载相应的模型文件路径参数:一个用于脸部检测的uint8量化pb文件"opencv_face_detector_uint8.pb"及其对应的pbtxt标签文件"opencv_face_detector.pbtxt")。

OpenCV现提供现成的人脸识别模型。也可自行训练。同样也能识别人体及其他物体。实现在人识别人体及其他物体。

下载训练模型

在GitHub中搜索opencv

33a7fcc3afd55511828c61aeb6a79192.png

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

90e12a40db6a2846514fc7030b1de66e.png

放置着 deploy.prototxt 和 opencv_face_detector.pbtxt 文件。接着在 GitHub 上搜索opencv_3rdparty,并将其打开如下:

7079b81377b3e57c1e272c9fd9a6e3f1.png

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

a1042b6ef3fa9730f207ae5839951914.png

在当前结构中存在两个明显的分支节点,在这里不仅有这两个主要路径,在这些选项中找到所需功能后点击进入,则会直接展示出我们需要下载的那个模型文件。

043f336837e3c778f6d6c8dbdee802cf.png
391f8a038e1626e8ef75f108483603ce.png

image.png

GitHub不再做介绍,目前而言,模型相关文件均已成功获取,其中最为关键的是检测功能,该功能主要包括以下四个关键组件:

加载训练模型:采用readNetFromCaffe或readNetFromTensorflow进行图像预处理,并将输入设置为blobFormImage后执行网络输入值的设置;随后通过setInput函数完成输入值的赋值,并利用forward函数进行网络预测

图片预处理:blobFormImage

该主要函数涉及两个核心步骤:

  1. 首先通过指定或默认的方式设定缩放因子和图像尺寸
  2. 然后计算图像均值向量并进行通道交换操作
    整个处理流程确保图像数据得到标准化处理

整体像素值减去平均值(mean)

通过缩放系数(scalefactor)对图片像素值进行缩放

主要参数解释:

image:输入图像对象。

为了达到更好的识别效果,在预处理阶段需要将输入图像中的每个像素扣除一个固定的均值向量(mean),该向量包含三个元素分别对应RGB三个通道的平均偏移量(104.0, 177.0, 123.0)。这个过程通常被称为归一化处理。值得注意的是,在实际应用中这些均值是在模型训练过程中预先确定好的参数,并且已经被优化用于提升模型的整体性能。由于我们已经在训练阶段使用过这些参数构建好了模型框架(如图所示),因此在测试阶段可以直接调用而不需额外计算这些统计量。具体的操作可以在train.prototxt配置文件中找到相关设置部分

scalefactor:经过像素去平均值以后,进行图片缩放,默认是1

size:这个参数是我们神经网络在训练的时候要求输入的图片尺寸。

swapRB:基于OpenCV的默认颜色通道顺序为BGR这一设定,在我的代码中默认假设为RGB;因此,在需要调换红绿通道以实现兼容性时,则需启用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 = OpenCV.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未检测出来的图片

51a697462b356eeff5272977949fab0c.png

DNN检测结果

同样的图片在采用Haar特征时难以实现有效的脸部识别。相比之下,基于深度神经网络(DNN)的方法能够显著提高识别准确率。当我们采用OpenCV提供的训练模型进行人脸识别时,默认的函数调用和所需参数与上文一致,并且其准确率达到99%以上。

总结

基于OpenCV的深度神经网络(DNN)实现的人脸检测技术,在效率和准确性等多个方面表现卓越,在实际应用场景中具备实用性,并且操作简便且易于部署。至此为止,在人脸识别这块我们就先做一个阶段性总结。

全部评论 (0)

还没有任何评论哟~