动手实操 | 如何用 Python 实现人脸识别,证明这个杨幂是那个杨幂?

需求分析

要做安全方面的内容,依靠人脸识别通过和库中的脸比对后判定相似率来验证用户身份。

快速从图片中识别出人的信息,用于寻人功能等。

其实从安全的角度出发有很多可以囊括的。比如智能家居中的刷脸开门,支付软件的刷脸支付等都是例子。

人脸特征提取的步骤

真正的人脸识别需要很多的知识,大体上粗略的可以分为以下步骤:

  1.人脸检测(从图片中找到人脸):返回人脸位置和大小的参数。
  2.人脸特征定位:一般 69 点或者 106 个点对人脸的特征定位,技术上有 Adaboost&haar,以及 MSRA 的 alignment。
  3.人脸特征归一化(几何归一/灰度归一):前者对图像进行仿射变化使得不同的脸可以进行比对,后者则能使图像展现更多的细节以及减弱光线光照的应用。
  4.特征提取-特征后期融合。(基于特征近似度的多特征融合)
  5.特征距之间的距离来比对相似度、三氏距离。(马氏、欧氏 、巴氏)

操作过程中的注意事项

  1. 每张图片要先上传到 bucket 中才可以利用。
  2. API 对人脸匹配再返回很大程度依赖于用户的网络带宽。
  3. 当用户网络不好的情况下需要很久的时间才能得到返回结果。
  4. 要经过压缩处理,一般识别的较为准确最多可将图片压缩至 25 kb 左右。

我们要进行如下的步骤:

1)得到我们刚刚通过摄像头取得的人像
2)对我们的人像图片进行压缩
3)上传我们的人像图片到我们的 bucket 中
(这里要申明一点,七牛所有支持的 API 都要求文件在华东的 Bucket 下)
4)得到我们上传的图片的链接地址
5)对链接进行 urlbase64 加密(这里只要 import python 的 base64 库即可)
6)请求 API
7)得到网页的 JSON 格式数据
8)通过 JSON 库对数据进行分析
9)判断人脸的相似度是否符合,输出结果
10)删除 Bucket 中上传的临时图片

返回的 JSON 格式分析

{"status":"ok","confidence":0.73065597}复制代码

我们可以看到返回的 JSON 信息很简单, status 的意思是成功和不成功,而 confidence 则是相似度,所以我们对返回的信息进行分析会很简单。 status 如若成功则为 ok,不成功则为 invalid。

人脸相似度的判断

上表中所用的图片都来自己互联网,从表数据我们可以大致将本人的相似度以 0.7 为分界线。不过有趣的是,不知道为什么按杨幂进行整容的为什么相似度竟然低于杨幂和范冰冰的相似度(其他女星照的图片为范冰冰的人像),不同性别的相似度差异明显,所以就粗略的根据表格定为 >0.7 即可认为是本人。

安装所需的库

在 python 中,我分享的这个例子总共需要引入 6 个库


1 #import SDK
2 #Python学习交流群:125240963,群内每天分享干货,包括最新的python企业案例学习资料和零基础入门教程,欢迎各位小伙伴入群学习交流
3 from qiniu import Auth,put_file,etag
4 import qiniu.config
5 import requestsimport base64
6 import json
7 from PIL import Image
8 import os

requests 库,json 库,PIL 库请自行安装;
base64 库和 OS 库为自带所以无需安装。

(由于电脑已经安装了较多库,所以对于这些库是否为自带也记得不太清楚,如果出现了错误,请大家对应自己安装。)

程序的实现

