人脸识别别环境:pycharm 和opencv-contrib-python
大体思路:采集人脸数据---->训练模型---->实现人脸识别
第一步:采集人脸数据
#导入模块
import cv2
#摄像头
cap=cv2.VideoCapture(0)
falg = 1
num = 1
while(cap.isOpened()):#检测是否在开启状态
ret_flag,Vshow = cap.read()#得到每帧图像
cv2.imshow("Capture_Test",Vshow)#显示图像
k = cv2.waitKey(1) & 0xFF#按键判断
if k == ord('s'):#保存
cv2.imwrite("C:/Users/Lenovo/Desktop/facerecog/opencv/data/tang/"+str(num)+".tang"+".jpg",Vshow)
print("success to save"+str(num)+".jpg")
print("-------------------")
num += 1
elif k == ord(' '):#退出
break
#释放摄像头
cap.release()
#释放内存
cv2.destroyAllWindows()
第二步:训练数据
import os
import cv2
import sys
from PIL import Image
import numpy as np
def getImageAndLabels(path):
facesSamples=[]
ids=[]
imagePaths=[os.path.join(path,f) for f in os.listdir(path)]
#检测人脸
face_detector = cv2.CascadeClassifier('D:/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml')
#打印数组imagePaths
print('数据排列:',imagePaths)
#遍历列表中的图片
for imagePath in imagePaths:
#打开图片,黑白化
PIL_img=Image.open(imagePath).convert('L')
#将图像转换为数组,以黑白深浅
# PIL_img = cv2.resize(PIL_img, dsize=(400, 400))
img_numpy=np.array(PIL_img,'uint8')
#获取图片人脸特征
faces = face_detector.detectMultiScale(img_numpy)
#获取每张图片的id和姓名
id = int(os.path.split(imagePath)[1].split('.')[0])
#预防无面容照片
for x,y,w,h in faces:
ids.append(id)
facesSamples.append(img_numpy[y:y+h,x:x+w])
#打印脸部特征和id
#print('fs:', facesSamples)
print('id:', id)
#print('fs:', facesSamples[id])
print('fs:', facesSamples)
#print('脸部例子:',facesSamples[0])
#print('身份信息:',ids[0])
return facesSamples,ids
if __name__ == '__main__':
#图片路径
path='./data/jm/'
#获取图像数组和id标签数组和姓名
faces,ids=getImageAndLabels(path)
#获取训练对象
recognizer=cv2.face.LBPHFaceRecognizer_create()
#recognizer.train(faces,names)#np.array(ids)
recognizer.train(faces,np.array(ids))
#保存文件
recognizer.write('trainer/trainer.yml')
#save_to_file('names.txt',names)
第三步:实时识别
# 人脸识别
# coding=utf-8
import cv2
import numpy
from PIL import Image, ImageDraw, ImageFont
# 语音说话
#import pyttsx3
# 解决cv2.putText绘制中文乱码
def cv2ImgAddText(img2, text, left, top, textColor=(0, 0, 255), textSize=20):
if isinstance(img2, numpy.ndarray): # 判断是否OpenCV图片类型
img2 = Image.fromarray(cv2.cvtColor(img2, cv2.COLOR_BGR2RGB))
# 创建一个可以在给定图像上绘图的对象
draw = ImageDraw.Draw(img2)
# 字体的格式
fontStyle = ImageFont.truetype(r"C:\WINDOWS\FONTS\MSYH.TTC", textSize, encoding="utf-8")
# 绘制文本
draw.text((left, top), text, textColor, font=fontStyle)
# 转换回OpenCV格式
return cv2.cvtColor(numpy.asarray(img2), cv2.COLOR_RGB2BGR)
# 准备识别方法
recognizer_sjs = cv2.face.LBPHFaceRecognizer_create()
recognizer_jhs = cv2.face.LBPHFaceRecognizer_create()
# 引用之前的模型
recognizer_sjs.read('C:/Users/Lenovo/Desktop/facerecog/opencv/trainer/trainwang.yml')
recognizer_jhs.read('C:/Users/Lenovo/Desktop/facerecog/opencv/trainer/traintang.yml')
# 调用人脸分类器
cascade_path = r'D:\Python3\Lib\site-packages\cv2\data\haarcascade_frontalface_alt2.xml'
face_cascade = cv2.CascadeClassifier(cascade_path)
# 加载一个字体,以便标注
font = cv2.FONT_HERSHEY_SIMPLEX
# 设置ID与标注的name
idum_sjs = 0
idum_jhs = 1
names = ['王某某', '唐某某']
# 调用摄像头
cam = cv2.VideoCapture(0)
minW = 0.1 * cam.get(3)
minH = 0.1 * cam.get(4)
while True:
ret, img = cam.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 识别人脸
faces = face_cascade.detectMultiScale(
gray,
scaleFactor=1.2,
minNeighbors=5,
minSize=(int(minW), int(minH))
)
# 进行校验
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
idnum_sjs, confidence_sjs = recognizer_sjs.predict(gray[y:y + h, x:x + w])
idnum_jhs, confidence_jhs = recognizer_jhs.predict(gray[y:y + h, x:x + w])
# 计算出一个检验结果
if confidence_sjs < 50:
name= names[idum_sjs]
# 注上姓名
img = cv2ImgAddText(img, name, x + 5, y - 30)
#cv2.putText(img, str(idnum_sjs), (x + 5, y - 5), font, 1, (0, 0, 255), 1)
elif confidence_jhs < 50:
name1= names[idum_jhs]
# 注上姓名
img = cv2ImgAddText(img, name1, x + 5, y - 30)
#cv2.putText(img, str(idnum_sjs), (x + 5, y - 5), font, 1, (0, 0, 255), 1)
else:
idnum = 'unknown'
# 解决cv2.putText绘制中文乱码
#
# cv2.putText(img, name, (x + 5, y - 5), font, 1, (0, 0, 255), 1) 无法显示中文
# cv2.putText(img, str(confidence.encode('utf-8')), (x+5, y+h-5), font, 1, (0, 0, 0), 1)
# 解决cv2.putText绘制中文乱码
# cv2.putText(img, name, (x + 5, y - 5), font, 1, (0, 0, 255), 1) 无法显示中文
# cv2.putText(img, str(confidence.encode('utf-8')), (x+5, y+h-5), font, 1, (0, 0, 0), 1)
# 展示结果
cv2.imshow('camera', img)
k = cv2.waitKey(20)
if k == 27:
break
elif ord('q') == cv2.waitKey(1): # 按下q退出
break
# 释放资源
cam.release()
cv2.destroyAllWindows()
中文字体其他显示方法:
中文字体下载地址:http://www.font5.com.cn/fontlist/fontlist_1_1.html
注意:拍取照片时尽量选取光照较好,背景颜色同一的地方,否则训练数据可能带来不必要干扰因素,经本人多次测试证实有效,如遇到多人不能分辨时,建议采取此方法;
另附:
1.刚学Python,遇到No Python Interpreter configured for the project,怎么解决? 2.pip install XXX总是报错,例如:Exception: Traceback (most recent call last):这种错误怎么办? 参考:
1.python实现多人脸识别 2.Python3和opencv的人脸识别并显示对应中文姓名完整版(含数据收集,模型训练)