实则一个分类任务(得到相应的输出)
收集数据集,即收集人脸图像。通过opencv自带人脸检测器检测人脸,然后将人脸保存为数据集。
实现过程:
import cv2
face_detector = cv2.CascadeClassifier('检测器位置(路径)') #创建人脸检测器
face_id = input('\n enter user id : ') # 数据集人脸label
count = 0
cap = cv2.VideoCapture(0 or 视频路径)
while Ture:
sucess,img = cap.read() # 布尔值,单帧图像
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #灰度图可以减少人脸检测的时间
faces = face_detector.detectMultiScale(gray,1.1,4) #检测器检测
for (x,y,w,h) in faces :
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0)) #人脸画框
cv2.imwrite("在同一级目录下创建一个facedata文件夹,在这输入路径",gray[y:y+h,x:x+w])
count +=1
cv2.imshow('image',img)
if count %100 == 0:
prnt('have been collected : %d'%count)
if cv2.waitKey(1) == 27: #esc键值=27
break
elif count >= 1000:
break
cap.release()
cv2.destroyAllWindows()
使用opencv自带的训练器,在那训练前,再对数据集进行人脸筛选一次。
import numpy as np
import os
import cv2
path = 'facedata' # 人脸数据路径
recognizer = cv2.face.LBPHFaceRecognizer_create() # 创建人脸识别器 (模型)
detector = cv2.CascadeClassifier("D:\\untitled2\\venv\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml")
def getImagesAndLabels(path):
imagePaths = [os.path.join(path, f) for f in os.listdir(path)] # os.path.join()拼接单张图片的路径 组成列表
faceSamples = []
ids = []
for imagePath in imagePaths: # 遍历列表,得到路径
img_numpy =cv2.imread(imagePath,-1) #img = Image.open(imagePath).convert('L') img_numpy = np.array(img,'uint8') # image转换为array
id = int(os.path.split(imagePath)[-1].split(".")[1]) # os.path.split() 分开路径与文件名 split()以 . 为分隔符 再索引
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
print('Training faces. It will take a few seconds. Wait ...')
faces, ids = getImagesAndLabels(path)
recognizer.train(faces,np.array(ids)) # 训练函数
recognizer.write(r'face_trainer\trainer.yml') # 保存训练数据
print("{0} faces trained. Exiting Program".format(len(np.unique(ids)))) # np.unique()保留数组中不同的数字
通过predict()函数可以预测出图像的label,cost(成本)。通过成本计算出精度。
import cv2
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('face_trainer/trainer.yml') # 读取训练模型(数据)
cascadePath = "D:\\untitled2\\venv\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath) # 创建检测器
font = cv2.FONT_HERSHEY_SIMPLEX # 正常尺寸的一种字体
idnum = 0
names = ['zhangbicheng','xiaoxinwang']
cam = cv2.VideoCapture(0)
cam.set( 3 ,640) # 设置高宽
cam.set( 4, 480)
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 = faceCascade.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 , confidence = recognizer.predict(gray[y:y+h, x:x+w]) # 预测函数 返回预测标记 cost
if confidence < 100: # cost
idnum = names[idnum]
confidence = "{0}%".format(round(100 - confidence)) # 精度 四舍五入
else:
idnum = "unknown"
confidence = "{0}%".format(round(100 - confidence))
cv2.putText(img, str(idnum), (x+5, y-5), font, 1, (0, 0, 255), 1)
cv2.putText(img, str(confidence), (x+5, y+h-5), font, 1, (0, 0, 0), 1) # 图片,添加的文字,坐标,字体,字体大小,颜色,字体粗细
cv2.imshow("camera",img)
if cv2.waitKey(1) == 27:
break
cam.release()
cv2.destroyAllWindows()