本节将介绍 Haar 级联分类器,通过对比分析相邻图像区域来判断给定图像或子图像与已知对象是否匹配。

本章将考虑如何将多个  Haar 级联分类器构成一个层次结构,即一个分类器能识别整体区域(如人脸),而其他的分类器可识别小的区域(如鼻子、眼睛和嘴)。

1 Haar 级联的概念

图像会因灯光、视角、视距、摄像头抖动以及数字噪声的变化而使得细节变得不稳定。所以提取图像的细节对产生稳定分类结果和跟踪结果很有作用。这些提取的结果被称为特征。

专业的表述为:从图像数据中提取特征。虽然任意像素都可能影响多个特征,但特征应该比像素少的多,两个图像的相似程度可以通过它们对应特征的欧式距离来度量。

例如:距离可能以空间坐标或颜色坐标来定义。类 Haar 特征是一种用于实现实时人脸跟踪的特征,每个类 Haar 特征都描述了相邻图像区域的对比模式。例如,边、顶点和细线都能生成具有判别的特征。

对于给定的图像,特征可能会因区域大小(也成为窗口大小 window size)而有所不同。仅在尺度上不同的两幅图也应该有相似的特征。因此能为不同大小的窗口生成特征非常有用,这些特征几何称之为级联。

Haar 级联具有尺度不变性,也即在尺度变化上具有鲁棒性。OpenCV 提供了尺度不变 Haar 级联的分类器和跟踪器,可将其保存成指定的文件格式。

注意:OpenCV 的 Haar 级联不具有旋转不变性;如,Haar 级联不认为倒置的人脸图像和直立的人脸图像一样,而侧面的人脸图像和正面的人脸图像也不一样;更可通过多种图像变换和多种窗口大小来提高 Haar 级联的旋转鲁棒性,但这样会变得很复杂,而且会耗费更多计算资源。

2 获取 Haar 级联数据

2.1 haarcascades---各种分类器xml文件在哪里?

(小插曲,可直接跳过本节内容,没干货)

在《OpenCV 3 计算机视觉 Python语言实现》中有这样一段话:

在 OpenCV 3 源代码的副本中会有一个文件夹 data/haarcascades。

我就先找源代码,当时的思路是先找 OpenCV 包的安装源代码,方式如下

C:\Users\****>python
>>> import cv2
>>> print(cv2.__file__)
C:\Users\***\AppData\Local\Programs\Python\Python36\lib\site-packages\cv2.cp36-win_amd64.pyd

将文件路径

(C:\Users\***\AppData\Local\Programs\Python\Python36\lib\site-packages)

复制到文件地址栏,看到关于opencv的文件如下:

  • opencv_python-4.0.1.dist-info(文件夹)
  • cv.py
  • cv2.cp36-win_amd64.pyd
  • opencv.LICENSE
  • opencv.LICENSE-3RD-PARTY
  • opencv_ffmpeg401_64.dll

没有data/haarcascades文件。

查看包 packages 还可以采用下列代码

>>> import sys
>>> sys.path
['', 'C:\\Users\\***\\AppData\\Local\\Programs\\Python\\Python36\\python36.zip', 'C:\\Users\\***\\AppData\\Local\\Programs\\Python\\Python36\\DLLs', 'C:\\Users\\***\\AppData\\Local\\Programs\\Python\\Python36\\lib','C:\\Users\\***\\AppData\\Local\\Programs\\Python\\Python36', 'C:\\Users\\***\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages']

或者

>>> import sys
>>> module = sys.path
>>> for i in module:
...     print(i)
...(再敲一下回车键)

C:\Users\***\AppData\Local\Programs\Python\Python36\python36.zip
C:\Users\***\AppData\Local\Programs\Python\Python36\DLLs
C:\Users\***\AppData\Local\Programs\Python\Python36\lib
C:\Users\***\AppData\Local\Programs\Python\Python36
C:\Users\***\AppData\Local\Programs\Python\Python36\lib\site-packages

没有找到haarcasades文件夹,我想再继续看看安装的源代码 .whl 文件

先看看 OpenCV 的版本,查看方式如下:

