目录
一、项目介绍
1.1 项目名称
《1:N人脸考勤机》
1.2 项目简介
基于windows平台下,使用PyCharmIDE完成开发工作,将提前准备好的照片上传百度云,借助百度aipSDK-Python实现和百度智能云的对接,实现摄像头采集人脸图片后上传百度云,在百度云中利用百度现有的人脸识别算法完成人脸的对比,之后借助SDK返回对比结果,将结果显示在客户端上。
1.3 项目物料
-
- 平台:windows
- 开发平台:PyCharm + Anaconda3(选装)
- 开发包:openCV2.4.9(Python)、aips(百度智能云人脸检测的SDK)
- 编程语言:Python
- 其他:识别对象的免冠正面照
1.4 技术栈
-
- 网络通信基本知识
- Python编程语言
- 百度智能云SDK(search函数等)
- OpenCV基于Python的接口的使用
1.5项目架构
上传百度云识别者照片--->图像采集--->图像处理--->上传百度云--->百度云对比--->返回对比结果--->结果处理--->显示结果。
三、项目细节
3.1 环境搭建
(1)安装PyCharm
1)安装
- 创建人脸识别项目及配置
(2)安装百度智能云人脸检测的SDK(Python)
1)接口的下载和安装
人脸识别_人脸检测_人脸对比_人脸搜索_活体检测_百度智能云
(3)创建百度智能云应用
1)选择百度云对应功能和免费权限
A、手机应用市场安装“百度”app,注册一个账号,登陆
B、利用百度app扫码登陆以下网址中的账户:
人脸识别私有化部署包_支持百万级超大型人脸库-百度AI开放平台
登陆成功后会返回图一,点击“立即申请”进入以下界面。
- 创建应用
注意:如果之前安装SDK失败了,这里可以选择直接下载SDK即可,选择其中的“Python Http SDK”即可。
- 创建组
这个就是上边创建的应用。我们开始创建组。
点击确认
点击画圈的地方(组名)
这就是创建组内用户的菜单,点击任何一个方框都可以。
- 上传识别的对比资源
创建组和组用户均完成,到时候百度云会自动找到要求的组,在组中对比符合要求的用户,反馈结果。
- 获取应用的账号和密码
将其中的内容(AK和SK)复制出来保存好(保存在一个文本文档内即可,文档一定要保留好)
关于opencv如何下载,作者在这里作为伏笔,大家自行尝试,有问题试着解决一下哦。解决不了记得评论哦。
3.2 利用opencv实现摄像头调取及相关图像的处理
其中有详细的注释,请仔细阅读,如果有不明白的地方,评论区留言,作者一一回复。
3.3 利用aips上传图像和结果返回
图片为多张,注意通过行号来看,避免少看代码
3.4 结果优化和处理
在屏幕显示结果:
在上边的92行位置加入如下代码:
注意通过行号来判断对齐缩进的位置,避免代码从属问题。
3.5 效果展示
3.6 遗留问题和解释
如遇闪退,可以优化,可以找找看是什么问题。由于账号隐私问题,隐藏APP_ID\AK\SK三个参数。
源码:
# coding: utf-8
# author: alex_chen
import cv2 as cv
from aip import AipFace # 创建百度智能云客户端client
from aip.face import base64 # 调取图片格式转换工具
import time
def main():
cap = cv.VideoCapture()
cap.open(0) # 打开摄像头
# 登陆百度智能云:
APP_ID = 'xxxxxxxx'
API_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxx'
SECRET_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# 创建自已百度云应用的客户端,账号密码确定接入的是百度云的“人脸考勤”应用
client = AipFace(APP_ID, API_KEY, SECRET_KEY)
# 创建haar分类器:
cf = cv.CascadeClassifier(
r"D:\anaconda3\envs\ml_dl\Lib\site-packages\haarcascades\haarcascade_frontalface_alt2.xml")
while cap.isOpened():
flag, frame = cap.read() # 获取摄像头截取到的图片
img = frame # 保留彩色原图frame <class 'numpy.ndarray'>
gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 灰度处理
# cv.equalizeHist(gray_img,gray_img) # 直方图均衡化:这个可以不要,处理效果更好
# 寻找特征(人脸)矩阵:
allFaceRect = cf.detectMultiScale(gray_img,) #得到的视频中出现的所有的人脸,并且保存在numpy.ndarray中(矩形向量组)
# print(type(allFaceRect[0])) # 图片中的第一张人脸# <class 'numpy.ndarray'> 没有脸的时候,返回()
# 矩形跟随人脸样本来绘图:
if allFaceRect is not ():
x,y,w,h = allFaceRect[0] # 第一张人脸标识出来
cv.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 255))
# for x, y, w, h in allFaceRect: # 标识出所有人脸
# cv.rectangle(gray_img, (x, y), (x + w, y + h), (255, 255, 255)) # 在每张图片中找到人脸并标注正方形
# 至此,找到了人脸,将人脸存放在一个容器face_img当中:
face_img = gray_img[y:y+w,x:x+h] # 将第一张人脸保存下来
check_result,img_encode = cv.imencode(".jpg", face_img) # 将找到的人脸进行编码存入缓存img_encode中。
# print(type(img_encode),img_encode) # 查看在内存中的图片的数据类型。
# 测试缓存中是否保存成功了:
# res = cv.imdecode(img_encode,1)
# cv.imshow("demo",res)
# 人脸搜索
# 1、将缓存区的图片img_encode转换为base64格式且返回处理后的图片:
base64img_send_to_aiServer = base64.b64encode(img_encode)
# 2、调用search()
# 注意:search()函数的第一个参数是字符串!需要把base64的字节序转换成字符串
res = client.search(bytes.decode(base64img_send_to_aiServer), "BASE64", "Teacher")
# print(res,type(res)) # 得到处理的结果 # 返回的是一个字典类型。
# 带参options:client.search(image, imageType, groupIdList, options) ----不用
# imageType参数的值:
# 图片类型 BASE64:图片的base64值,base64编码后的图片数据,编码后的图片大小不超过2M;---选择这个,将图片进行base64编码
# URL:图片的 URL地址( 可能由于网络等原因导致下载图片时间过长);
# FACE_TOKEN: 人脸图片的唯一标识,调用人脸检测接口时,会为每个人脸图片赋予一个唯一的FACE_TOKEN,同一张图片多次检测得到的FACE_TOKEN是同一个
# groupIdList参数: 人脸分组的序号,通过序号选择对应的组,如果要在多个组之间选择,则用逗号分隔序号
# res_json:返回的是找到的人脸的相关信息(结果),格式json:
# {
# "face_token": "fid",
# "user_list": [ 返回的所有找到的用户的列表
# {
# "group_id": "test1",
# "user_id": "u333333",
# "user_info": "Test User",
# "score": 99.3 人脸匹配度(低于80即搜索失败)
# } 每个用户都有这四个数据,多个user用逗号分隔
# ]
# }
'''
{
'error_code': 0,
'error_msg': 'SUCCESS',
'log_id': 2253051395,
'timestamp': 1667464653,
'cached': 0,
'result':
{
'face_token': '551d377ffeb0d24fed5b9dc07885203c',
'user_list': [
{
'group_id': 'Teacher',
'user_id': 'ChenBingXu',
'user_info': '',
'score': 97.605316162109
}
]
}
}
'''
if 'result' in res.keys():
print(res['result'])
name = res['result']['user_list'][0]['user_id'] #从数据中拿到返回的人脸匹配的姓名name
current_time = time.strftime("%Y.%m.%d %H:%M:%S",time.localtime(time.time())) # 获取系统时间
print(name,current_time)
cv.putText(frame,str(name)+" "+str(current_time),(0,50),cv.FONT_HERSHEY_SIMPLEX, 0.75, (255, 255, 255), 2)
# 显示灰度图
cv.imshow("demo", frame)
key_pressed = cv.waitKey(5)
# 按ESC退出:
if key_pressed == 27:
break
# 关闭摄像头:
cap.release()
# 关闭窗口:
cv.destroyAllWindows()
if __name__ == '__main__':
main() # 调用主函数
# print(cv.__file__) # 打印库位置,将haarcascade训练器样板导入
四、声明
仅供教学和个人学习爱好者作为基础入门材料使用,项目中内容不涉及任何企业及个人保密成分,不可用于商业用途,特此声明!如有盗版等问题必追究其法律责任,严禁抄袭剽窃等行为。