face_recognition是世界上最简洁的人脸识别库,你可以使用Python和命令行工具提取、识别、操作人脸。

face_recognition的人脸识别是基于业内领先的C++开源库 dlib中的深度学习模型,用Labeled Faces in the Wild人脸数据集进行测试,有高达99.38%的准确率。但对小孩和亚洲人脸的识别准确率尚待提升。

face_recognition可以产生很多有趣的应用。

官方原文代码见:https://github.com/ageitgey/face_recognition/blob/master/examples/face_recognition_knn.py

face_recognition包括三个部分的代码

1、训练数据集

2、预测数据集

3、输出标签

训练数据集要遵循一定的数据格式,可以是以文件夹名称为标识的一个个图片,也可以是以文件名为标识的单个图片,当然前者每个人的图片越多,训练越充分。

训练数据集首先要检测出人脸,多个或零个均非合法的人脸

然后将图片二进制传入X,图片标识传入y,进行训练

训练图片是使用sklearn的KNN近邻分类器(KNeighborsClassifier)进行训练的,这个近邻的个数可以调节。

训练完成后写入模型文件,写入模型文件的好处是一次训练,后续可以直接使用,毕竟训练的时间过长,而用户可以实时添加人脸,难点在于如何增量进行训练?还没想到好办法。

预测过程中最大的困惑是neighbors的返回值,以及对返回值的处理,尤其是distance,这个distance关系到预测的准确与否,无论如何knn都会返回最近的距离和标签,但这个标签正确与否就不知道了,所以阈值设置很重要,我这边设置的是0.5。

最后是在图片上标注出人脸矩形和识别出的人物标签。

我这边是用的ORL数据集,以及从网上找到刘德华、成龙和我的照片。

