近几年来,兴起了一股人工智能热潮,让人们见到了AI的能力和强大,比如图像识别,语音识别,机器翻译,无人驾驶等等。总体来说,AI的门槛还是比较高,不仅要学会使用框架实现,更重要的是,需要有一定的数学基础,如线性代数,矩阵,微积分等。

幸庆的是,国内外许多大神都已经给我们造好“轮子”,我们可以直接来使用某些模型。今天就和大家交流下如何实现一个简易版的人脸对比,非常有趣!

整体思路:

1、预先导入所需要的人脸识别模型;

2、遍历循环识别文件夹里面的图片,让模型“记住”人物的样子;

3、输入一张新的图像,与前一步文件夹里面的图片比对,返回最接近的结果。

使用到的第三方模块和模型:

1、模块:os,dlib,glob,numpy;

2、模型:人脸关键点检测器,人脸识别模型。

第一步:导入需要的模型。

这里解释一下两个dat文件:

它们的本质是参数值(即神经网络的权重)。人脸识别算是深度学习的一个应用,事先需要经过大量的人脸图像来训练。所以一开始我们需要去设计一个神经网络结构,来“记住”人类的脸。

对于神经网络来说,即便是同样的结构,不同的参数也会导致识别的东西不一样。在这里,这两个参数文件就对应了不同的功能(它们对应的神经网络结构也不同):

shape_predictor.dat这个是为了检测人脸的关键点,比如眼睛,嘴巴等等;dlib_face_recognition.dat是在前面检测关键点的基础上,生成人脸的特征值。

所以后面使用dlib模块的时候,其实就是相当于,调用了某个神经网络结构,再把预先训练好的参数传给我们调用的神经网络。顺便提一下,在深度学习领域中,往往动不动会训练出一个上百M的参数模型出来,是很正常的事。

import os,dlib,glob,numpy
from skimage import io

# 人脸关键点检测器
predictor_path = "shape_predictor.dat"
# 人脸识别模型、提取特征值
face_rec_model_path = "dlib_face_recognition.dat"
# 训练图像文件夹
faces_folder_path ='train_images'

# 加载模型
detector = dlib.get_frontal_face_detector()
sp = dlib.shape_predictor(predictor_path)
facerec = dlib.face_recognition_model_v1(face_rec_model_path)
第二步:对训练集进行识别。

在这一步中,我们要完成的是,对图片文件夹里面的人物图像,计算他们的人脸特征,并放到一个列表里面,为了后面可以和新的图像进行一个距离计算。关键地方会加上注释,应该不难理解。

candidate = [] # 存放训练集人物名字
descriptors = [] #存放训练集人物特征列表

for f in glob.glob(os.path.join(faces_folder_path,"*.jpg")):
print("正在处理: {}".format(f))
img = io.imread(f)
candidate.append(f.split('\\')[-1].split('.')[0])
# 人脸检测
dets = detector(img, 1)
for k, d in enumerate(dets):
shape = sp(img, d)
# 提取特征
face_descriptor = facerec.compute_face_descriptor(img, shape)
v = numpy.array(face_descriptor)
descriptors.append(v)

print('识别训练完毕!')
当你做完这一步之后,输出列表descriptors看一下,可以看到类似这样的数组,每一个数组代表的就是每一张图片的特征量(128维)。然后我们可以使用L2范式(欧式距离),来计算两者间的距离。

举个例子,比如经过计算后,A的特征值是[x1,x2,x3],B的特征值是[y1,y2,y3], C的特征值是[z1,z2,z3]。

那么由于A和B更接近,所以会认为A和B更像。想象一下极端情况,如果是同一个人的两张不同照片,那么它们的特征值是不是应该会几乎接近呢?知道了这一点,就可以继续往下走了。

第三步:处理待对比的图片。

其实是同样的道理,如法炮制,目的就是算出一个特征值出来,所以和第二步差不多。然后再顺便计算出新图片和第二步中每一张图片的距离,再合成一个字典类型,排个序,选出最小值,搞定收工!

try:
## test_path=input('请输入要检测的图片的路径(记得加后缀哦):')
img = io.imread(r".\test_images\test6.jpg")
dets = detector(img, 1)
except:
print('输入路径有误,请检查!')

dist = []
for k, d in enumerate(dets):
shape = sp(img, d)
face_descriptor = facerec.compute_face_descriptor(img, shape)
d_test = numpy.array(face_descriptor)
for i in descriptors: #计算距离
dist_ = numpy.linalg.norm(i-d_test)
dist.append(dist_)

# 训练集人物和距离组成一个字典
c_d = dict(zip(candidate,dist))
cd_sorted = sorted(c_d.items(), key=lambda d:d[1])
print ("识别到的人物最有可能是: ",cd_sorted[0][0])
这里我用了一张“断水流大师兄”林国斌的照片,识别的结果是,果然,是最接近黎明了(嘻嘻,我爱黎明)。但如果你事先在训练图像集里面有放入林国斌的照片,那么出来的结果就是林国斌了。

为什么是黎明呢?我们看一下输入图片里的人物最后与每个明星的距离,输出打印一下:

{'刘亦菲': 0.5269014581137407,

'刘诗诗': 0.4779630331578229,

'唐艺昕': 0.45967444611419184,

'杨幂': 0.4753850256188804,

'迪丽热巴': 0.5730399094704894,

'郑秀妍': 0.40740137304879187,

'郑秀晶': 0.45325515192940385,

'郭富城': 0.7624925709626963,

'黎明': 0.5925473299225084}

