暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

关于OpenCV for Python入门-自带人脸识别工具测试

追梦IT人 2022-03-25
854

前文提到了OpenCV自带的人脸分类器,虽然准确度一般,但是含着泪也要把工作做完,巧了,OpenCV还提供了三种人脸识别算法(Eigenfaces、Fisherfaces、LBPH),这几种算法各有各的特点,识别率也一般。

OpenCV有三种人脸识别的算法:

Eigenfaces 他是通过PCA来处理的。PCA是计算机视觉中用的较多的数学概念。它的本质是,识别某个训练集上的主成分,并计算出检测到人脸相对于数据库的发散程度,并输出一个值,该值越小,表明人脸数据库和检测到的人脸之间的差别就越小,0表示完全匹配。低于4000-5000的值相对可靠

Fisherfaces  它是从PCA衍生发展起来的,逻辑更复杂,计算更密集,但是比Eigenfaces更容易得到准确的效果。

LBPH(Local Binary Pattern Histogram) 在非常搞的层次上,将检测到的人脸分成小单元,并将其与模型中的对应单元进行比较,对每个区域的匹配值产生一个直方图,由于这种方法的灵活性,它是唯一运行模型样本人脸和检测到的人脸在形状、大小上可以不同的人脸识别算法。置信分在50以内的相对来说比较可靠

model = cv2.face.EigenFaceRecognizer_create()

创建识别模型,使用EigenFace算法识别,Confidence评分低于4000是可靠

model = cv2.face.LBPHFaceRecognizer_create()

创建识别模型,使用LBPHFace算法识别,Confidence评分低于50是可靠

model = cv2.face.FisherFaceRecognizer_create()

创建识别模型,使用FisherFace算法识别,Confidence评分低于4000是可靠

新建一个预测文件夹,从训练图片中随机选了两种,从网上找了一张刘德华的照片,试一下识别效果如何。

获取训练集的函数与前文一致

在主函数中增加了一段训练的过程和预测的过程。

