Huge Lemon的博客

Python学习笔记 —— OpenCV+百度云接口实现人脸认证

2018-05-17

有话在先

前日注册了百度云账号,接触到了百度云的一系列接口,看到“人脸对比”后突发奇想,用人脸识别来做认证(虽然没有Alipay那么高端)模拟登录执行程序。
于是就去百度了百度云接口python实现人脸识别OpenCV人脸认证。网上实现百度云接口的代码是用Python3写的,但是OpenCV目前只支持Python2;所以我尝试了一下把py3的百度云人脸识别代码改成了py2的。
结果……失败了【悲伤.gif】……
所以我将就用那个py3,同时安装了py2,然后再在一个程序里面调用另一个程序
但是这样做可移植性差,需要用户同时安装py2和py3。

原文

python3.6+百度人脸识别API进行照片人脸对比:https://blog.csdn.net/weixin_39133476/article/details/79310817
python+OpenCV人脸认证:https://www.cnblogs.com/hanson1/p/7105265.html

Python2.x与3​​.x版本区别

  • Python的3​​.0版本,常被称为Python 3000,或简称Py3k。相对于Python的早期版本,这是一个较大的升级。
  • 为了不带入过多的累赘,Python 3.0在设计的时候没有考虑向下相容。
  • 许多针对早期Python版本设计的程式都无法在Python 3.0上正常执行。
  • 为了照顾现有程式,Python 2.6作为一个过渡版本,基本使用了Python 2.x的语法和库,同时考虑了向Python 3.0的迁移,允许使用部分Python 3.0的语法与函数。
  • 新的Python程式建议使用Python 3.0版本的语法。
  • 除非执行环境无法安装Python 3.0或者程式本身使用了不支援Python 3.0的第三方库。目前不支援Python 3.0的第三方库有Twisted, py2exe, PIL等。
  • 大多数第三方库都正在努力地相容Python 3.0版本。即使无法立即使用Python 3.0,也建议编写相容Python 3.0版本的程式,然后使用Python 2.6, Python 2.7来执行。
    详情阅读:
    https://blog.csdn.net/ljl6158999/article/details/78983725
    https://www.cnblogs.com/sherlockChen/p/8064896.html
    其实我遇到的问题是库的问题,py3将py2的一些库做了整合和删除,导致py2变py3时会很麻烦

实现方法

思想

  • 这需要之前先保存一张人脸的图片,然后调用摄像头拍照获取当前人脸,通过代码上传二者到百度云人脸对比进行比较分析
  • 分析后会有一段返回值,用BeautifulSoup库可取其重点文字:“是同一个人”,“不是同一个人”。二者有重复语句段,在判断的时候要注意。

源代码

authentication.py [Python2.7]

authentication.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# coding: utf-8
import cv2
import os
import time
import subprocess

print('Press Esc to exit')
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
faceCascade.load('D:/Program Files/Python/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')
imgWindow = cv2.namedWindow('FaceDetect', cv2.WINDOW_NORMAL)
path = os.getcwd()

def detect_face():
capInput = cv2.VideoCapture(0)
# 避免处理时间过长造成画面卡顿
nextCaptureTime = time.time()
faces = []
count = 0
if not capInput.isOpened(): print('Capture failed because of camera')
while 1:
ret, img = capInput.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
if nextCaptureTime < time.time():
nextCaptureTime = time.time() + 0.1
faces = faceCascade.detectMultiScale(gray, 1.3, 5)
# if faces:
for x, y, w, h in faces:
count += 1
img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

cv2.imshow('FaceDetect', img)
if count == 8:
print(u'检测出人脸')
cv2.imwrite(path + '/face.jpg', img)
time.sleep(2)
break
# 这是简单的读取键盘输入,27即Esc的acsii码
if cv2.waitKey(1) & 0xFF == 27:
break
capInput.release()
cv2.destroyAllWindows()

def main():
detect_face()

program = path + "/FaceCompare.py"
command = "py -3 "+ program
print(command)
os.system(command)
if os.path.exists(path + '/face.jpg'):
os.remove(path + '/face.jpg')

main()

FaceCompare.py [Python3.6]

FaceCompare.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import sys
import ssl
from urllib import request,parse
from aip import AipFace
import tkinter as tk
from tkinter import filedialog
import os

APP_ID = '你的APP_ID'
API_KEY = '你的API_KEY'
SECRET_KEY = '你的SECRET_KEY'

path = os.getcwd()

# client_id 为官网获取的AK, client_secret 为官网获取的SK
#获取token
def get_token():
client_id = API_KEY
client_secret = SECRET_KEY
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s'%(client_id,client_secret)
req = request.Request(host)
req.add_header('Content-Type', 'application/json; charset=UTF-8')
response = request.urlopen(req)
#获得请求结果
content = response.read()
#结果转化为字符
content = bytes.decode(content)
#转化为字典
content = eval(content[:-1])
return content['access_token']


#转换图片
#读取文件内容,转换为base64编码
#二进制方式打开图文件
def imgdata(file1path,file2path):
import base64
f=open(r'%s' % file1path,'rb')
pic1=base64.b64encode(f.read())
f.close()
f=open(r'%s' % file2path,'rb')
pic2=base64.b64encode(f.read())
f.close()
#将图片信息格式化为可提交信息,这里需要注意str参数设置
params = {"images":str(pic1,'utf-8') + ',' + str(pic2,'utf-8')}
return params

#提交进行对比获得结果
def img(file1path,file2path):
token = get_token()
#人脸识别API
#url = 'https://aip.baidubce.com/rest/2.0/face/v2/detect?access_token='+token
#人脸对比API
url = 'https://aip.baidubce.com/rest/2.0/face/v2/match?access_token='+token
params = imgdata(file1path,file2path)
#urlencode处理需提交的数据
data = parse.urlencode(params).encode('utf-8')
req = request.Request(url,data=data)
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
response = request.urlopen(req)
content = response.read()
content = bytes.decode(content)
content = eval(content)
#获得分数
score = content['result'][0]['score']
if score>80:
return '照片相似度:'+str(score)+',同一个人'
else:
return '照片相似度:'+str(score)+',不是同一个人'

def main():
print("\n************百度云人脸对比************")
file1_path = path + '/face.jpg'
file2_path = path + '/compared.jpg' # 之前保存的用于对比的图像
print("计算中...")
res = img(file1_path,file2_path)
print(path)
print('\n' + res)
print("**************************************\n")
if('同一个人' in res):
print('认证成功, 进入跑操系统')
if os.path.exists(path + '/face.jpg'):
os.remove(path + '/face.jpg')
command = path + '/SportsSpider.exe' # 上次写的学校跑操系统的爬虫程序
os.system(command)
else:
print('认证失败')

main()
使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