没错,他和黎明的距离是最小的,所以和他也最像了!

源码及模型下载:https://download.csdn.net/download/m0_38106923/10772957

原文链接:https://blog.csdn.net/m0_38106923/article/details/83862334

用Python实现一个简单的——人脸相似度对比的更多相关文章

  1. 用Python写一个简单的Web框架

    一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...

  2. 用Python编写一个简单的Http Server

    用Python编写一个简单的Http Server Python内置了支持HTTP协议的模块,我们可以用来开发单机版功能较少的Web服务器.Python支持该功能的实现模块是BaseFTTPServe ...

  3. python中一个简单的webserver

     python中一个简单的webserver 2013-02-24 15:37:49 分类: Python/Ruby 支持多线程的webserver   1 2 3 4 5 6 7 8 9 10 11 ...

  4. Python实现一个简单三层神经网络的搭建并测试

    python实现一个简单三层神经网络的搭建(有代码) 废话不多说了,直接步入正题,一个完整的神经网络一般由三层构成:输入层,隐藏层(可以有多层)和输出层.本文所构建的神经网络隐藏层只有一层.一个神经网 ...

  5. 用python实现一个简单的词云

    对于在windows(Pycharm工具)里实现一个简单的词云还是经过了几步小挫折,跟大家分享下,如果遇到类似问题可以参考: 1. 导入wordcloud包时候报错,当然很明显没有安装此包. 2. 安 ...

  6. python制作一个简单的中奖系统

    注释: 展示图下的代码,我是用pycharm写的,是python解释器中的一种,本课没不同解释器的要求,可根据自己喜欢的解释器编写. 步骤: 本期给大家带来的是,一个简单的中奖系统,首先打开自己电脑上 ...

  7. python 搭建一个简单的 搜索引擎

    我把代码和爬好的数据放在了git上,欢迎大家来参考 https://github.com/linyi0604/linyiSearcher 我是在 manjaro linux下做的, 使用python3 ...

  8. 使用Python制作一个简单的刷博器

    呵呵,不得不佩服Python的强大,寥寥几句代码就能做一个简单的刷博器. import webbrowser as web import time import os count=0 while co ...

  9. 使用Python实现一个简单的项目监控

    在公司里做的一个接口系统,主要是对接第三方的系统接口,所以,这个系统里会和很多其他公司的项目交互.随之而来一个很蛋疼的问题,这么多公司的接口,不同公司接口的稳定性差别很大,访问量大的时候,有的不怎么行 ...

随机推荐

  1. OpenFire后台插件上传获取webshell及免密码登录linux服务器

    1.目标获取 (1)fofa.so网站使用搜索body="Openfire, 版本: " && country=JP,可以获取日本存在的Openfire服务器.如图 ...

  2. Cheat Engine 人造指针

    打开游戏 查看内存区域 查看游戏当前使用的内存区域 下面这一段是游戏当前使用的内存区域,选择一片可以读写的内存区域 跳转到这片内存 查看是否有空余内存可以使用 使用空闲内存 我们选择0075DFD0开 ...

  3. consul:健康检查

    官方文档:https://www.consul.io/docs/agent/checks.html consul提供的健康检查有以下几种: 1.script+interval 2.http+inter ...

  4. 搞不懂JS中赋值·浅拷贝·深拷贝的请看这里

    前言 百科定义:拷贝就是拷贝指向对象的指针,意思就是说:拷贝出来的目标对象的指针和源对象的指针指向的内存空间是同一块空间,浅拷贝只是一种简单的拷贝,让几个对象公用一个内存,然而当内存销毁的时候,指向这 ...

  5. sizeof()计算

    本节包含sizeof()计算结构体,位域,数组,字符串,指针,c++中的class等类型的大小,sizeof()计算的大小都是以字节为单位. 一 计算基本类型的长度 sizeof(char): 1 s ...

  6. GitHub Vue项目推荐|Vue+Element实现的电商后台管理系统功能丰富

    GitHub Vue项目推荐|mall-admin-web是一个电商后台管理系统的前端项目基于Vue+Element实现 主要包括商品管理.订单管理.会员管理.促销管理.运营管理.内容管理.统计报表. ...

  7. Solr基础理论【相关度计算】

    一.简介 寻找匹配的文档是构建优质搜索体验的关键步骤,但这仅仅是第一步.大多数用户不愿意通过逐页翻阅搜索结果来找到想要的文档.根据一般经验,仅有10%的用户在网页搜索中有意愿继续翻阅第一页以后的搜索结 ...

  8. 最新的JavaScript知识总结,欢迎各位大佬指正,需要的留下邮箱,给你们发原稿(PDF版)

    小编整理javascript用的是有道云笔记,导出的word版本,但是代码块显示格式是乱的,不便于阅读 所以,各位有需要的话,小编可以将导出的pdf版发给大家!pdf版跟word没有什么区别,知识没法 ...

  9. Httpd服务入门知识-Httpd服务常见配置案例之日志设定

    Httpd服务入门知识-Httpd服务常见配置案例之日志设定 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.日志类型 [root@node101.yinzhengjie.org ...

  10. gitlab修改IP地址及仓库地址

    将IP修改为192.168.10.100,操作方法 . 先修改本地的IP地址 vim /etc/sysconfig/network-scripts/ifcfg-eth0TYPE=EthernetBOO ...