方案一:先在命令提示符中输入python,进入python环境。

python>>> import cv2
>>> cv2.__version__
'4.0.1'

方案二:直接在命令提示符中输入下段代码

C:\Users\***>pip list
Package         Version
--------------- ----------
absl-py         0.6.1
opencv-python   4.0.1
...

该方法会显示出基于 pip 安装的所有 packages 列表。

打开安装的 .whl 文件,找到当时我的安装文件

opencv_python-4.0.1-cp36-cp36m-win_amd64.whl,

将.whl后缀修改为.zip,即

opencv_python-4.0.1-cp36-cp36m-win_amd64.zip

再将其解压,也没有发现书中所述文件,在data文件下下有 opencv_ffmpeg401_64.dll 文件。

2.2 haarcascades---各种分类器xml文件在这里

直接打开OpenCV(官网https://opencv.org/最下方有GitHub的代码超链接)在GitHub上的官方文件即可。文件地址:

https://github.com/opencv/opencv/tree/master/data/haarcascades

在这里( opencv / data / haarcascades / )有所有 OpenCV haarcascades 文件,这些文件可用于检测静止图像、视频和摄像头所得到的图像中的人脸。

首先创建一个项目文件夹,然后再创建一个子文件(命名为 cascade),将 haarcascades 文件夹中的所有文件复制到 cascades 文件夹中。

为方便下载,可以直接下载 haarcascdes 文件夹【点击我

其文件目录如下:

└─cascades
        haarcascade_eye.xml
        haarcascade_eye_tree_eyeglasses.xml
        haarcascade_frontalcatface.xml
        haarcascade_frontalcatface_extended.xml
        haarcascade_frontalface_alt.xml
        haarcascade_frontalface_alt2.xml
        haarcascade_frontalface_alt_tree.xml
        haarcascade_frontalface_default.xml
        haarcascade_fullbody.xml
        haarcascade_lefteye_2splits.xml
        haarcascade_licence_plate_rus_16stages.xml
        haarcascade_lowerbody.xml
        haarcascade_profileface.xml
        haarcascade_righteye_2splits.xml
        haarcascade_russian_plate_number.xml
        haarcascade_smile.xml
        haarcascade_upperbody.xml

从文件名可知,这些级联是用于人脸、眼睛、鼻子和嘴的跟踪(人脸检测器),这些文件需要正面、直立的人脸图像。

接下来我们创造自己的级联,并训练这些级联来检测各种对象。

2019年03月10日更新

今天发现不同的安装方式,其包含的内容是由区别的,因为要学习书中第六节内容SIFT,结果采用重新安装 opencv。

pip install opencv_contrib_python

发现文件中就含有data/***.xml 检测器文件。

而采用在python非官方第三方库中下载安装,就没有data/.xml 文件。

3 使用 OpenCV 进行人脸检测

人脸检测的图像来源可分为:

  • 静态图像
  • 视频

静态图像和视频中检测人脸的操作非常相似,基本理论也是一致的;实际上,视频人脸检测是从摄像头中读取每帧图像,然后采用静态图像中的人脸检测方法进行检测;不过视频人脸检测还涉及诸如跟踪等静态图像中没有的概念。

3.1 静态图像中的人脸检测

图像识别内容及其分析详见下代码

import cv2

filename = './pic.jpg'

def detect(filename):
    # 声明一个变量,该变量为级联分类器CascadeClassifier对象,它负责人脸检测
    face_cascade = cv2.CascadeClassifier('./cascades/haarcascade_frontalface_default.xml')

    # 加载文件并将其转为灰度图,因人脸检测需要这样的色彩空间
    img = cv2.imread(filename)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # detectMultiScale函数检测操作返回人脸矩形数组
    # scaleFactor=1.15 - 人脸检测过程中每次迭代时图像的压缩率
    # minNeighbors=5 - 人脸检测过程中每次迭代时每个人脸矩形保留近邻数目的最小值,   # 调节这两个参数可以实现人脸的有效识别
    faces = face_cascade.detectMultiScale(gray,1.15, 5)
    # print(faces.shape) # (16,4)
    # 这里面会出现 16 行 4 列,代表16个矩形
    # 每个矩形为(x,y,w,h)
    print(faces) 

    # 通过依次提取faces变量中的值来找人脸,并在人脸周围绘制蓝色矩形(255,0,0)
    # cv2.rectangle通过坐标绘制矩形(x和y表示左上角,w和h表示人脸矩形的宽度和高度
    # 注意这是在原始图像而不是灰度图上进行绘制
    for (x,y,w,h) in faces:
        img = cv2.rectangle(img, (x,y),(x+w,y+h),(255,0,0),2)
    # 最后创建nameWindow的实例,并显示处理后的图像。
    cv2.namedWindow('Detected')
    cv2.imshow('Detected',img)
    cv2.imwrite('./Detected.jpg', img)
    # 加入waitKey函数,这样在按下任意键时才可关闭窗口
    cv2.waitKey(0)

detect(filename)

运行

[[1916  781  121  121]
 [1524  804  122  122]
 [2308  796  132  132]
 [2788 1305  292  292]
 [2917  848  162  162]
 [ 165 1172  241  241]
 [3366 1182  246  246]
 [1181  851  135  135]
 [2663  853  138  138]
 [ 604  869  158  158]
 [ 797 1194  240  240]
 [ 884  905  144  144]
 [3132  935  155  155]
 [ 385  978  196  196]
 [3579 1029  230  230]
 [1544 1312  249  249]]

输出图像 【原图像

3.2 视频中的人脸检测

3.1 的章节内容可以实现静态图像上的人脸检测;实际上,在视频的帧上重复3.1 章节中的过程就能完成视频(摄像头的输入或视频文件)中的人脸检测。

在书中的其他地方一直出现报错,后来 参考 视频人脸检测——OpenCV版(三),两者结合学习才将问题解决。同时觉得课本上的代码结构没有 王磊 博客中那个合理,书中将人脸检测和视频流读入有部分杂糅。下图是可以运行的代码。

import cv2

# 图片识别方法封装,
def discern(img):
    # 将图img转为灰度图,因opencv中的人脸检测是基于灰度的色彩空间
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 实例化级联分类器
    face_cascade = cv2.CascadeClassifier('D:/project/opencv3/c5/cascades/haarcascade_frontalface_default.xml')
    # 调用图像中的对象,并返回矢量矩形
    faceRects = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(50, 50))
    # 只要视频存在,就输出人脸识别框
    if len(faceRects):
        # 框出人脸,分开写
        # for faceRect in faceRects:
            # x, y, w, h = faceRect
            # cv2.rectangle(img, (x, y), (x + h, y + w), (0, 255, 0), 2)
        # 框出人脸,合并写
        for (x,y,w,h) in faceRects:
            # 在原彩色图img上绘制识别的人脸矩形
            cv2.rectangle(img, (x, y), (x + h, y + w), (0, 255, 0), 2)
    # 将绘制有矩形框的img显示输出
    cv2.imshow("Image", img)

# 打开一个VideoCapture目标(初始化摄像头)
# 参数为摄像头ID,0表获取第一个摄像头
cap = cv2.VideoCapture(0)
while(True):
    # 将视频逐帧显示
    ret, img = cap.read()
    # 调用discern函数
    discern(img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
# 释放摄像头
cap.release()
# 释放窗口资源
cv2.destroyAllWindows()

运行输出

可以识别出人物。

3.3 视频中的人脸和人眼检测

将3.2 章节中的内容进行丰富,人脸识别的同时,增加人眼识别。代码如下:

import cv2

# 图片识别方法封装,
def discern(img):
    # 将图img转为灰度图,因opencv中的人脸检测是基于灰度的色彩空间
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 实例化级联分类器
    face_cascade = cv2.CascadeClassifier('D:/project/opencv3/c5/cascades/haarcascade_frontalface_default.xml')
    eye_cascade = cv2.CascadeClassifier('D:/project/opencv3/c5/cascades/haarcascade_eye.xml')
    # 调用图像中的对象,并返回矢量矩形
    faceRects = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3, minSize=(50, 50))
    # 只要视频存在,就输出人脸识别框
    if len(faceRects):
        # 框出人脸,分开写
        # for faceRect in faceRects:
            # x, y, w, h = faceRect
            # cv2.rectangle(img, (x, y), (x + h, y + w), (0, 255, 0), 2)
        # 框出人脸,合并写
        for (x,y,w,h) in faceRects:
            # 在原彩色图img上绘制识别的人脸矩形
            cv2.rectangle(img, (x, y), (x + h, y + w), (0, 255, 0), 2)
            # 将眼睛区域限制在人脸范围内,不过这种方式不太好用
            # roi_gray = gray[y:y+h, x:x+w]
            # eyes = eye_cascade.detectMultiScale(roi_gray,scaleFactor=1.03,minNeighbors=5,flag=0,minSize=(40,40))
            eyes = eye_cascade.detectMultiScale(img,scaleFactor=1.03,minNeighbors=5,minSize=(40,40))

        # 框出人眼
        for (ex,ey,ew,eh) in eyes:
            cv2.rectangle(img,(ex,ey),(ex+ew,ey+eh),(0,0,255),2)

    # 将绘制有矩形框的img显示输出
    cv2.imshow("Image", img)

# 打开一个VideoCapture目标(初始化摄像头)
# 参数为摄像头ID,0表获取第一个摄像头
cap = cv2.VideoCapture(0)
while(True):
    # 将视频逐帧显示
    ret, img = cap.read()
    # 调用discern函数
    discern(img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放摄像头
cap.release()
# 释放窗口资源
cv2.destroyAllWindows()

在眼睛检测中增加了参数,增加的主要原因是detectMultiScale有许多参数;在人脸检测时,默认的选项足以完成人脸检测,但是眼睛是一个比较小的人脸特征,且还存在胡子、鼻子等本身阴影(self-casting shadow)以及帧的随机阴影都会产生假阳性(false positive)

通过限制对眼睛搜索的最小尺寸为 40 * 40 像素,可去掉所有的假阳性。然后调试这些参数,直到程序可满足预期(例如,可以尝试指定特征的最大尺寸,或增加比例因子以及邻近的数量)。


关于 cv2.waitKey(1) & 0xFF == ord('q') 的理解

Opencv中使用waitKey(10) & 0xFF的原因

cv2.waitKey

用python opencv 调用摄像头之if cv2.waitKey(1) & 0xFF == ord('q')分析

3.4 人脸识别

人脸检测是OpenCV的一个不错的功能,它是人脸识别的基础。

人脸识别就是程序能识别给定图像或视频中的人脸;可通过一系列分好类的图像(人脸数据库)来 ” 训练 “ 程序。并基于这些图像进行识别。

人脸识别所需的人脸获取方式

  • 自己获得图像
  • 从人脸数据库免费获得可用的人脸图像

3.4.1 生成人脸识别数据

人脸识别模块的一项重要特征:每个识别都具有转置信(confidence)评分。所以在实际应用中通过对其设置阈值来进行筛选。

下段代码可制定样本,依据代码可知,样本具有如下特征:

  • 图像为灰度格式,后缀名为.pgm
  • 图像为正方形
  • 图像大小要一样(这里保存为200*200,大多是免费图像集都比这个小)

具体代码如下:

import cv2
import time

# 图像名编号
count = 1
# 记录循环次数
i = 1
# 控制图片保存频率,间隔10次保存一次图像
FREQUENCY = 5
# 拟制备样本数量
MAX = 20

# 图片识别方法封装,
def discern(img):
    global count
    global i
    global FREQUENCY

    # 将图img转为灰度图,因opencv中的人脸检测是基于灰度的色彩空间
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 实例化级联分类器
    face_cascade = cv2.CascadeClassifier('D:/project/opencv3/c5/cascades/haarcascade_frontalface_default.xml')
    eye_cascade = cv2.CascadeClassifier('D:/project/opencv3/c5/cascades/haarcascade_eye.xml')
    # 调用图像中的对象,并返回矢量矩形
    faceRects = face_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5)
    # 只要视频存在,就输出人脸识别框
    if len(faceRects):
        # 框出人脸
        for (x,y,w,h) in faceRects:
            # 在原彩色图img上绘制识别的人脸矩形
            cv2.rectangle(img, (x, y), (x + h, y + w), (255, 0, 0), 2)
            # 裁剪灰度帧的区域,将其调整为200*200像素
            f = cv2.resize(gray[y:y+h, x:x+w],(200,200))

            # 控制输出频率,如果没有控制,则输出的非常快
            i += 1
            if i % FREQUENCY == 0:
                # 将裁剪区域保存到指定文件夹中,文件后缀名为.pgm
                cv2.imwrite('D:/project/opencv3/c5/%s.pgm' %str(count),f)
                count += 1

        # 将绘制有矩形框的img显示输出
        cv2.imshow("camera",img)

# 打开一个VideoCapture目标(初始化摄像头)
# 参数为摄像头ID,0表获取第一个摄像头
cap = cv2.VideoCapture(0)
while(True):
    # 将视频逐帧显示
    ret, img = cap.read()
    # 调用discern函数
    discern(img)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    # 如果大于所需样本数量,则推出循环程序
    if count > MAX:
        break

# 释放摄像头
cap.release()
# 释放窗口资源
cv2.destroyAllWindows()

注意:

如果不加图像保存速率,则会短时间内保存大量图片;同时图像保存速率可以人为控制,实验中发现,时间间隔愈大,运行速度越慢。

3.4.2 人脸识别

OpenCV 3 有三种人脸识别的方式,对应于三种不同的算法:

  • Eigenfaces - Eigenfaces 是通过 PCA 来处理的,PCA 是计算机视觉中提到最多的数学概念。PCA 的本质是识别某个训练集上(比如人脸数据库)的主成分,并计算出训练集(图像或帧中检测到的人脸)相对于数据库的发散程度,并输出一个值。该值越小,表明人脸数据库和检测到的人脸之间的差别就越小;0 值表示完全匹配。
  • Fisherfaces - Fisherfaces 是从PCV 衍生并发展起来的概念,它采用更复杂的逻辑。尽管计算更加密集,但比Eigenfaces 更容易得到准确的效果。
  • Local Binary Pattern Histogram(LBPH) - LBPH粗略地(在非常高的层次上)将检测到的人脸分成小单元,并将其与模型中的对应单元进行比较,对每个区域的匹配值产生一个直方图。由于这种方法的灵活性,LBPH 是唯一允许模型样本人脸和检测到的人脸在形状、大小上可以不同的人脸识别算法。书中作者认为这种是最准确的算法,但是每个算法都有其长处和缺点。

备注:所有的方法都有类似的过程,即都使用了分好类的训练数据集(人脸数据库,每个人都有很多样本)来进行 " 训练 “ ,对图像或视频中检测到的人脸进行分析,并从两方面来确定:

  • 是否识别到目标
  • 目标真正被识别到的置信度的度量,这也称为置信度评分

2.4.3 准备训练数据

将已有的样本图像加载到人脸识别算法中。

一般而言,人脸识别算法在它们的 train() 函数中都有两个参数:

  • 图像数组
  • 标签数组

基于上述要求创建一个 逗号分隔值(comma-separated value,CSV)的文件,并用ID记录样本图像的路径。CSV文件内容如下所示

jm/1.pgm; 0

jm/2.pgm; 0

jm/3.pgm; 0

...

jm - 文件夹

1.pgm、2.pgm - 样本图像

0 - 人脸ID,假如 A 的人脸ID为0,B 的人脸 ID 为 1 。标签。

2.4.4 加载数据并识别人脸

本段代码会将 图像数组 和 CSV 文件加载到人脸识别的算法中,以训练人脸识别算法。

1、需要创建函数用来逐行读取 CSV 文件。

2、将对应路径的图像加载到图像数组中。

3、将 ID 加载到标签数组中。

4、基于 Eigenfaces 的人脸识别

详细代码如下所示:

import cv2
import os
import numpy as np

# 建立标签
label_num = [0, 1, 2]
label_name = ["gengyi", "cat", "gengniu"]
images = []
labels = []

# 将图像数组和CSV文件加载到人脸识别的算法中
def read_images(path):
    # 定义数据和标签
    # 获取path文件下的文件及文件夹并返回名称列表
    for dir_item in os.listdir(path):
        # 返回path规范化的绝对路径
        path_abs = os.path.abspath(os.path.join(path, dir_item))
        # 判断path_abs是文件还是文件还是文件夹
        try:
            # str.endswith()是判断文件str后缀是否为指定格式
            # 本图像指定为.png格式
            if(path_abs.endswith('.png')):
                # print("try:", path_abs)
                # 读取训练数据
                img = cv2.imread(path_abs)
                # 统一输入文件的尺寸大小
                img = cv2.resize(img, (200, 200))
                # 统一图像文件的元素dtype,并将其加入images中
                images.append(np.asarray(img, dtype=np.uint8))
                # 为训练数据赋标签
                # 简单地可以用,当文件夹为me时,标签设置为0
                # if(dir_item.endswith('gengyi')):
                #   labels.append(0)
                # 为了代码更具有实用性,拟以下处理
                # 先将path_abs分割,注意分割线\\,而不是//
                path_piece = path_abs.split('\\')
                # 为训练数据赋标签,较多标签通过elif追加即可
                if label_name[0] in path_piece:
                    labels.append(label_num[0])
                elif label_name[1] in path_piece:
                    labels.append(label_num[1])
                elif label_name[2] in path_piece:
                    labels.append(label_num[2])
                else:
                    # 没有对应标签则删除训练数据
                    images.pop()
                    # pass
            # 若为文件夹则递归调用,循环读取子子文件内容
            elif os.path.isdir(path_abs):
                read_images(path_abs)
            # 若为其他情况则循环运行
            else:
                continue
        # 当发生异常时则抛出异常信息e
        except Exception as e:
            print("REASON:", e)
    print('labels:',labels)
    print("images:",images)
    return images, labels

# 基于Eigenfaces的模型训练
def face_model():

    # 使用label_num作为全局变量
    # 每当脚本识别出一个ID,就会将相应名称数组中的名字打印到人脸上
    global label_num
    # 获取文件所在文件夹的绝对路径
    path = os.getcwd()
    # 调用图像读入函数,获取训练数据及标签
    images, labels = read_images(path)
    # print("face_model_images:", images)

    # 实例化人脸识别模型
    model = cv2.face.EigenFaceRecognizer_create()
    # 通过图像数组和标签来训练模型
    model.train(np.asarray(images), np.asarray(labels))

    return model

def face_rec():
    # 调用训练好的模型
    face_model_trained = face_model()
    # 初始化摄像头
    camera = cv2.VideoCapture(0)
    # 实例化人脸识别级联分类器
    face_cascade = cv2.CascadeClassifier('D:/project/opencv3/c5/cascades/haarcascade_frontalface_default.xml')
    while(True):
        read, img = camera.read()
        faces = face_cascade.detectMultiScale(img, 1.3, 5)
        for (x, y, w, h) in faces:
            img = cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            roi = gray[x:x+w, y:y+h]
            try:
                roi = cv2.resize(roi, (200, 200), interpolation=cv2.INTER_LINEAR)
                # predict()预测函数,返回预测标签和置信度
                params = face_model_trained.predict(roi)
                print("Label: %s, confidence: %0.2f" % (label_name[params[0]], params[1]))
                cv2.putText(img, label_name[params[0]], (x, y-20), cv2.FONT_HERSHEY_SIMPLEX, 3, (255, 0, 0), 2)
            except Exception as e:
                print("face_rec_REASON:", e)

        cv2.imshow('camera', img)
        if cv2.waitKey(10) & 0xff == ord('q'):
            break

    cv2.destroyAllWindows()

if __name__ == '__main__':
    face_rec()

注意:上述代码是基于被训练的图片与该文件在同一个文件夹下。

备注:代码一直识别错误。查找不出原因。

附:

2.4.5 基于 Fisherfaces 的人脸识别

Fisherfaces 的实现过程并没有太大变化,只需要采用不同的算法。模型变量的声明如下:

model = cv2.face.FisherFaceRecognizer_create()

备注:该函数与 《 OpenCV 3 计算机视觉 Python 语言实现》中的函数有差别。该函数参数与 Eigenfaces 参数相同,保留 Fisherfaces 的参数以及置信度阈值;置信度高于该阈值的人脸将被丢弃。

2.4.6 基于 LBPH 的人脸识别

该运算过程与前面的识别过程很类似;该算法的参数有点复杂,这些参数依次表示 radius、neighbors、grid_x、grid_y 以及置信度阈值;如果不指定这些值,这些参数就会取默认值:1,8,8,8,123.0。模型声明如下。

model = cv2.face.createLBPHFaceRecognizer()

备注:

对于 LBPH 不需要调整图像大小,因为网格中的分割允许在每个单元中比较识别到的模式。

对于上面的话,纯书中的内容,没有验证!

2.4.7 通过置信度评分来丢弃结果

predict() 函数返回值含有两个元素的数组:

  • 被识别个体的标签
  • 置信度评分

所有的算法都有一个置信度评分阈值,置信度评分用来衡量所识别人脸与原模型的差距,0 表示完全匹配。

可能有时不想保留所有的识别结果,则需进一步处理,因此可用自己的算法来估算识别的置信度评分。

例如:如果正在试图识别视频中的人,则可能要分析后续帧的置信度评分来评估识别是否成功,在这种情况下,可通过算法来检查得到的置信度评分,然后得出自己的结论。

Eigenfaces / Fisherfaces 和 LBPH 的置信度评分值完全不同。Eigenfaces 和 Fisherfaces 将产生 0 到 20000 的值,而任意低于 4000 到 5000 的评分都是相当可靠的识别。

LBPH 有类似的工作方式,但是一个好的识别参考值要低于 50 ,任何高于 80 的参考值都会被认为是低的置信度评分。

Python中 sys.argv[]的用法简明解释

os.walk和os.listdir遍历目录比较

python os.path模块常用方法详解

Python endswith()方法

Python List 删除元素

os.getcwd()、sys.path[0]、sys.argv[0]和__file__的区别

import os

print(os.path.abspath('C:/Downloads/Machine Learning for OpenCV - 2017.pdf'))

# C:\Downloads\Machine Learning for OpenCV - 2017.pdf

Python 3.2

os.makedirs(path, exist_ok=True)

python 3.2创建目录新增了可选参数existok,把existok设置True,创建目录如果已经存在则不会往外抛出异常。exist_ok默认值为False

OpenCV 学习笔记 05 人脸检测和识别的更多相关文章

  1. OpenCV 学习笔记 05 人脸检测和识别 AttributeError: module 'cv2' has no attribute 'face'

    1 环境设置: win10 python 3.6.8 opencv 4.0.1 2 尝试的方法 在学习人脸识别中,遇到了没有 cv2 中没有 face 属性.在网上找了几个方法,均没有成功解决掉该问题 ...

  2. OpenCV 学习笔记 07 目标检测与识别

    目标检测与识别是计算机视觉中最常见的挑战之一.属于高级主题. 本章节将扩展目标检测的概念,首先探讨人脸识别技术,然后将该技术应用到显示生活中的各种目标检测. 1 目标检测与识别技术 为了与OpenCV ...

  3. OpenCV 学习笔记 05 级联分类器CascadeClassifier类

    在人脸检测中,CascadeClassifier 是一个类,该类的作用是(基于官方已经训练好的数据文件 .xml)实例化一个检测器. 1 类 CascadeClassifier 的概述 首先看一下该类 ...

  4. OpenCV学习代码记录——人脸检测

    很久之前学习过一段时间的OpenCV,当时没有做什么笔记,但是代码都还在,这里把它贴出来做个记录. 代码放在码云上,地址在这里https://gitee.com/solym/OpenCVTest/tr ...

  5. opencv学习笔记霍夫变换——直线检测

    参考大佬博文:blog.csdn.net/jia20003/article/details/7724530 lps-683.iteye.com/blog/2254368 openCV里有两个函数(比较 ...

  6. OpenCV 学习笔记03 boundingRect、minAreaRect、minEnclosingCircle、boxPoints、int0、circle、rectangle函数的用法

    函数中的代码是部分代码,详细代码在最后 1 cv2.boundingRect 作用:矩形边框(boundingRect),用于计算图像一系列点的外部矩形边界. cv2.boundingRect(arr ...

  7. 基于OpenCv的人脸检测、识别系统学习制作笔记之三

    1.在windows下编写人脸检测.识别系统.目前已完成:可利用摄像头提取图像,并将人脸检测出来,未进行识别. 2.在linux下进行编译在windows环境下已经能运行的代码. 为此进行了linux ...

  8. 基于OpenCV读取摄像头进行人脸检测和人脸识别

    前段时间使用OpenCV的库函数实现了人脸检测和人脸识别,笔者的实验环境为VS2010+OpenCV2.4.4,opencv的环境配置网上有很多,不再赘述.检测的代码网上很多,记不清楚从哪儿copy的 ...

  9. OpenCV 学习笔记 02 使用opencv处理图像

    1 不同色彩空间的转换 opencv 中有数百种关于不同色彩空间的转换方法,但常用的有三种色彩空间:灰度.BRG.HSV(Hue-Saturation-Value) 灰度 - 灰度色彩空间是通过去除彩 ...

随机推荐

  1. Python之禅的翻译和解释

      The Zen of Python, by Tim Peters   Beautiful is better than ugly. Explicit is better than implicit ...

  2. Codeforces Round #309 (Div. 2) -D. Kyoya and Permutation

    Kyoya and Permutation 这题想了好久才写出来,没看题解写出来的感觉真的好爽啊!!! 题目大意:题意我看了好久才懂,就是给你一个序列,比如[4, 1, 6, 2, 5, 3],第一个 ...

  3. BZOJ5120 [2017国家集训队测试]无限之环 费用流

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ5120 题意概括 原题挺简略的. 题解 本题好难. 听了任轩笛大佬<国家队神犇>的讲课才 ...

  4. 二分搜索-HihoCoder1128

    题目链接:https://hihocoder.com/problemset/problem/1128 题目描述: 题目大意就是要我们编程找出K在数组a中的大小排序后的位置. 代码实现: #includ ...

  5. Linux/Window 正斜杠 反斜杠

    文件目录结构: Linux 是用正斜杠 目录名区分大小写 Window 是用反斜杠 目录名不区分大小写

  6. 监听发现局域网dropbox客户端broadcast-dropbox-listener

    监听发现局域网dropbox客户端broadcast-dropbox-listener   Dropbox是一款网盘文件同步工具.为了实现局域网内同步,该工具会通过UDP 17500端口发送广播包.N ...

  7. 移动端html页面分享

    开发APP应用比开发移动端网页挑战小,因为APP应用只需要适配不同手机即可,而移动端网页不仅需要适配不同手机,还要适配同一部手机的不同浏览器. 移动端页面分享是一个常用的功能,需要宿主环境,可以是某A ...

  8. 项目冲刺 Sixth

    Sixth Sprint 1.各个成员今日完成的任务 蔡振翼:编写博客 谢孟轩:完善了编辑界面,实现续约功能 林凯:初步实现注册功能 肖志豪:帮助组员 吴文清:完善管理员图书录入功能以及图书录入的界面 ...

  9. HDU.5909.Tree Cutting(树形DP FWT/点分治)

    题目链接 \(Description\) 给定一棵树,每个点有权值,在\([0,m-1]\)之间.求异或和为\(0,1,...,m-1\)的非空连通块各有多少个. \(n\leq 1000,m\leq ...

  10. 洛谷.3437.[POI2006]TET-Tetris 3D(二维线段树)

    题目链接 下落一个d*s的方块,则要在这个平面区域找一个最高的h' 更新整个平面区域的值为h+h' 对于本题,维护最大高度h和all 对于平面的x轴维护一棵线段树t1,每个t1的节点维护对应y轴的两棵 ...