在win10环境下安装face_recognition,了解face_recognition中api的使用,如人脸截取、人脸矫正、人脸特征提取、人脸关键点提取、人脸mask获取、人脸特征比对等功能。最后构建自己的人脸数据库,使用knn实现人脸识别软件。

1、安装face_recognition

face_recognition库依赖于dlib库,安装dlib库则需要安装cmake,故此安装命令分别为:

pip3 install cmake

特别说明

在安装cmake后,可能会由于python环境路径没有添加到环境变量中,故此需要将程序输出的路径添加到系统环境变量path中

安装好cmake后即可安装dlib和face_recognition

pip3 install dlib
pip3 install face_recognition

2、api使用

2.1、获取图像中人脸的位置

关键函数:face_recognition.face_locations(img)
传入img图像(whc格式的np数组),返回图像中多个人脸的坐标,坐标格式为y0, x1, y1, x0

from skimage import io
import face_recognition
img=io.imread('D:\深度学习\人脸识别模型\database\zhou1-rui4-fa1.jpg')
face_locations = face_recognition.face_locations(img)
print(face_locations)

输出为

[(81, 373, 236, 218)]

封装为函数测试

import os
import face_recognition
from skimage import io,transform
from PIL import Image, ImageDraw,ImageFont
import matplotlib.pyplot as plt
import matplotlib.patches as patches
##----------------------------
#1、定位图像中的人脸
def dect_crop_face(image):  '''  在一张包含人脸的图片中圈出来人脸  '''  fig,ax = plt.subplots(1,figsize=(8,12))ax.imshow(image)face_locations = face_recognition.face_locations(image)  heads=[]for one in face_locations:     y0, x1, y1, x0=one  rect = patches.Rectangle((x0,y0),x1-x0,y1-y0,linewidth=2,edgecolor='r',facecolor='none')ax.add_patch(rect)x1, y1 =x1+25,y1+25cropped = image[y0:y1,x0:x1]if True:fig,ax2 = plt.subplots(1)#plt.title('dect_face crop')ax2.imshow(cropped)heads.append(cropped)#plt.figure(figsize=(8,12))plt.show()return face_locations,heads
face_locations,heads=dect_crop_face(img)

测试效果为

将识别出的多个人脸保存为图像

将识别出的多个人脸裁剪出来,并缩放到指定大小(200, 200),然后保存为图像

#2、裁剪出识别到的人脸
#扩大裁剪出人脸的范围
def scale_rect(y0, x1, y1, x0,width=None,height=None,rate=0):if rate>0:sx,sy=x1-x0,y1-y0#x0=0 if int(x0-sx*rate)<0 else int(x0-sx*rate)#y0=0 if int(y0-sy*rate)<0 else int(y0-sy*rate)x1=width if int(x1+sx*rate)>width else int(x1+sx*rate)y1=height if int(y1+sy*rate)>height else int(y1+sy*rate)return y0, x1, y1, x0
def crop_face(image,face_locations=None,show=None):  '''  图片中人脸截图保存  '''  if not face_locations:face_locations = face_recognition.face_locations(image)  #(top, right, bottom, left)  head=[]for i in range(len(face_locations)):  y0, x1, y1, x0 = face_locations[i]  y0, x1, y1, x0 =scale_rect(y0, x1, y1, x0,width=image.shape[1],height=image.shape[0])cropped = image[y0:y1,x0:x1] # (left, upper, right, lower)  左上角  右下角  head.append(cropped)cropped=transform.resize(cropped, (200, 200))if show:plt.figure(figsize=(7,7))#plt.title('face crop')plt.imshow(cropped)plt.show()io.imsave('face_tmp.png',cropped)return head

2.2 提取人脸特征进行比对

提取人脸特征,具体流程为:先定位人脸,然后编码
通过face_encoding函数可以将图像中的多个人脸编码为多个128维的向量

#3、将图片中的每张人脸编码成一个128维长度的向量
def face_encoding(image):face_locations = face_recognition.face_locations(image)  #(top, right, bottom, left)   face_encodings = face_recognition.face_encodings(image, face_locations)  #将单个人脸数据转化为一个128维的向量  return face_encodings

人脸比对,具体思路为,根据人脸特征向量的距离判断其相似性,如果距离小于阈值则判断为相似。判断人脸特征距离的函数为face_distance,具体封装使用如下所示