import math
from sklearn import neighbors
import os
import os.path
import pickle
from PIL import Image, ImageDraw
import face_recognition
from face_recognition.face_recognition_cli import image_files_in_folderALLOWED_EXTENSIONS = {'bmp','png', 'jpg', 'jpeg'}# 对指定的训练图片文件夹进行训练
def train(train_dir, model_save_path=None, n_neighbors=None, knn_algo='ball_tree', verbose=False):"""Trains a k-nearest neighbors classifier for face recognition.:param train_dir: directory that contains a sub-directory for each known person, with its name.(View in source code to see train_dir example tree structure)Structure:<train_dir>/├── <person1>/│   ├── <somename1>.jpeg│   ├── <somename2>.jpeg│   ├── ...├── <person2>/│   ├── <somename1>.jpeg│   └── <somename2>.jpeg└── ...:param model_save_path: (optional) path to save model on disk:param n_neighbors: (optional) number of neighbors to weigh in classification. Chosen automatically if not specified:param knn_algo: (optional) underlying data structure to support knn.default is ball_tree:param verbose: verbosity of training:return: returns knn classifier that was trained on the given data."""X = []y = []# 循环获取训练集图片for class_dir in os.listdir(train_dir):if not os.path.isdir(os.path.join(train_dir, class_dir)):continue# 遍历当前任务的每一张图片# image_files_in_folder,这个地方是获取文件夹下的所有图片文件,可以修改其中的图片类型# 默认是jpg|jpeg|png,后来追加了bmpprint('training picture of {}'.format(class_dir))for img_path in image_files_in_folder(os.path.join(train_dir, class_dir)):# 加载图片文件,其实是numpy数组image = face_recognition.load_image_file(img_path)# 获取人脸检测框face_bounding_boxes = face_recognition.face_locations(image)# 多个人物或者0个人物不处理if len(face_bounding_boxes) != 1:# If there are no people (or too many people) in a training image, skip the image.if verbose:print("Image {} not suitable for training: {}".format(img_path, "Didn't find a face" if len(face_bounding_boxes) < 1 else "Found more than one face"))else:# Add face encoding for current image to the training setX.append(face_recognition.face_encodings(image, known_face_locations=face_bounding_boxes)[0])y.append(class_dir)# 设置KNN分类器的近邻数# Determine how many neighbors to use for weighting in the KNN classifierif n_neighbors is None:# n_neighbors = int(round(math.sqrt(len(X))))n_neighbors = 3if verbose:print("Chose n_neighbors automatically:", n_neighbors)# 创建KNN分类器,并进行训练knn_clf = neighbors.KNeighborsClassifier(n_neighbors=n_neighbors, algorithm=knn_algo, weights='distance')knn_clf.fit(X, y)# 保存KNN训练结果if model_save_path is not None:with open(model_save_path, 'wb') as f:pickle.dump(knn_clf, f)return knn_clf# 对指定的预测图片进行预测
def predict(X_img_path, knn_clf=None, model_path=None, distance_threshold=0.5):"""Recognizes faces in given image using a trained KNN classifier:param X_img_path: path to image to be recognized:param knn_clf: (optional) a knn classifier object. if not specified, model_save_path must be specified.:param model_path: (optional) path to a pickled knn classifier. if not specified, model_save_path must be knn_clf.:param distance_threshold: (optional) distance threshold for face classification. the larger it is, the more chanceof mis-classifying an unknown person as a known one.:return: a list of names and face locations for the recognized faces in the image: [(name, bounding box), ...].For faces of unrecognized persons, the name 'unknown' will be returned."""# 校验当前文件类型if not os.path.isfile(X_img_path) or os.path.splitext(X_img_path)[1][1:] not in ALLOWED_EXTENSIONS:raise Exception("Invalid image path: {}".format(X_img_path))# 校验当前模型文件和knn模型,两个不能全空if knn_clf is None and model_path is None:raise Exception("Must supply knn classifier either thourgh knn_clf or model_path")# 加载训练好的KNN模型if knn_clf is None:with open(model_path, 'rb') as f:knn_clf = pickle.load(f)# 加载图片,获取人脸检测框X_img = face_recognition.load_image_file(X_img_path)X_face_locations = face_recognition.face_locations(X_img)# print('predict {}'.format(X_img_path))# 如果未找到人脸,返回[]if len(X_face_locations) == 0:return []# 对测试图片进行编码转换,转换为numpy数组faces_encodings = face_recognition.face_encodings(X_img, known_face_locations=X_face_locations)# 通过KNN模型找到最佳匹配的人脸closest_distances = knn_clf.kneighbors(faces_encodings, n_neighbors=3)# # 返回值indices:第0列元素为参考点的索引,后面是(n_neighbors - 1)个与之最近的点的索引# # 返回值distances:第0列元素为与自身的距离(为0),后面是(n_neighbors - 1)个与之最近的点与参考点的距离# closest_distances= [[0.34997745 0.3750366  0.37819395]]# closest_distances= [[ 5 12 11]]# for i in closest_distances:#     print('closest_distances=',i)are_matches = []# are_matches = [closest_distances[0][i][0] <= distance_threshold for i in range(len(X_face_locations))]for i in range(len(X_face_locations)):are_matches.append( closest_distances[0][i][0] <= distance_threshold)#print('predict value=', closest_distances[0][i][0])# print('knn_clf.predict(faces_encodings)=',knn_clf.predict(faces_encodings))# 预测分类return [(pred, loc) if rec else ("unknown", loc) for pred, loc, rec in zip(knn_clf.predict(faces_encodings), X_face_locations, are_matches)]# 在图片上输出预测标签
def show_prediction_labels_on_image(img_path, predictions):"""Shows the face recognition results visually.:param img_path: path to image to be recognized:param predictions: results of the predict function:return:"""# 打开图片,获取句柄pil_image = Image.open(img_path).convert("RGB")draw = ImageDraw.Draw(pil_image)# 对预测结果进行遍历for name, (top, right, bottom, left) in predictions:# 在人脸周边画矩形框draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))# There's a bug in Pillow where it blows up with non-UTF-8 text# when using the default bitmap fontname = name.encode("UTF-8")# 在人脸地图输出标签text_width, text_height = draw.textsize(name)draw.rectangle(((left, bottom - text_height - 10), (right, bottom)), fill=(0, 0, 255), outline=(0, 0, 255))draw.text((left + 6, bottom - text_height - 5), name, fill=(255, 255, 255, 255))# Remove the drawing library from memory as per the Pillow docsdel draw# Display the resulting imagepil_image.show()if __name__ == "__main__":# 指定训练集路径和预测集路径train_dir=r'C:\Python\Pycharm\docxprocess\picture\ORL'test_dir=r'C:\Python\Pycharm\docxprocess\picture\predict'# 第一步,通过KNN分类器进行训练,并存储模型文件print("Training KNN classifier...")classifier = train(train_dir, model_save_path="trained_knn_model.clf", n_neighbors=3)print("Training complete!")# 第二步,使用训练分类器,对未知图片进行预测for image_file in os.listdir(test_dir):full_file_path = os.path.join(test_dir, image_file)print("Looking for faces in {}".format(image_file))# 使用训练模型进行预测predictions = predict(full_file_path, model_path="trained_knn_model.clf")# 输出结果for name, (top, right, bottom, left) in predictions:print("- Found {} at ({}, {})".format(name, left, top))# 图片上显示输出结果show_prediction_labels_on_image(os.path.join(test_dir, image_file), predictions)

人物1的识别,分类准确,距离为0

人物2的识别,分类准确,距离为0

合照的识别,里面包括周星驰、刘德华、李连杰、成龙,但周星驰和李连杰不在训练集内,周星驰未识别出来,刘德华和成龙识别正确,但李连杰识别出的最近距离甚至比刘德华本人还接近。

刘德华本人的识别,分类准确,距离为0.35左右

刘亦菲的识别,分类准确,距离为0.68左右

本人的识别,分类准确,距离为0.42左右,我只有两张训练照片,一张是身份证,一张是正照。

最后,谢谢关注,谢谢支持!

