2019年10月17号
作者:杨轮飞
将会使用到python中的opencv、dlib、sklearn库。
- 前面遗漏了一些步骤,和一些问题,我们先进行修正
X = np.array(X)
np.save("face255.npy", X)
Y = np.array(Y)
#PCA降维处理
X = pca(X, 150)
np.save("face255.npy", X)
我们先保存出未降维数据,用于之后在视频中要预测的单个数据进行降维
face_model = OneVsRestClassifier(SVC(kernel='rbf', C=1e3, gamma='scale', probability=True))
第二步就是在定义SVM模型时添加参数probability=True,这样可以输出识别概率。
- 前面两个问题修改后我们就开始最后的实验工作了,先导入库
import warnings
warnings.filterwarnings("ignore")
import cv2
import dlib
import numpy
import numpy as np
from sklearn.externals import joblib #加载我们保存好的模型
from sklearn.decomposition import PCA #PCA降维
from sklearn.preprocessing import scale #去中心化
- 然后先放好两个要使用到的函数,一个pca,一个归一化
#归一化处理
def MaxMinNormalization(x):
xmin, xmax = np.min(x), np.max(x)
x = (x - xmin) / (np.max(x) - xmin)
return x
#使用库PCA
def pca(data, n):
pca = PCA(n_components=n)
pca.fit(data)
return pca.transform(data)
- 在定义全局变量,提前定义好一些变量:dlib人脸检测函数,读取模型,定义好一个人名对应的字典,导入数据集,定义一个字体
predictor_path = "F:\qq\shape_predictor_68_face_landmarks.dat"
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
clf = joblib.load("face_train_model.m")
people_name = {'cjy':'程嘉怡', 'szq':'单志祺', 'hrx':'黄日兴', 'lwj':'赖文进',
'txj':'唐小俊', 'xwm':'许微', 'wzy':'王曾宇', 'ylf':'杨轮飞'}
formerdata = np.load("face255.npy")
font = cv2.FONT_HERSHEY_SIMPLEX
- dlib检测人脸,并且将人脸区域进行归一化和去中心化处理,再覆盖到原数据集的第一个数据,进行pca降维后再单独提出来,使用模型进行预测,并且输出预测概率
def dlib_find_face(img, temp_gray, dets):
for k, d in enumerate(dets):
minx, miny, maxx, maxy = 640, 640, 0, 0
shape = predictor(img, d)
#(x, y, w, h) = face_utils.rect_to_bb(rect)
landmark = numpy.matrix([[p.x, p.y] for p in shape.parts()])
for idx, point in enumerate(landmark):
x, y = (point[0, 0], point[0, 1])
cv2.putText(img, "*", (x, y), font,0.3,(0, 255, 0))
if x > maxx: maxx = x;
if x < minx: minx = x;
if y > maxy: maxy = y;
if y < miny: miny = y;
cv2.rectangle(img, (minx-10, miny-10), (maxx+10, maxy+10), (0, 255, 0), 2)
face = temp_gray[miny:maxy, minx:maxx]
face = MaxMinNormalization(cv2.resize(face, (64, 64)))
formerdata[0] = scale(np.array(face, np.float32).flatten().astype('float32'))
facedata = pca(formerdata, 150)[:1]
result = clf.predict(facedata)
proba = np.max(clf.predict_proba(facedata)[0])
cv2.putText(img, str(result)+str(proba*100)[:4]+"%", (minx-10, miny-20), font, 1.2, (255, 0, 0), 2)
return img
- 然后开始进行实验了, 打开摄像头,二值化,dlib检测,然后调用自己的dlib_find_face函数进行处理
if __name__=="__main__":
cap = cv2.VideoCapture(0)
while True:
sucess, img = cap.read()
temp = img.copy()
temp_gray = cv2.cvtColor(temp, cv2.COLOR_RGB2GRAY)
dets = detector(temp_gray, 1)
k = cv2.waitKey(30)
if k == 27:
break
if len(dets) >= 1:
temp = dlib_find_face(temp, temp_gray,dets)
if k == 32: cv2.waitKey();
cv2.imshow("result", temp)
- 最后来看一下我们的实验结果
可以看到,虽然识别的置信度不高,但总算能识别出来,而且可以同时识别多个人脸哦,总的来说,这些代码是入门级的,不是很难~