热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python人脸识别训练模型,Python人脸识别算法

之前曾经写过一篇博客,使用dlib进行人脸检测,就是检测视频中是否出现了人脸,dlib还可以实现人脸识别。因此今天更新博客主要是记录如何使用python+opencv+dl

之前曾经写过一篇博客,使用dlib进行人脸检测,就是检测视频中是否出现了人脸,dlib 还可以实现人脸识别。因此今天更新博客主要是记录如何使用 python + opencv + dlib 实现人脸识别

源代码已经托管到github,下拉到底部即可看到

人脸识别的主要算法

其核心算法是 欧式距离算法使用该算法计算两张脸的面部特征差异,一般在0.6 以下都可以被认为是同一张脸

人脸识别的主要步骤

1 获得人脸图片
2 将人脸图片转为128D的矩阵(这个也就是人脸特征的一种数字化表现)
3 保存人脸128D的特征到文件中
4 获取其他人脸转为128D特征通过欧式距离算法与我们保存的特征对比,如果差距在0.6以下就说明两张脸差距比较小

准备工作

人脸识别需要下载两个文件:
wget http://dlib.net/files/shape_predictor_5_face_landmarks.dat.bz2
wget http://dlib.net/files/dlib_face_recognition_resnet_model_v1.dat.bz2
下载完成后 通过 bzip2 -d 命令解压这两个压缩包

以下就按照上面的步骤一步一步去实现人脸识别 1 获取人脸

获取人脸的方式有两种途径
1 通过图片
2 通过摄像头采集

图片方式

通过图片获取人脸 demo(需要检查图片中是否包含了人脸)

import cv2import dlibpicture = '/home/sunshine/faces/harden1.jpg'detector = dlib.get_frontal_face_detector()def add_face_from_image(image):imdata = cv2.imread(image)rgb_image = cv2.cvtColor(imdata, cv2.COLOR_BGR2RGB)faces = detector(rgb_image, 1)if len(faces) == 0:print("没有检测到人脸")else: # 到此就获取到了人脸数据 pass 视频方式

通过视频方式获取人脸demo 这种方式需要把视频的图片截取下来保存到指定的路径

import cv2import dlibfrom pathlib import Pathvideo = cv2.VideoCapture(0)save_path = '/home/fantasy/faces'def read_camera0(): """ 读取摄像头 """ while 1: ok, frame = video.read() if not ok: print("读取摄像头#0失败") return else: yield frame video.release()def putText(image, text, location=(100, 150), fOnt=cv2.FONT_HERSHEY_COMPLEX, size=1.1, color=(0, 255, 255), font_weight=2): """ 往视频上加文字 param: image 视频/图片 param: text 文字内容 param: location 文字的位置 param: font 字体 param: size: 字体大小 param: color: 字体颜色 param: font_weight 字体粗细 """ cv2.putText(image, text, location, font, size, color, font_weight, lineType=cv2.LINE_AA)def add_face_from_camera():frames = cv_tools.read_camera0() count = 0 for frame in frames: image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) title = 'Register' press = cv2.waitKey(2) data = detector(image_rgb) if len(data) == 0: putText(frame, "No face was detected!", color=(0, 0, 255)) if press == ord('q'): break if press == ord('a'): if len(data) == 0: putText(frame, "No face was detected!", color=(0, 0, 255)) else: count += 1 impath = Path(save_path).joinpath('%s.jpg' % count) print("保存照片 %s" % impath) cv2.imwrite(str(impath), frame) cv_tools.putText(frame, 'a:Add', location=(40, 300)) cv_tools.putText(frame, 'q:Quit', location=(40, 350)) cv_tools.putText(frame, 'save count:%s' % count, location=(40, 400), size=1.0) cv2.imshow(title, frame) cv2.destroyAllWindows()

视频的方式需要注意几点
1 我使用的是笔记本电脑因此 通过 cv2.VideoCapture(0) 方法默认就是获取到笔记本默认的摄像头,如果你的台式机没有摄像头或者是外接摄像头可能就无法获取
2 视频的方式保存图片 需要将光标点击到视频,然后按 a 键, 退出就按 q 键
3 视频中如果没有检查到人脸就会出现提示 No face was detected! 此时是没法保存图片的

视频方式截图

到这一步就完成了 获取人脸照片,保存到指定的路径了 2-3 将获取到的人脸数据转为128D 数据,并保存到文件

这一步我们要做的就是,将我们上一步保存的人脸数据,通过使用dlib 提取人脸特征然后保存到文件里面
这样我们就拥有了 某张脸的数据了, 下次直接使用这个数据和新的数据比对就可以确定是否是同一个人

人脸转为128D特征数据demo

import osimport cv2import dlibfrom imutils import pathsface_image = '/home/sunshine/faces'predictor_path = '/home/fantasy/MachineLearning/cv/shape_predictor_5_face_landmarks.dat'face_model_path = '/home/fantasy/MachineLearning/cv/dlib_face_recognition_resnet_model_v1.dat'def prepare(): """ """ if not os.path.exists('feature'): os.mkdir('feature') if os.path.exists('feature'): shutil.rmtree('feature') os.mkdir('feature')def get_detector(): """ """ return dlib.get_frontal_face_detector()def get_predictor(): """ """ return dlib.shape_predictor(predictor_path)def get_face_model(): """ """ return dlib.face_recognition_model_v1(face_model_path)def get_faces_image(): """ """ return paths.list_images(face_image)def faces_to_128D(): """ """ prepare() faces = get_faces_image() detector = get_detector() predictor = get_predictor() face_model = get_face_model() count = 0 for image in faces: imdata = cv2.imread(image) image_rgb = cv_tools.bgr2rgb(imdata) has_face = detector(image_rgb, 1) if len(has_face) == 0: print("未检测到人脸 %s" % image) continue count += 1 shape = predictor(image_rgb, has_face[0]) face_desc = face_model.compute_face_descriptor(image_rgb, shape) feature_array = np.array([]) for _, desc in enumerate(face_desc): feature_array = np.append(feature_array, desc) filename = str(count) + '.csv' filename = os.path.join('feature', filename) print("保存 %s 特征文件 %s" % (image, filename)) face_feature_to_csv(filename, feature_array)def face_feature_to_csv(filename, col): """ """ np.savetxt(filename, col, delimiter=',')