关于OpenCV for Python入门-face_recognition实现人脸识别相关推荐

  1. 关于OpenCV for Python入门-自带人脸检测算法比较

    本来学习OpenCV的目的就是为了做人脸识别.车辆识别.人群计数等等,识别人脸首先要进行人脸检测,OpenCV中内置了Haar Cascade人脸分类器,其中包括haarcascade_frontal ...

  2. 关于OpenCV for Python入门-dlib实现人脸检测

    Dlib 是用编程语言 C ++编写的通用跨平台软件库.它的设计深受来自契约式设计和基于组件的软件工程的思想的影响.因此,首先也是最重要的是一组独立的软件组件.这是一个加速软件许可证下发布的开源软件. ...

  3. Python与人工智能入门实践——简易人脸识别系统

    Python与人工智能入门实践--简易人脸识别系统 写在前面: 笔者在寒假期间进行了一些简短的实训,主要内容包括简单的爬虫和简单的人脸识别算法,由于时间有限,对于python也是第一次详细学习,功能较 ...

  4. 人脸识别python face_recognize_【python+face_recognition】人脸识别初始

    [python+face_recognition]人脸识别初始 发布时间:2018-09-01 12:03, 浏览次数:366 , 标签: python face recognition face_r ...

  5. Python+OpenCV 调用手机摄像头并实现人脸识别

    文章内容: 1.windows 环境下安装 OpenCV 机器视觉环境搭建: 2.基于通过 Python+OpenCV调用手机摄像头并实现人脸检测识别. 目录 1 实验环境 2 实验准备 2.1 下载 ...

  6. python人脸识别考勤系统 dlib+OpenCV和Pyqt5、数据库sqlite 人脸识别系统 计算机 毕业设计 源码

    一.项目介绍 Python语言.dlib.OpenCV.Pyqt5界面设计.sqlite3数据库 本系统使用dlib作为人脸识别工具,dlib提供一个方法可将人脸图片数据映射到128维度的空间向量,如 ...

  7. python人脸识别毕业设计-Python基于Dlib的人脸识别系统的实现

    之前已经介绍过人脸识别的基础概念,以及基于opencv的实现方式,今天,我们使用dlib来提取128维的人脸嵌入,并使用k临近值方法来实现人脸识别. 人脸识别系统的实现流程与之前是一样的,只是这里我们 ...

  8. 用Python实现简单的人脸识别,10分钟(附源码)

    前言 今天,我们用Python实现简单的人脸识别技术! Python里,简单的人脸识别有很多种方法可以实现,依赖于python胶水语言的特性,我们通过调用包可以快速准确的达成这一目的.这里介绍的是准确 ...

  9. 10分钟手把手教你运用Python实现简单的人脸识别

    欲直接下载代码文件,关注我们的公众号哦!查看历史消息即可! 前言:让我的电脑认识我 我的电脑只有认识我,才配称之为我的电脑! 今天,我们用Python实现高大上的人脸识别技术! Python里,简单的 ...

  10. 基于Python的百度AI人脸识别API接口(可用于OpenCV-Python人脸识别)

    基于Python的百度AI人脸识别API接口(可用于OpenCV-Python人脸识别) 资源: download.csdn.net/download/weixin_53403301/43644312 ...

最新文章

  1. 在人工智能时代,我们更需要理解自己的智能 | 艾伦脑科学研究所所长克里斯托夫·科赫STEP峰会演讲实录
  2. Java的内存泄漏和垃圾回收机制
  3. AJAX 跨域请求 - JSONP获取JSON数据
  4. php屏蔽行,PHP屏蔽过滤指定关键字的方法
  5. Marketing Cloud demo环境和API使用方法说明
  6. 水泵怎么做_泳池设备日常怎么维护和保养?
  7. xshell 6 连接debian系统拒绝了密码_原来连接Linux,还有这个方法
  8. com.android.phone已停止运行怎么解决方法,com.android.phone已停止运行怎么解决
  9. UNIX环境高级编程——线程同步之条件变量以及属性
  10. linux+tux游戏,Linux吉祥物游戏SuperTux 0.5.0版发布 类《超级马里奥兄弟》
  11. CAD转GIS工具软件下载
  12. js 实现文件上传 php,JS+php后台实现文件上传功能详解
  13. Base64的Woff2字体信息如何转成成文件
  14. 01.电脑黑客基本知识
  15. M480 EMAC驱动01-EMAC底层接口
  16. 一招学会DIY官网可视化设计支持导出微擎、UNIAPP、H5、微信小程序源码
  17. java 字符串转换成map_java中string类型转换成map
  18. 数码相片转传统相片尺寸表
  19. python画树叶-用Python绘图,感受编程之美
  20. 【UI篇】Android 沉浸式状态栏的那些事

热门文章

  1. matlab语言与测绘,MATLAB语言及测绘数据处理应用
  2. SSL证书申请流程,中文域名如何申请证书?
  3. 实现跨word文档的格式刷,两个word间格式刷
  4. 《财富》杂志评选出必读的75本最睿智的图书
  5. 手机无法获取电脑热点ip地址
  6. 解决Eclipse保存web.xml卡的问题
  7. Falsy Bouncer|FreeCodeCamp
  8. noob学算法----冒泡(bubble)排序算法 Java
  9. 从企业版BOSS直聘,看求职简历技巧
  10. 介绍会议中控系统模块化构成及功能作用