opencv人脸识别主要有3种算法
1 EigenFace,大题思路是用PCA 对人脸进行降维,在比较距离
2 FisherFace,基于LDA降维
3 LBPH 利用局部二值模式直方图的人脸识别算法
具体步骤:
一、人脸的训练,需要将训练图片中人脸扣出->正脸->转化灰度图->直方图均衡化->训练
二、经过同样步骤处理图片,然后预测
下面具体演示一下,用LBPH算法,训练我准备好的图片,然后打开我的摄像头,识别摄像头前的人脸
训练集:
每个文件里有几张训练图片:
获取训练图片函数:
def get_images_and_labels(path):
image_paths = [os.path.join(path, f) for f in os.listdir(path)]
predictor_path = "C:\\Users\\51530\\Desktop\\openFace\\shape_predictor_68_face_landmarks.dat"
detector = dlib.get_frontal_face_detector()
# 使用官方提供的模型构建特征提取器
predictor = dlib.shape_predictor(predictor_path)
images = []
labels = []
fileNum = 0
i=0
for image_path in image_paths:
fileNum = fileNum + 1
for (root, dirs, files) in os.walk(image_path):
print(root)
for f in files:
bgr_image = cv2.imread(image_path+'/'+f)
faces = dlib.full_object_detections()
rgb_image = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2RGB)
dets = detector(rgb_image, 1)
if len(dets) > 0: # 如果检测到人脸,则将人脸进行标记
for det in dets:
faces.append(predictor(rgb_image, det))
imagechips = dlib.get_face_chips(rgb_image, faces, size=120)
if len(imagechips) > 0:
for image in imagechips:
cv_rgb_image = np.array(image).astype(np.uint8) # 先转换为numpy数组
grap = cv2.cvtColor(cv_rgb_image, cv2.COLOR_BGR2GRAY) # 灰度化
img = cv2.equalizeHist(grap)
# cv2.imshow('img',img)
# key = cv2.waitKey(2000)
indx = i
images.append(img)
labels.append(indx)
print('总共加载文件夹数量为:',fileNum)
i=i+1
return images, labels
因为opencv训练标签只能用数字,所以建了字典使数字与label对应
import os
#把一个文件夹里的文件对应生成字典
def create_of(path):
dirs=os.listdir(path)
i=0
dic = {}
for d in dirs:
updic={i:d}
i=i+1
dic.update(updic)
return dic
主方法:
import cv2
import numpy as np
from tool.createDic import create_of
from tool.loadPhoto import get_images_and_labels
import dlib
#建立字典
dic=create_of('C:\\Users\\51530\\Desktop\\image')
#-----------dlib部分
predictor_path = "C:\\Users\\51530\\Desktop\\openFace\\shape_predictor_68_face_landmarks.dat"
#与人脸检测相同,使用dlib自带的frontal_face_detector作为人脸检测器
detector = dlib.get_frontal_face_detector()
#使用官方提供的模型构建特征提取器
predictor = dlib.shape_predictor(predictor_path)
#加载训练图片
images, labels=get_images_and_labels('C:\\Users\\51530\\Desktop\\image')
print(np.array(labels))
cap=cv2.VideoCapture(0)#打开1号摄像头
color = (134,126,255)#设置人脸框的颜色
fenlei=cv2.face.LBPHFaceRecognizer_create()
fenlei.train(images,np.array(labels))
success, frame = cap.read()
font = cv2.FONT_HERSHEY_SIMPLEX
divisor = 0
while success:
success, frame = cap.read() # 读取一桢图像,这个图像用来获取它的大小
#转rgb方便后面dlib操作
rgb_img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# minSize=int((w/divisor, h/divisor))
dets = detector(rgb_img, 1)
faces = dlib.full_object_detections()
left=0
top=0
right=0
bottom=0
#对于每找到的人脸作以下操作
if len(dets)>0:
for det in dets:
faces.append(predictor(rgb_img, det))
left = det.left()
top = det.top()
right = det.right()
bottom = det.bottom()
cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 1)
shape = predictor(rgb_img,det)
for index, pt in enumerate(shape.parts()):
# print('Part {}: {}'.format(index, pt))
pt_pos = (pt.x, pt.y)
cv2.circle(frame, pt_pos, 2, (255, 0, 0), 1)
images = dlib.get_face_chips(rgb_img, faces, size=120)
if len(images)>0:
for image in images:
cv_rgb_image = np.array(image).astype(np.uint8) # 先转换为numpy数组
grap = cv2.cvtColor(cv_rgb_image, cv2.COLOR_BGR2GRAY)#灰度化
cv2.equalizeHist(grap,grap)
print(cv_rgb_image.shape)
res, q = fenlei.predict(grap)#预测
try:
resname=dic[int(res)]
except KeyError:
resname='unknown'
cv2.putText(frame, resname, (right, bottom), font, 0.5, (255, 255, 255), 2)
cv2.imshow("test", frame)#显示图像
key=cv2.waitKey(1)
c = chr(key & 255)
if c in ['q', 'Q', chr(27)]:
break
cv2.destroyAllWindows
运行后效果图: