1、加载人脸数据
# encoding: utf-8
import cv2
import os, sys
# import win32com.client
import numpy as np
def get_vip( path):
# speaker.Speak("您好,欢迎加入VIP大家庭,请输入您的姓名")
print("客户您好,请输入您的姓名:")
name = sys.stdin.readline()
subject_path = os.path.join(path, name)[:-1]
return subject_path, name[:-1]
def generate( name, dirname):
# 创建人脸检测器对象
face_cascade = cv2.CascadeClassifier('D:/Anaconda3/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml')
# eye_cascade = cv2.CascadeClassifier('D:/Anaconda3/Lib/site-packages/cv2/data/haarcascade_eye.xml')
# 带眼镜的时候可以用下面这个
# eye_cascade = cv2.CascadeClassifier('D:/Anaconda3/Lib/site-packages/cv2/data/haarcascade_eye_tree_eyeglasses.xml')
# 创建目录
if not (os.path.isdir(dirname)):
os.makedirs(dirname)
# 打开摄像头进行人脸图像采集w
# speaker.Speak(name+"您好!现在开始采集人脸信息,请正视摄像头")
camera = cv2.VideoCapture(0)
count = 1
while (True):
ret, frame = camera.read() # 读入摄像头图像
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 转为灰度图
faces = face_cascade.detectMultiScale(gray, 1.3, 5, cv2.CASCADE_DO_CANNY_PRUNING, (100, 100), (400, 400)) # 检测人脸部位
for (x, y, w, h) in faces:
img = cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2) # 框出人脸区域
roi = gray[x: x + w, y: y + h]
cv2.putText(img, "getting "+str(count)+"/20"+"...", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
# 重设置图像尺寸200 * 200
f = cv2.resize(roi, (200, 200), interpolation=cv2.INTER_LINEAR)
cv2.imwrite(dirname + '/%s.pgm' % str(count), f)
print(count)
count += 1
cv2.imshow("camera", frame)
if cv2.waitKey(100) & 0xff == ord("q"):
break
# 获取多少张图片就停止
elif count > 20:
break
camera.release()
cv2.destroyAllWindows()
# speaker.Speak("信息采集完毕,感谢您的配合!")
def read_images(path, sz=None):
c = 0
X, y = [], []
for dirname, dirnames, filenames in os.walk(path):
for subdirname in filenames:
subject_path = os.path.join(dirname, subdirname)
# print(subject_path)
try:
if not subject_path.endswith('.pgm'): # 读入灰度图
continue
filepath = os.path.join(path, subject_path)
im = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)
if sz is not None: # 重塑图像大小
im = cv2.resize(im, (200, 200))
X.append(np.asarray(im, dtype=np.uint8)) # 图片转为数组
y.append(c) # 记录图片的编号
except:
print("Unexpected error:", sys.exc_info()[0])
c = c + 1
return [X, y]
def train_model(path):
# 训练脸部识别匹配模型
print("信息录入中...")
[X, y] = read_images(path) # 读入图片数组和编号
y = np.asarray(y, dtype=np.int32)
model = cv2.face.EigenFaceRecognizer_create() # 创建脸部识别的模型
model.train(np.asarray(X), np.asarray(y))
model.save("./face_model.xml")
print("信息录入完毕!")
if __name__ == "__main__":
path = "E:/study/data/face_data"
# speaker = win32com.client.Dispatch("SAPI.SpVoice")
# 创建VIP客户文件,返回路径
subject_path, name = get_vip( path)
# 采集vip客户人脸图像
generate(name, subject_path)
# 读入采集的图像,保存训练模型
train_model(path)
2、识别人脸判断客户类型
# encoding: utf-8
import cv2
import win32com.client
import time
def face_rec(img_path):
model = cv2.face.EigenFaceRecognizer_create() # 创建脸部识别的模型
start = time.time()
model.read("./face_model.xml")
end = time.time()
print("循环运行时间:%.2f秒" % (end - start))
camera = cv2.VideoCapture(0)
face_cascade = cv2.CascadeClassifier(
r'D:/Anaconda3/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml')
total_frame = 0
total_Confidence = 0
while (True):
read, img = camera.read()
faces = face_cascade.detectMultiScale(img, 1.3, 5, cv2.CASCADE_DO_CANNY_PRUNING, (100, 100), (400, 400))
for (x, y, w, h) in faces:
img = cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), 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)
params = model.predict(roi) # 预测结果
total_frame += 1
total_Confidence += params[1]
print("Label: %s, Confidence: %s" % (params[0], params[1])) # 输出预测结果
print(total_Confidence, total_frame)
if params[1] <= 6500:
cv2.putText(img, "VIP", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) # 在屏幕显示匹配的帧数
elif params[1] >= 8500:
cv2.putText(img, "Client", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
except:
continue
cv2.imshow("camera", img) # 显示摄像头捕捉图片
if cv2.waitKey(100) & 0xff == ord('q'):
break
elif total_frame > 20: # 得到多少帧图片就停止采集
break
camera.release()
cv2.destroyAllWindows()
print("Average_Confidence: %.2f" % (total_Confidence / total_frame)) # 输出预测结果
speaker = win32com.client.Dispatch("SAPI.SpVoice")
if (total_Confidence / total_frame) <= 6500:
speaker.Speak("vip客户欢迎您!我是智能机器人,您可以叫我小呆。请问有什么可以为您服务?")
elif (total_Confidence / total_frame) > 8500:
speaker.Speak("欢迎您!我是智能机器人,您可以叫我小呆。请问有什么可以为您服务?")
else:
speaker.Speak("人脸对比失败!请重新检测!")
if __name__ == "__main__":
face_rec(r'E:/study/data/face_data') # 人脸数据路径img_path