请见下方的代码,采集到的人脸为 face.jpg。 (这里用了杨幂的两张图片作为示例)

  1 #七牛云"人脸识别"功能的python实现方法:by xlxw
  2 #请得到自己的Secret和Access key用于上传图片到空间中进行处理
  3 #人像识别是七牛云的一项收费项目,价格为 ¥1.5/1000次 测试时请先存2元避免意外
  4 
  5 #import SDK
  6 from qiniu import Auth,put_file,etag
  7 import qiniu.config
  8 import requests
  9 import base64
 10 import json
 11 from PIL import Image
 12 import os
 13 
 14 #上传
 15 def upload(bucket,path,filename,key,url):
 16     token = key.upload_token(bucket, filename, 3600)
 17     print('正在上传..')
 18     reform,inform = put_file(token, filename, path)
 19     if reform != None:
 20         print('已经成功地将{}->>{}'.format(filename,bucket))
 21         print("正在处理您的图片...")
 22         url=url + '/' + filename
 23         path=path.split('/')[-1]
 24     else:
 25         print('这里出现了一个小错误.无法上传..')
 26 
 27 #调用API
 28 def apiget(urlbucket,url):
 29     try:
 30         url=urlbucket + '/001.jpg' + '?face-analyze/verification/url/' + url
 31         #标准对比的图片地址,名称为001.jpg
 32         r=requests.get(url)
 33         r.raise_for_status()
 34         r.encoding=r.apparent_encoding
 35         return r.text
 36     except:
 37         print("网络发生故障,请重试..")
 38 
 39 #base64 Encode
 40 def base64encode(url):
 41     try:
 42         print("正在加密链接..")
 43         enurl=base64.urlsafe_b64encode(bytes(url, "utf-8"))
 44         print("加密完成")
 45         enurl=str(enurl)
 46         enurl=enurl.split("'")[1]
 47         return enurl
 48     except:
 49         print("这里出现了一个问题,请重试..")
 50 
 51 #PIL 图片压缩
 52 def pilresize(per,path):
 53     im=Image.open(path)
 54     imsize=im.size
 55     sizex=int(imsize[0]*per)
 56     sizey=int(imsize[1]*per)
 57     im=im.resize((sizex,sizey))
 58     im.save('trans.jpg','JPEG')
 59     print('图片压缩完成,输出成功')
 60     print('{}->>({},{})'.format(imsize,sizex,sizey))
 61 
 62 def pilwork(path):
 63     try:
 64         size=os.path.getsize(path)
 65         size = float(size)
 66         kb=size/1024
 67         per=10/kb
 68         pilresize(per,path)
 69     except:
 70         print("请检查您的地址是否输入错误")
 71 
 72 
 73 #JSON分析
 74 def jsonanal(jtext):
 75     print("正在分析,请稍后..")
 76     rj=json.loads(jtext)
 77     stat=rj['status']
 78     confi=rj['confidence']
 79     return stat + ',' +str(confi)
 80 
 81 #主体
 82 def main():
 83     #填写你的 AK 和 SK
 84     accesskey = input('请输入您在七牛云的AccessKey:')
 85     secretkey = input('请输入您在七牛云的SecretKey:')
 86 
 87     #鉴定身份
 88     keyq=Auth(accesskey,secretkey)
 89 
 90     #所要操作的空间
 91     bucketname =input("请输入要操作的空间(公开)名字:")
 92 
 93     #所要操作空间的外链地址
 94     urlbucket = input("请输入空间所绑定的域名或者默认外链地址:")
 95 
 96     #判定操作类型
 97     while 1:
 98         order=input('请输入你需要进行的操作:')
 99         mode=order.split(' ')[0]
100         if mode == '识别':
101             path=order.split(' ')[1]
102             fname=path.split('/')[-1:][0]
103             unrl=urlbucket+'/trans.jpg'
104             print('正在压缩图片.请稍后..')
105             #调用函数
106             pilwork(path)  #压缩图片
107             print("正在上传token,请稍后..")
108             upload(bucketname,'./trans.jpg','trans.jpg',keyq,urlbucket) #上传文件
109             enurl=base64encode(unrl)   #base64加密
110             jtext=apiget(urlbucket,enurl) #调用七牛api并得到返回的json数据
111             result=jsonanal(jtext)  #分析返回的json,得到最终相似度
112             if result.split(',')[0] == 'invalid':
113                 print('识别发生了错误')
114             else:
115                 if eval(result.split(',')[1]) >= 0.7:
116                     print("识别成功,鉴定为本人,相似度为{:.1f}".format(eval(result.split(',')[1])*100))
117                 else:
118                     print("识别成功,鉴定不是本人,相似度过低")
119         if mode == '退出':
120             print("欢迎您的使用..")
121             break
122 
123 #终端提示显示
124 print("+----------------------------------------+")
125 print("|        欢迎使用七牛的人脸识别功能      |")
126 print("+----------------------------------------+")
127 print("|本程序须知:                            |")
128 print("|1.本程序测试图片为杨幂的人像,见face.jpg |")
129 print("|2.您需要提供服务的Accesskey,Secretkey  |")
130 print("|3.您需要提供 bucket名字和bucket外链地址 |")
131 print("+----------------------------------------+")
132 print("|使用方法:                               |")
133 print("|1.识别输入格式: 识别 图片位置(包括后缀)|")
134 print("|2.退出输入格式: 退出                   |")
135 print("+----------------------------------------+")
136 main()

程序运行的截图:

用到的杨幂的两张照片为:
(均来自百度图片)

(用于比对的标准人像图片)
(已用 PIL 压缩 x0.3,y0.3)

(用于比对的图片)

作者:七牛云
链接:https://juejin.im/post/59719caef265da6c4741cdd7

猜你喜欢

转载自www.cnblogs.com/Python6359/p/9357197.html