通过上面的步骤我们把之前通过图片或者视频方式获取到的人脸提取到了特征 保存在文件里面了 4 人脸对比

通过前面的方式我们已经拥有了一个可以识别某张脸的数据,现在就需要采集到其他的人脸图片转为128D再和我们保存的数据,使用欧式距离方式进行对比

人脸对比的demo 从摄像头或者图片从获取人脸对比已有的数据

import cv2import dlibimport globimport numpy as np# 保存人脸特征的csv文件路径csv_path = '/home/sunshine/feature'all_load_feature = []# 1 先把保存的人脸特征读取到def load_face_feature(): """ """ all_csv = glob.glob(csv_path + '/*.csv') for filename in all_csv: array = np.loadtxt(filename, delimiter=',') print("加载已有的面部特征文件 %s" % filename) all_load_feature.append(array)# 2 再从摄像头或者 图片从获取一张人脸,转为128D数据和现有的对比def read_face_from_image(image): """ 通过从图片中获取人脸 """ imdata = cv2.imread(image) face_compare(imdata) cv2.imshow("face recogition", imdata) key = cv2.waitKey(0) if key == ord('q'): cv2.destroyAllWindows()def face_compare(face_image): """ """ rgb_image = cv2.cvtColor(face_image, cv2.COLOR_BGR2RGB) im_shape = rgb_image.shape im_height = im_shape[0] im_width = im_shape[1] faces = detector(rgb_image, 1) # 要检查图片中是否包含人脸 if len(faces) == 0: putText(face_image, "No face was detected!", color=(0, 0, 255)) else: # 将图片中的人脸转为128D数据 feature = face_feature(rgb_image, faces) csv_feature = random.choice(all_load_feature) # 使用欧式距离计算两张脸的差距 same = face_recogition(feature, csv_feature) if same: putText(face_image, "Yes!", location=(int(im_height/2), int(im_width/2))) else: putText(face_image, "No!", location=(int(im_height/2), int(im_width/2)), color=(0, 0, 255))def face_feature(image, faces): """ """ model = get_face_model() predictor = get_predictor() array = np.array([]) shape = predictor(image, faces[0]) face_desc = model.compute_face_descriptor(image, shape) for _, desc in enumerate(face_desc): array = np.append(array, desc) return arraydef face_recogition(face1, face2): """ """ # 计算两张脸的欧式距离 方法 1 # distance = 0 # for i in range(len(face1)): # distance += (face1[i] - face2[i])**2 # distance = np.sqrt(distance) # 计算两张脸的欧式距离 方法 2 # distance = np.sqrt(np.sum(np.square(face1 - face2))) # 计算两张脸的欧式距离 方法 3 distance = np.linalg.norm(face1- face2) print(distance) if(distance <0.5): return True else: return Falsedef read_face_from_camera0(): """ 从摄像头获取人脸 """ video = read_camera0() for frame in video: face_compare(frame) cv2.imshow("face recogition", frame) key = cv2.waitKey(1) if key == ord('q'): break cv2.destroyAllWindows()

以下是我从图片中输入了一张人脸,并将这张人脸特征保存到1.csv

然后再分别给一张是同一个人,不同人的脸的输出结果

源代码已经托管到github 喜欢的欢迎给我 star
代码地址:
https://github.com/pythondever/python-dlib-face-recognition

附: 人脸识别的原理:
https://zhuanlan.zhihu.com/p/24567586


推荐阅读
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • 无损压缩算法专题——LZSS算法实现
    本文介绍了基于无损压缩算法专题的LZSS算法实现。通过Python和C两种语言的代码实现了对任意文件的压缩和解压功能。详细介绍了LZSS算法的原理和实现过程,以及代码中的注释。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 开源真香 离线识别率高 Python 人脸识别系统
    本文主要介绍关于python,人工智能,计算机视觉的知识点,对【开源真香离线识别率高Python人脸识别系统】和【】有兴趣的朋友可以看下由【000X000】投稿的技术文章,希望该技术和经验能帮到 ... [详细]
  • 本文介绍了Python对Excel文件的读取方法,包括模块的安装和使用。通过安装xlrd、xlwt、xlutils、pyExcelerator等模块,可以实现对Excel文件的读取和处理。具体的读取方法包括打开excel文件、抓取所有sheet的名称、定位到指定的表单等。本文提供了两种定位表单的方式,并给出了相应的代码示例。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 访问控制_身份认证和访问控制技术学习20199319
    身份认证技术1、常用的身份认证方法(1)静态口令认证的问题:静态口令,即由用户自己设置或者系统给 ... [详细]
  • 区块链技术的应用案例展示
    按照行业主流观点,区块链技术应用将经历数字货币(1.0)、合约(2.0)和社会治理(3.0)阶段,当前正逐渐迈入合约阶段。一、区块链1.0:数字货币区块链技术伴随比特币应用而生,比 ... [详细]
author-avatar
张淑男尧珊肇玲
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有