1.先上图:(蓝奏云:https://zyjblogs.lanzous.com/idvX3e2jq2d)
2.首先开启摄像头采集人脸数据
import cv2
detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
sampleNum = 0
Id = input('输入人脸ID: ')
print('\n 正在初始化人脸采集,请注视摄像头 ...')
cam = cv2.VideoCapture(0)
minW = 0.1 * cam.get(3)
minH = 0.1 * cam.get(4)
while True:
#读取一帧
ret, img = cam.read()
#将彩色图转为灰度图
if ret:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = detector.detectMultiScale(
gray,
scaleFactor=1.05,
minNeighbors=3,
minSize=(int(minW), int(minH))
)
for (x, y, w, h) in faces:
#opencv绘制正方形需要左上角坐标和右下角坐标,人脸检测检测出得是左上角坐标和宽高
cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
#增加样本计数
sampleNum = sampleNum + 1
# 将样本拷贝到指定文件夹
#注意:opencv的宽高和实际是相反的
cv2.imwrite("dataSet/User." + str(Id) + '.' + str(sampleNum) + ".jpg", gray[y:y + h, x:x + w]) #
cv2.imshow('frame', img)
if cv2.waitKey(2) & 0xFF == ord('q'):
print(sampleNum)
break
elif sampleNum >= 200:
print(sampleNum)
break
cam.release()
cv2.destroyAllWindows()
#暗光环境拍摄一张照片,opencv进行降噪(可选)
#采集至少三个样本进行训练
#数据分析常见面试题 https://github.com/yoghurtjia/-python-BAT-(重点)
2.训练采集到的人脸数据
import cv2
import os
import numpy as np
from PIL import Image
detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
recognizer = cv2.face.LBPHFaceRecognizer_create()
def get_images_and_labels(path):
image_paths = [os.path.join(path, f) for f in os.listdir(path)]
face_samples = []
ids = []
for image_path in image_paths:
#打开文件并转为灰度图
image = Image.open(image_path).convert('L')
image_np = np.array(image, 'uint8')
if os.path.split(image_path)[-1].split(".")[-1] != 'jpg':
continue
image_id = int(os.path.split(image_path)[-1].split(".")[1])
faces = detector.detectMultiScale(image_np)
for (x, y, w, h) in faces:
#生成训练数据
face_samples.append(image_np[y:y + h, x:x + w])
#标记数据'User.1.2.jpg' 1就是我们的标记,相当于我们之前的target
ids.append(image_id)
return face_samples, ids
faces, Ids = get_images_and_labels('dataSet')
print('正在训练. 请等待一会儿 ...')
recognizer.train(faces, np.array(Ids))
recognizer.save('trainner/trainner.yml')
print('训练完成')
3.人脸识别
import cv2
import numpy as np
#加载识别器
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trainner/trainner.yml')
#加载分类器
cascade_path = "haarcascade_frontalface_default.xml"
face_cascade = cv2.CascadeClassifier(cascade_path)
#开摄像头
cam = cv2.VideoCapture(0)
minW = 0.1*cam.get(3)
minH = 0.1*cam.get(4)
#加载一个字体
font = cv2.FONT_HERSHEY_SIMPLEX
#名字对应1,2,3
names = ['zhansan','lishi','wangwu']
agelist=[21,21,21,21,21,21,22]
while True:
#人脸识别
ret, img = cam.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(
gray,
scaleFactor=1.3,
minNeighbors=5,
minSize=(int(minW), int(minH))
)
#加方框和名字
for (x, y, w, h) in faces:
cv2.rectangle(img, (x , y ), (x + w , y + h ), (225, 0, 0), 2)
img_id, confidence = recognizer.predict(gray[y:y + h, x:x + w])
print(img_id,confidence)
if confidence < 80:
img_id = names[img_id-1]
confidence = "{0}%".format(round(100 - confidence))
else:
img_id = "Unknown"
confidence = "{0}%".format(round(100 - confidence))
cv2.putText(img, str(img_id), (x, y + h), font, 0.55, (0, 255, 0), 1)
cv2.putText(img, "18", (x , y + 500), font, 1, (0, 255, 0), 1)
cv2.putText(img, "18", (x , y +h + 150), font, 1, (0, 255, 0), 1)
cv2.putText(img, str(confidence), (x + 5, y - 5), font, 1, (0, 255, 0), 1)
cv2.imshow('im', img)
if cv2.waitKey(5) & 0xFF == ord('q'):
break
cam.release()
cv2.destroyAllWindows()