opencv人脸识别 (二):人脸识别 (基于 LBPH)
人脸检测是 OpenCV 的一个很不错的功能, 它是人脸识别的基础。 什么是人脸识别呢?
其实就是一个程序能识别给定图像或视频中的人脸。 实现这一目标的方法之一是用一系列分好类的图像来“训练” 程序, 并基于这些图像来进行识别。这就是 OpenCV 及其人脸识别模块进行人脸识别的过程。
人脸识别模块的另外一个重要特征是: 每个识别都具有转置信(confidence) 评分, 因此可在实际应用中通过对其设置阈值来进行筛选。
人脸识别所需要的人脸可以通过两种方式来得到: 自己获得图像或从人脸数据库免费获得可用的人脸图像
训练数据
pycharm可以打开.cpm图像
import os import cv2 import numpy as np import sys from PIL import Image detector = cv2.CascadeClassifier("D:\\Anaconda3\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml") def getImagesAndLabels(path): imagePaths = [os.path.join(path,f) for f in os.listdir(path)] faceSamples=[] ids = [] for imagePath in imagePaths: #打开图片 PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale #将图像转换为数组 img_numpy = np.array(PIL_img,'uint8') #获取每张图片的id #print(os.path.split(imagePath)) id = int(os.path.split(imagePath)[-1].split(".")[0]) faces = detector.detectMultiScale(img_numpy) for x,y,w,h in faces: faceSamples.append(img_numpy[y:y+h,x:x+w]) ids.append(id) return faceSamples,ids if __name__ == '__main__': #图片路径 path='data/jm/' #获取图像数组和id标签数组 faces, ids = getImagesAndLabels(path) #获取训练对象 recognizer = cv2.face.LBPHFaceRecognizer_create() recognizer.train(faces, np.array(ids)) #要将ids从列表转换为数组 # Save the model into trainer/trainer.yml recognizer.write('trainer/trainer.yml')
基于 LBPH 的人脸识别
LBPH(Local Binary Pattern Histogram) 将检测到的人脸分为小单元, 并将其与模型中的对应单元进行比较, 对每个区域的匹配值产生一个直方图。 由于这种方法的灵活性, LBPH是唯一允许模型样本人脸和检测到的人脸在形状、 大小上可以不同的人脸识别算法。
调整后的区域中调用 predict()函数, 该函数返回两个元素的数组: 第一个元素是所识别个体的标签, 第二个是置信度评分。 所有的算法都有一个置信度评分阈值, 置信度评分用来衡量所识别人脸与原模型的差距, 0 表示完全匹配。 可能有时不想保留所有的识别结果, 则需要进一步处理, 因此可用自己的算法来估算识别的置信度评分。
LBPH 一个好的识别参考值要低于 50 , 任何高于 80 的参考值都会被认为是低的置信度评分。
之前训练的数据都在trainer.yml里,
这次读取一个图片,程序会输入和训练数据的哪个最像,然后置信度评分是多少
import cv2 import numpy as np import os recognizer = cv2.face.LBPHFaceRecognizer_create() #加载数据 recognizer.read('trainer/trainer.yml') faceCascade = cv2.CascadeClassifier("D:\\Anaconda3\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml") font = cv2.FONT_HERSHEY_SIMPLEX id = 0 img=cv2.imread('1.pgm') #识别的图片 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale(gray) for(x,y,w,h) in faces: cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2) id, confidence = recognizer.predict(gray[y:y+h,x:x+w]) print('标签id:',id,'置信评分:',confidence) cv2.imshow('camera',img) cv2.waitKey(0) cv2.destroyAllWindows()
6.pgm
这是训练用的数据集data/jm里的2.pgm,可见被识别的6.pgm和2.pgm还是属于同一个人的,只不过置信评分有些高了
1.gpm
data/jm里面就有这张照片,所以识别出来一摸一样,置信0.0