#4、对比两张脸是否一致 image1:要对比的图像,image2:unknow的图像
def face_feature_contrast(known_encoding,unknown_encoding,rate=0.6):  '''  给定两个人脸特征,判断是否是同一个人  '''  #face_recognition.compare_facesrate = face_recognition.face_distance([known_encoding], unknown_encoding)  boolres=True if rate<0.6 else Falsereturn 1-rate,boolres
def face_contrast(image1,image2,rate=0.6):  '''  给定两张图片,判断是否是同一个人  '''  known_encoding = face_encoding(image1)unknown_encoding = face_encoding(image2) return face_feature_contrast(known_encoding,unknown_encoding,rate=0.6)

2.3 脸部关键点识别、标注

通过face_recognition.face_landmarks(image) 函数获取人脸关键点坐标,函数返回一个json数组,数组中元素的keys包含[‘chin’, ‘left_eyebrow’, ‘right_eyebrow’, ‘nose_bridge’, ‘nose_tip’, ‘left_eye’, ‘right_eye’, ‘top_lip’, ‘bottom_lip’]

def face_key_point(image,show=False):  face_landmarks_list = face_recognition.face_landmarks(image)  #print("I found {} face(s) in this photograph.".format(len(face_landmarks_list)))# plt.figure(figsize=(8,12))pil_image = Image.fromarray(image)  draw = ImageDraw.Draw(pil_image)  font = ImageFont.truetype("consola.ttf", 12, encoding="unic")#设置字体for face_landmarks in face_landmarks_list:  point_nums=0for facial_feature in face_landmarks.keys():  #draw.line(face_landmarks[facial_feature], width=1,fill='blue') for point in face_landmarks[facial_feature]:#draw.point(point,fill='blue') x,y=pointr=1draw.ellipse((x-r, y-r, x+r, y+r), 'red', 'red') point_nums+=1#draw.text(point, str(point_nums), 'red',font)print("The {} feature: {}".format(facial_feature, face_landmarks[facial_feature])) if show:plt.imshow(pil_image)plt.show()return pil_image,face_landmarks
pil_image,face_landmarks=face_key_point(img,show=True)

