这可能是最无聊的部分,对吧?别担心,接下来会有有趣的事情发生。现在是时候训练我们自己的人脸识别器了,这样一旦训练它就能识别它所训练的人的新面孔了。读吗?那我们来训练我们的人脸识别器。
训练人脸识别器
我们知道,OpenCV配备了三个人脸识别器。
1、EigenFaces人脸识别器识别器 - cv2.face.createEigenFaceRecognizer()
2、FisherFaces人脸识别器识别器 - cv2.face.createFisherFaceRecognizer()
3、局部二值模式直方图(LBPH)人脸识别器 - cv2.face.createLBPHFaceRecognizer()
我将使用LBPH人脸识别器,但您可以使用您选择的任何人脸识别器。 无论您使用哪个OpenCV的脸部识别器,其代码都将保持不变。 您只需更改一行,即下面给出的面部识别器初始化行。
#创建我们的LBPH人脸识别器 face_recognizer = cv2.face.createLBPHFaceRecognizer() #或者使用EigenFaceRecognizer替换上面的行 #face_recognizer = cv2.face.createEigenFaceRecognizer() #或者使用FisherFaceRecognizer替换上面的行 #face_recognizer = cv2.face.createFisherFaceRecognizer()
现在我们已经初始化了我们的人脸识别器,也准备了我们的训练数据,现在是时候训练人脸识别器了。我们将通过调用人脸识别器的序列(面向量,标签向量)方法来实现这一点。
#训练我们的面部识别器 face_recognizer.train(faces, np.array(labels))
你有没有注意到,不是直接将标签矢量直接传递给人脸识别器,而是先把它转换成numpy数组?这是因为OpenCV希望标签向量是一个numpy数组。
仍然不满意? 想看到一些行动? 下一步是真正的行动,我保证!
预测
现在是我最喜欢的部分,预测部分。 这是我们真正了解我们的算法是否确实能够识别受过训练的对象脸部的地方。 我们将拍摄两张我们的景点的测试图像,从他们每个人身上检测脸部,然后将这些脸部传递给我们训练有素的脸部识别器,看看它们是否识别它们。
下面是一些实用功能,我们将用它来绘制围绕脸部的边界框(矩形)并将边界名称放在边界框附近。
#函数在图像上绘制矩形 #根据给定的(x,y)坐标和 #给定的宽度和高度 def draw_rectangle(img, rect): (x, y, w, h) = rect cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) #函数在从图像开始绘制文本 #通过(x,y)坐标。 def draw_text(img, text, x, y): cv2.putText(img, text, (x, y), cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 255, 0), 2)
第一个函数draw_rectangle根据传入的矩形坐标在图像上绘制一个矩形。 它使用OpenCV的内置函数cv2.rectangle(img,topLeftPoint,bottomRightPoint,rgbColor,lineWidth)绘制矩形。 我们将使用它在测试图像中检测到的脸部周围画一个矩形。
第二个函数draw_text使用OpenCV的内置函数cv2.putText(img,text,startPoint,font,fontSize,rgbColor,lineWidth)在图像上绘制文本。
既然我们有绘图功能,我们只需要调用人脸识别器预测(人脸)方法来测试我们的测试图像上的人脸识别器。 以下功能为我们做了预测。
#this function recognizes the person in image passed #and draws a rectangle around detected face with name of the #学科 def predict(test_img): #制作图像的副本,因为我们不想更改原始图像 img = test_img.copy() #从图像中检测脸部 face, rect = detect_face(img) #使用我们的脸部识别器预测图像 label= face_recognizer.predict(face) #获取由人脸识别器返回的相应标签的名称 label_text = subjects[label] #在检测到的脸部周围画一个矩形 draw_rectangle(img, rect) #画预计人的名字 draw_text(img, label_text, rect[0], rect[1]-5) return img