前言:
虹软sdk3.0是目前用过的最方便,效果最好的且免费的离线人脸识别SDK。
提供的编程语音没有python,有大佬用c++代码接口转成python调用的,
我在此基础上完善了一些功能,能够实现高精度多人脸实时人脸识别。
并提供了年龄/性别识别,活体检测,人脸3D角度等功能。
曾在2018年使用过虹软SDK1.0并写了博客 阅读链接
参考代码
这里参考了大佬的代码 我在他基础上再做实时人脸识别的开发。
下面是原文链接
https://my.oschina.net/u/4584428/blog/4712244
https://gitee.com/shellcoder/ArcFace-python
下面教程只列出来重点部分 讲解
其余部分 以及整个流程 可以自己看代码理解 并不是很麻烦
官方文档也给到比较详细
使用方法 :
- 将下载好的sdk3.0中的动态链接库放入到lib文件夹中
- demo_cam文件中添加自己的 APP_ID 和SDK_key
- 注册图片在文件夹asserts中 文件名就是这个人的信息
我完善后的项目GitHub 链接
获取SDK
- 进入虹软官网 链接
登陆或者注册账号。 - 进入 链接 下载虹软SDK3.0
- 点击免费获取 选择平台 版本 语言 和应用(自己创建)
- 确认之后即可 下载相关SDK
- 关于APP_ID 和SDK_key
上面的APP_ID 和SDK_key 要写入到代码中,是用于激活的。
第一次运行代码需要联网,因为会做激活操作,首次运行激活成功后会得到一个ArcFace64.dat文件,当有此文件以后,可以不用执行激活代码。
个人认证用户,每年免费激活限制 100 台终端。 - SDK目录说明
人脸检测和人脸识别
把c++的接口调出来python使用
-
激活 调用函数ASFOnlineActivation
#激活接口,首次需联网激活
res = ASFOnlineActivation(APPID, SDKKey)
返回res 为状态码 如果是0或90114则为成功激活
#获取激活文件信息
res,activeFileInfo = ASFGetActiveFileInfo()
能够返回SDK版本以及本机信息等 同样res为状态码 0位正确
-
初始化
首先获取人脸识别引擎
ArcFace() 创建一个对象初始化接口
face_engine.ASFInitEngine(ASF_DETECT_MODE_IMAGE,ASF_OP_0_ONLY,30,10,5)
- detectMode: VIDEO 模式/IMAGE 模式 ,VIDEO 模式:处理连续帧的图像数据 IMAGE 模式:处理单张的图像数据
- detectFaceOrientPriority: 人脸检测角度,推荐单一角度检测;IMAGE 模式下不支持全角度(ASF_OP_0_HIGHER_EXT)检测
- detectFaceScaleVal: 识别的最小人脸比例(图片长边与人脸框长边的比值),VIDEO 模式取值范围[2,32],推荐值为 16 ,IMAGE 模式取值范围[2,32],推荐值为 30
- detectFaceMaxNum: 最大需要检测的人脸个数,取值范围[1,50]
- combinedMask: 需要启用的功能组合,可多选 人脸检测为1 人脸特征为4 年龄检测8 性别检测16 RGB活体128 红外活体1024 选择多个功能时加起来就可以了。(比如上面我使用的是人脸识别 需要人脸检测和人脸特征 就是1+4 =5)
-
预处理
需要注意的是 输入端图片宽度必须是4的倍数
这个时候就需要对输入的图片尺寸进行处理 否则会报错def LoadImg(imagePath): """ 将输入图片长和 宽都变成4的倍数 符合要求 """ img = cv2.imdecode(np.fromfile(imagePath,dtype=np.uint8),-1) # 读取中文命名的图片 #img = cv2.imread(imagePath) sp = img.shape img = cv2.resize(img, (sp[1]//4*4, sp[0]//4*4)) return img
输入时图片的路径 输出是处理好的已经读取的图片
-
检测人脸 并 提取人脸特征
img1 = cv2.imread ("asserts/1.jpg") #检测第一张图中的人脸 res,detectedFaces1 = face_engine.ASFDetectFaces(img1) #print(detectedFaces1) #图片中人脸信息 if res==MOK: single_detected_face1 = ASF_SingleFaceInfo() single_detected_face1.faceRect = detectedFaces1.faceRect[0] single_detected_face1.faceOrient = detectedFaces1.faceOrient[0] res ,face_feature1= face_engine.ASFFaceFeatureExtract(img1,single_detected_face1) if (res!=MOK): print ("ASFFaceFeatureExtract 1 fail: {}".format(res)) else: print("ASFDetectFaces 1 fail: {}".format(res))
使用函数
face_engine.ASFDetectFaces()
检测人脸
获取到图片中的人脸坐标(list) 人脸角度(list) 人脸个数(int)使用
ASFFaceFeatureExtract()
提取人脸特征
获取到特征 用于人脸比对 -
人脸比对
res,score = face_engine.ASFFaceFeatureCompare(face_feature1,face_feature2)
输入的是两个人脸的人脸特征 返回的第一个是状态码 第二个是相似度
普通照片 阈值0.8即可
- 年龄 性别等其他
在初始化引擎时指定的功能内 即是加上 需要添加的功能
获取年龄
res = face_engine.ASFProcess(img1,detectedFaces1,processMask)
print(processMask)
if res == MOK:
# 获取年龄
res,ageInfo = face_engine.ASFGetAge()
ageInfo即是检测到的年龄。
其他功能获取方式类似 可以参考代码
实时人脸识别
这里面使用到了官方提到的faceID即是 在判断同一个人的情况下就不再多次进行人脸特征提取进行人脸识别
这样就能减少运行时间。
选取的一张运行截图
但是如果第一章faceID判断失误会导致后面的全部判断错。为了防止这种情况发生,在代码里面进行了判断 如果faceID连续出现了5帧 则将进行重新识别。
else
多线程人脸识别还没搞懂 还没尝试怎么做
如果文章有帮助到你,关注 点赞 收藏!