The chin feature: [(218, 140), (222, 159), (225, 176), (231, 194), (239, 209), (254, 223), (272, 234), (293, 241), (315, 242), (334, 235), (347, 221), (357, 203), (364, 185), (366, 166), (364, 148), (362, 130), (360, 113)] The left_eyebrow feature: [(240, 131), (247, 119), (260, 113), (274, 111), (288, 114)] The right_eyebrow feature: [(306, 111), (317, 104), (330, 100), (342, 103), (350, 111)] The nose_bridge feature: [(299, 125), (302, 138), (306, 150), (309, 163)] The nose_tip feature: [(291, 170), (300, 172), (310, 173), (317, 169), (324, 164)] The left_eye feature: [(256, 137), (263, 131), (271, 130), (279, 132), (272, 134), (264, 136)] The right_eye feature: [(316, 125), (323, 120), (331, 119), (339, 121), (333, 123), (324, 124)] The top_lip feature: [(270, 189), (285, 184), (299, 183), (310, 183), (319, 180), (331, 177), (342, 176), (339, 178), (320, 183), (310, 187), (300, 186), (273, 189)] The bottom_lip feature: [(342, 176), (333, 193), (322, 202), (312, 205), (301, 206), (286, 202), (270, 189), (273, 189), (300, 199), (310, 199), (320, 196), (339, 178)] ![在这里插入图片描述](https://img-blog.csdnimg.cn/20470b6b42644b089f2ad81323eb29cc.png)

2.4 获取人脸的mask

使用dlib加载模型,使用模型detector预测出人脸的位置,然后使用predictor 预测出每一个人脸的mask

import face_recognition_models
import dlib
import cv2
import numpy as np
#获取原始人脸特征点
def get_landmarks(image):predictor_68_path = face_recognition_models.pose_predictor_model_location()#detector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor(predictor_68_path)img_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)rects = detector(img_gray, 0)for i in range(len(rects)):landmarks = np.matrix([[p.x, p.y] for p in predictor(image, rects[i]).parts()])return landmarks
#根据特征点提取人脸的掩码
def get_image_hull_mask(image,show=False, ie_polys=None):image_shape=image.shapeimage_landmarks=get_landmarks(image)# get the mask of the imageif image_landmarks.shape[0] != 68:raise Exception('get_image_hull_mask works only with 68 landmarks')int_lmrks = np.array(image_landmarks, dtype=np.int)#hull_mask = np.zeros(image_shape[0:2]+(1,), dtype=np.float32)hull_mask = np.full(image_shape[0:2] + (1,), 0, dtype=np.float32)cv2.fillConvexPoly(hull_mask, cv2.convexHull(np.concatenate((int_lmrks[0:9],int_lmrks[17:18]))), (1,))cv2.fillConvexPoly(hull_mask, cv2.convexHull(np.concatenate((int_lmrks[8:17],int_lmrks[26:27]))), (1,))cv2.fillConvexPoly(hull_mask, cv2.convexHull(np.concatenate((int_lmrks[17:20],int_lmrks[8:9]))), (1,))cv2.fillConvexPoly(hull_mask, cv2.convexHull(np.concatenate((int_lmrks[24:27],int_lmrks[8:9]))), (1,))cv2.fillConvexPoly(hull_mask, cv2.convexHull(np.concatenate((int_lmrks[19:25],int_lmrks[8:9],))), (1,))cv2.fillConvexPoly(hull_mask, cv2.convexHull(np.concatenate((int_lmrks[17:22],int_lmrks[27:28],int_lmrks[31:36],int_lmrks[8:9]))), (1,))cv2.fillConvexPoly(hull_mask, cv2.convexHull(np.concatenate((int_lmrks[22:27],int_lmrks[27:28],int_lmrks[31:36],int_lmrks[8:9]))), (1,))# nosecv2.fillConvexPoly(hull_mask, cv2.convexHull(int_lmrks[27:36]), (1,))image[hull_mask[:,:,0]==0]=0if ie_polys is not None:ie_polys.overlay_mask(hull_mask)plt.imshow(image)return hull_mask
hull_mask=get_image_hull_mask(img,True)


根据提取出的人脸进行化妆

#6、根据第5部分脸部关键点识别进行自动化妆
def face_makeup(image,show=False):  face_landmarks_list = face_recognition.face_landmarks(image)  pil_image = Image.fromarray(image)  for face_landmarks in face_landmarks_list:  demo = ImageDraw.Draw(pil_image, 'RGBA')  demo.polygon(face_landmarks['left_eyebrow'], fill=(68, 54, 39, 128))  demo.polygon(face_landmarks['right_eyebrow'], fill=(68, 54, 39, 128)) demo.line(face_landmarks['left_eyebrow'], fill=(68, 54, 39, 150), width=2)  demo.line(face_landmarks['right_eyebrow'], fill=(68, 54, 39, 150), width=2)demo.polygon(face_landmarks['top_lip'], fill=(150, 0, 0, 128))  demo.polygon(face_landmarks['bottom_lip'], fill=(150, 0, 0, 128))  demo.line(face_landmarks['top_lip'], fill=(150, 0, 0, 64), width=2)  demo.line(face_landmarks['bottom_lip'], fill=(150, 0, 0, 64), width=2)  demo.polygon(face_landmarks['left_eye'], fill=(255, 255, 255, 30))  demo.polygon(face_landmarks['right_eye'], fill=(255, 255, 255, 30))  demo.line(face_landmarks['left_eye'] + [face_landmarks['left_eye'][0]], fill=(0, 0, 0, 110), width=2)  demo.line(face_landmarks['right_eye'] + [face_landmarks['right_eye'][0]], fill=(0, 0, 0, 110), width=2) if show:plt.imshow(image)plt.imshow(pil_image)plt.show()return pil_image
pil_image=face_makeup(img,True)

2.5 裁剪人脸并矫正

由于通过face_recognition.face_locations获取的人脸存在一定倾斜,故使用dlib.get_face_chips获取矫正后的人脸切片。

import dlib
import face_recognition_models
from skimage import io
import matplotlib.pyplot as plt
predictor_5_path = face_recognition_models.pose_predictor_five_point_model_location()#
predictor_68_path = face_recognition_models.pose_predictor_model_location()#
print(predictor_68_path)
detector = dlib.get_frontal_face_detector()
sp = dlib.shape_predictor(predictor_68_path)img=io.imread('D:\深度学习\人脸识别模型\database\zhou1-rui4-fa1.jpg')
plt.imshow(img)
plt.show()
if True:# 检测脸部dets = detector(img, 1)print("Number of faces detected: {}".format(len(dets)))    num_faces = len(dets)# 查找脸部位置faces = dlib.full_object_detections()for detection in dets:faces.append(sp(img, detection))    images = dlib.get_face_chips(img, faces, size=320)for image in images:plt.imshow(image)plt.show()#image = dlib.get_face_chip(img, faces[0], size=320)

3、搭建自己的人脸识别系统

基于face_recognition的人脸特征提取,和knn分类算法,我们可以搭建自己的人脸识别系统。这里采用各类明星的公开数据集进行测试

3.1 数据集准备

目标采集到以下明星的照片,存入database目录,作为标准人脸照片。可以针对每一个明星采集多个样本,那则需要将样本数据存入同一个文件夹下。这里每个样本数据中只允许存在一个人脸。

针对上述人脸基础数据,再次采集第二张图片作为测试数据,数据存入database-test目录。

3.2 构建人脸数据集

遍历传入的路径,判断是单个样本还是多个样本,并提取每一个样本的第一个人脸(如果存在多个人脸,则跳过该样本),将人脸图像存入faces数组,人脸特征存入encodings 数组,人脸标签存入labels 数组(这里采用文件名或者文件夹名作为人脸的标签),将存在多个人脸的数据存入unknown数组。其中train_dir 存储的是人脸的文件名,也就是姓名。


from matplotlib import pyplot as plt
import face_recognition
from sklearn import svm
import os
import numpy as np
def img_encoding(path):faces=[]encodings = []labels = []# Training directorytrain_dir = os.listdir(path)unknown=[]# Loop through each person in the training directoryfor person in train_dir:if os.path.isdir(path + person):#目录文件夹,多样本模式pix = os.listdir(path + person)for person_img in pix:# Get the face encodings for the face in each image fileface = face_recognition.load_image_file(path + person + "/" + person_img)face_bounding_boxes = face_recognition.face_locations(face)#If training image contains exactly one faceif len(face_bounding_boxes) == 1:faces.append(face)face_enc = face_recognition.face_encodings(face)[0]encodings.append(face_enc)labels.append(train_dir.index(person))else:print(person+"/"+person_img+" was skipped and can't be used for training")unknown.append(person + "/" + person_img)else:#文件样本单一模式face = face_recognition.load_image_file(path + person)face_bounding_boxes = face_recognition.face_locations(face)if len(face_bounding_boxes) == 1:faces.append(face)face_enc = face_recognition.face_encodings(face)[0]encodings.append(face_enc)labels.append(train_dir.index(person))else:print(person+"/"+person_img+" was skipped and can't be used for training")unknown.append(person + "/" + person_img)print('data of % had load!'%path)return np.array(train_dir),np.array(faces),np.array(encodings),np.array(labels),np.array(unknown)

3.3 测试人脸数据

先调用img_encoding函数加载出人脸数据(filenams、人脸图像数据、人脸特征编码、人脸标签数据和unknown数据),然后训练knn,最后使用knn来进行人脸分类。

def myimshows(imgs, titles=False, fname="test.jpg", size=6):lens = len(imgs)fig = plt.figure(figsize=(size * lens,size))if titles == False:titles="0123456789"for i in range(1, lens + 1):cols = 100 + lens * 10 + iplt.xticks(())plt.yticks(())plt.subplot(cols)if len(imgs[i - 1].shape) == 2:plt.imshow(imgs[i - 1], cmap='Reds')else:plt.imshow(imgs[i - 1])plt.title(titles[i - 1])plt.xticks(())plt.yticks(())#plt.savefig(fname, bbox_inches='tight')plt.show()# Create and train the SVC classifier
#clf = svm.SVC(gamma='auto')
#clf.fit(encodings,names)
train_dir,faces,encodings,names,unknown=img_encoding('D:\\深度学习\\人脸识别模型\\database\\')
knn_clf = neighbors.KNeighborsClassifier(n_neighbors=int(round(math.sqrt(encodings[0].shape[0]))-2), algorithm='ball_tree', weights='distance')
knn_clf.fit(encodings, names)test_dir='D:\\深度学习\\人脸识别模型\\databse-test\\'
test_list=os.listdir(test_dir)
correct=0
#遍历图片
for file in test_list:test_image = face_recognition.load_image_file(test_dir+file)face_locations = face_recognition.face_locations(test_image)no = len(face_locations)print(file," recognition:=> ")#遍历人脸for i in range(no):test_image_enc = face_recognition.face_encodings(test_image)[i]cls_p = knn_clf.predict([test_image_enc])[0]#以文件名判断是否预测正确if file.split('.')[0]==train_dir[cls_p].split('.')[0]:correct+=1else:print("---recognition:error---")print(train_dir[cls_p])myimshows([test_image,faces[cls_p]],['test image','predict result'])
print(correct/len(test_list))
print("------------end-----------")

上述程序遍历了databse-test下所有的图片文件,并截取出图像中的每一个人脸图片使用knn预测其类型,然后调用myimshows进行绘图展示




win10环境下基于face_recognition搭建自己的人脸识别软件相关推荐

  1. U盘文件夹变exe的win10环境下纯手工解决方法(无需任何软件)

    U盘文件夹变exe的win10环境下纯手工解决方法(无需任何软件) 把U盘插入装有win10系统的电脑 打开U盘目录(这里假设U盘目录是G:) 选中变成exe的文件,删除(放心,这里的exe是一个几k ...

  2. Linux下基于百度智能云平台人脸识别

    Linux下基于百度智能云平台人脸识别 1.百度智能云接口及简介 https://cloud.baidu.com/product/face   接口技术文档: 2.人脸检测属性分析项目示例  硬件平台 ...

  3. Win10环境下基于Hexo的静态博客环境搭建,及其阿里云部署

    引言 1.为什么要搭建自己的个人博客 工作和学习过程中,我们经常遇到一些这样或那样的问题,此时我们可能会在网上找到相应的解决方法.但是过了一段时间之后,当我们再次碰到类似的问题时,早已忘记以前是怎么解 ...

  4. Python 在 Windows 下利用 face_recognition 和 OpenCV 实现人脸识别

    在安装Python的一些库时,遇到的错误及解决办法: # OpenCV的介绍.安装和使用 # OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,OpenCV用C++语言编写, # 支持 ...

  5. win10环境下基于OpenVINO部署yolov5模型

    以在Intel的OpenVINO上部署Yolov5模型为例,加深对模型部署的理解. 1. 训练准备 获取yolov5模型及数据集 git clone git://github.com/ultralyt ...

  6. win10环境下搭建IIS图片服务器

    Win10环境下搭建IIS图片服务器 背景交代:项目开发中在不依赖后端接口的前提下 前端基于mock获取数据,涉及到图片这块,需要完全还原线上场景,多以需要将图片放在服务器上.所以需要在本地利用win ...

  7. Win10环境下如何配置Java JDK系统环境变量【图文教程】

    Windows10正式版发布后,不少用户都在第一时间对系统进行了升级.但是,最近有位刚刚升级的用户反映自己因为工作需求要在Windows10环境下配置Java JDK系统环境变量,却不知道该如何操作. ...

  8. Win10环境下的Ubuntu安装与配置

    目录 Ubuntu的安装与配置 WSL的安装 切换到root用户 工具安装 SSH配置 github配置SSH VS Code远程连接Ubuntu VS Code的安装 远程连接 VS Code配置L ...

  9. win10环境下 运行debug程序

    百度网盘:链接:https://pan.baidu.com/s/1y6omgW6fI-gT3Dp-0hutOg    提取码:iw4l CSDN0积分下载:https://download.csdn. ...

最新文章

  1. 《Cacti实战》——3.1 检索流程
  2. 零基础的前端开发初学者应如何系统地学习?
  3. 第18天学习Java的笔记-ArrayList
  4. Popush任务之linux配置篇
  5. 计算机检测维修与数据恢复课件,2017年全国职业院校技能大赛中职组“计算机检测维修与数据恢复”赛项说明会ppt课件.ppt...
  6. ActionScript 3.0入门:Hello World、文件读写、数据存储(SharedObject)、与JS互调
  7. MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理
  8. 我们如何在Python中创建多行注释?
  9. Python3 语法
  10. 【clickhouse】ClickHouseException code: 225 ZooKeeper session has been expired
  11. 简述springmvc过程_Springmvc执行流程
  12. linux 驱动程序 设备模块 设备号 设备文件创建 设备注册 字符驱动设备分析
  13. [JNI]开发之旅(7)JNI函数中调用java对象的方法
  14. http长连接、长轮询的理解
  15. w10如何共享计算机硬盘,w10共享盘怎么设置_win10如何共享硬盘
  16. 到底买苹果XS还是XR_iPhone XS和XR买哪个?10个理由告诉你XS更好,贵是有原因的!...
  17. 轻松学会分布式事务算法
  18. matlab产生正定矩阵
  19. echarts的x轴文字倾斜展示
  20. linkkitapp log for debug

热门文章

  1. ppt密码忘了怎么解除,ppt权限限制怎么解除?
  2. php 5.3 版本for mac下载,PHP for Mac下载
  3. iOS开发 - 在实战中挖掘之线程间的通信方式
  4. Android之使用GPS和NetWork定位
  5. 抖音xg算法源码Python,Java解析 0361 0404
  6. EPCSTOE半球型电磁炉E0故障维修
  7. R语言学习笔记(六):OLS回归
  8. 全国vb计算机二级考试试题,全国计算机二级考试VB程序设计复习试题
  9. 个人日程管理软件(最新版本1.6 beta 202009261922)
  10. bWKztRpC滞誓麓旁矣驹沤航评旨访司对拥有雷火的宇天,少年也得认真对待:“那好。我