import cv2import numpy as npimport osimport shutil# OpenCV有三种人脸识别的算法:# Eigenfaces 他是通过PCA来处理的。PCA是计算机视觉中用的较多的数学概念。它的本质是,识别某个训练集上的主成分,并计算出检测到人脸相对于数据库的发散程度,并输出一个值,该值越小,表明人脸数据库和检测到的人脸之间的差别就越小,0表示完全匹配。低于4000-5000的值相对可靠# Fisherfaces  它是从PCA衍生发展起来的,逻辑更复杂,计算更密集,但是比Eigenfaces更容易得到准确的效果。# LBPH(Local Binary Pattern Histogram) 在非常搞的层次上,将检测到的人脸分成小单元,并将其与模型中的对应单元进行比较,对每个区域的匹配值产生一个直方图,由于这种方法的灵活性,它是唯一运行模型样本人脸和检测到的人脸在形状、大小上可以不同的人脸识别算法。置信分在50以内的相对来说比较可靠# model = cv2.face.EigenFaceRecognizer_create()# 创建识别模型,使用EigenFace算法识别,Confidence评分低于4000是可靠# model = cv2.face.LBPHFaceRecognizer_create()# 创建识别模型,使用LBPHFace算法识别,Confidence评分低于50是可靠# model = cv2.face.FisherFaceRecognizer_create()# 创建识别模型,使用FisherFace算法识别,Confidence评分低于4000是可靠# OpenCV 通过函数 cv2.face.EigenFaceRecognizer_create()生成特征脸识别器实例模型,# 然后应用 cv2.face_FaceRecognizer.train()函数完成训练,# 最后用cv2.face_FaceRecognizer.predict()函数完成人脸识别。# 1. 函数cv2.face.EigenFaceRecognizer_create()# retval = cv2.face.EigenFaceRecognizer_create( [, num_components[, threshold]] )# 其中:#   num_components:在 PCA 中要保留的分量个数。(一般来说, 80 个分量就足够了。)#   threshold:进行人脸识别时所采用的阈值。# 2. 函数cv2.face_FaceRecognizer.train()# 函数 cv2.face_FaceRecognizer.train()对每个参考图像进行 EigenFaces 计算,得到一个向量。每个人脸都是整个向量集中的一个点。# None = cv2.face_FaceRecognizer.train( src, labels )# 其中:#   src:训练图像,用来学习的人脸图像。#   labels:人脸图像所对应的标签。#   该函数没有返回值。# 3. 函数cv2.face_FaceRecognizer.predict()# 函数 cv2.face_FaceRecognizer.predict()在对一个待测人脸图像进行判断时,会寻找与当前图像距离最近的人脸图像。# 与哪个人脸图像最接近,就将待测图像识别为其对应的标签。# label, confidence = cv2.face_FaceRecognizer.predict( src )# 其中:#   src:需要识别的人脸图像。#   label:返回的识别结果标签。#   confidence:返回的置信度评分。置信度评分用来衡量识别结果与原有模型之间的距离。#   0 表示完全匹配。该参数值通常在 0 到 20 000 之间, 只要低于 5000, 都被认为是相当可靠的识别结果。#   注意,这个范围与 LBPH 的置信度评分值的范围是不同的。# 下载官方的ORL人脸数据库# 载入图像,读取ORL人脸数据库,准备训练数据def loadimageface(data):    # 加载图片数据用于训练    # params:data:训练数据所在的目录,要求图片尺寸一样    #ret:    #    images:[m,height,width]  m为样本数,height为高,width为宽    #    names:名字的集合    #    labels:标签    images = []    names = []    labels = []    face_casecade = cv2.CascadeClassifier('C:\\Python\\Python37\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml')    # haarcascade_frontalface_alt_tree  21    # [ 3  9 13 13 13 13 15 17 24 31 33 34 34 34 35 35 36 37 37 37 37]    # haarcascade_frontalface_alt   222    # [ 0  0  1  1  1  1  1  1  1  1  1  2  2  2  2  2  2  2  2  3  3  3  3  3    #   3  3  3  3  3  4  4  4  4  4  5  5  5  5  5  6  6  6  6  6  7  7  7  7    #   8  8  9  9  9  9  9  9  9  9  9  9 10 10 10 12 12 12 12 12 12 12 12 12    #  13 13 13 13 13 13 13 13 13 13 14 15 15 15 15 15 15 16 16 16 16 16 17 17    #  17 17 18 18 18 18 18 18 19 20 20 21 21 21 21 21 21 21 21 22 22 22 22 22    #  22 23 23 23 23 23 23 23 23 24 24 24 24 24 25 25 26 26 26 26 26 26 26 26    #  29 29 29 29 29 30 30 30 30 30 31 31 31 31 31 31 31 31 31 31 32 32 32 33    #  33 33 33 33 34 34 34 34 34 34 34 35 35 35 35 35 36 36 36 36 36 36 36 36    #  36 37 37 37 37 37 37 37 37 37 37 38 38 38 38 38 38 38 38 38 39 39 39 39    #  39 39 39 39 39]    # haarcascade_frontalface_alt2  231    # [ 0  0  0  1  1  1  1  1  1  1  1  1  2  2  2  2  2  2  2  3  3  3  3  3    #   3  3  3  3  3  4  4  4  4  5  5  5  5  6  6  6  6  6  6  7  7  7  7  7    #   7  8  8  9  9  9  9  9  9  9  9  9  9 10 10 10 12 12 12 12 12 12 12 12    #  12 13 13 13 13 13 13 13 13 13 13 15 15 15 15 15 15 15 15 15 16 16 16 16    #  16 16 16 16 17 17 17 17 17 18 18 18 18 18 19 19 19 20 20 21 21 21 21 21    #  21 21 21 22 22 22 22 22 22 22 23 23 23 23 23 23 23 23 23 24 24 24 24 24    #  25 25 26 26 26 26 26 28 29 29 29 29 29 30 30 30 30 31 31 31 31 31 31 31    #  31 31 31 32 32 32 32 32 32 33 33 33 33 33 34 34 34 34 34 34 34 35 35 35    #  35 35 36 36 36 36 36 36 36 36 36 37 37 37 37 37 37 37 37 37 37 38 38 38    #  38 38 38 38 38 39 39 39 39 39 39 39 39 39]    # haarcascade_frontalface_default   264    # [ 0  0  0  0  0  1  1  1  1  1  1  1  1  2  2  2  2  2  2  2  2  2  2  3    #   3  3  3  3  3  3  4  4  4  4  4  4  5  5  5  5  5  5  5  5  5  5  6  6    #   6  6  6  6  6  7  7  7  7  7  7  7  8  8  9  9  9  9  9  9  9  9  9  9    #  10 10 10 10 10 12 12 12 12 12 12 12 12 12 12 13 13 13 13 13 13 13 13 13    #  13 14 14 14 14 14 14 14 15 15 15 15 15 15 16 16 16 16 16 16 16 16 16 17    #  17 17 17 17 18 18 18 18 18 19 19 19 19 19 19 19 19 19 19 20 20 20 20 20    #  20 21 21 21 21 21 21 22 22 22 22 23 23 23 23 23 23 23 24 24 24 24 24 25    #  25 25 25 26 26 26 26 26 26 26 26 26 29 29 29 29 29 29 29 30 30 30 30 30    #  30 30 31 31 31 31 31 31 31 31 31 32 32 32 32 33 33 33 33 33 33 33 33 34    #  34 34 34 34 34 34 35 35 35 35 35 36 36 36 36 36 36 36 36 36 37 37 37 37    #  37 37 37 37 37 37 38 38 38 38 38 38 38 38 38 39 39 39 39 39 39 39 39]    label = 0    # 遍历当前文件夹    for subdir in os.listdir(data):        print('processing ',subdir)        # 构造路径全链路        subpath = os.path.join(data, subdir)        # 如果是否文件夹        if os.path.isdir(subpath):            # 每个文件夹代表一个人,也就是构造人的姓名            names.append(subdir)            # 遍历文件夹中的图片文件            for filename in os.listdir(subpath):                imgpath = os.path.join(subpath, filename)                # 读取图片,并转换为灰度图片                # 灰度图片用于进行训练                # 构造图片和标签关系                img = cv2.imread(imgpath, cv2.IMREAD_COLOR)                gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)                faces = face_casecade.detectMultiScale(gray_img, 1.3, 5)                 for (x, y, w, h) in faces:                    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)                if (len(faces) > 0):                    (x, y, w, h) = faces[0]                    # 只返回图像的正面部分                    images.append(gray_img[y:y + w, x:x + h])                    labels.append(label)                cv2.imshow('img', img)            label += 1    # 将图片转换为易于操作的ndarray形式    images = np.asarray(images)    # 将标签转为numpy格式    labels = np.asarray(labels)    return images, labels, namesdif __name__ == '__main__':    trainimage = 'C:\\Python\\Pycharm\\docxprocess\\picture\\ORL\\'    predictdata='C:\\Python\\Pycharm\\docxprocess\\picture\\predict\\'    face_cascade = cv2.CascadeClassifier('C:\\Python\\Python37\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_alt2.xml')    X, y, names = loadimageface(trainimage)    model = cv2.face.LBPHFaceRecognizer_create()    model.train(X, y)    for filename in os.listdir(predictdata):        imgpath = os.path.join(predictdata, filename)        if os.path.isfile(imgpath):pass        img = cv2.imread(imgpath)        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)        faces = face_cascade.detectMultiScale(gray, 1.3, 5)        for (x, y, w, h) in faces:            cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)            roi_gray = gray[y:y + h, x:x + w]            roi_color = img[y:y + h, x:x + w]            roi_gray = cv2.resize(roi_gray, (92, 112), interpolation=cv2.INTER_LINEAR)            params = model.predict(roi_gray)            print('Label:%s,confidence:%.2f' % (params[0], params[1]))            print('人员姓名:',names[params[0]])            cv2.putText(img, names[params[0]], (x, y - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2)        cv2.imshow('img', img)        cv2.waitKey(0)        cv2.destroyAllWindows() 

识别结果如下,前两张随机挑选的照片置信度在65-69之间,识别输出是准确无误的,但刘德华这张照片就有点无厘头了。

# Label:3,confidence:65.66# 识别照片: s12# Label:23,confidence:68.60# 识别照片: s30# Label:26,confidence:114.96# 识别照片: s33

最后,谢谢关注,谢谢支持!

文章转载自追梦IT人,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论