一、项目说明
虹软官网传送门 ,有不同平台和不同版本的sdk,有需要的根据业务下载。 此次项目支持windows和linux系统。
1.项目由go-iris框架创建(最快的go-api框架,没有之一)。
2.采用虹软最新增值4.0SDK。
3.调用虹软sdk的方法参考于 WindOSX 大佬写的低版本调用方法,在这里感谢 WindOSX 的技术支持。
4.toml管理配置文件
5.采用cgo调用C++库(gcc版本大于4.8.2),win10计算机需要装mingw64 windows版本,具体自行百度和科学上网下载。 其它的请自行百度,此处就不细细阐述了。
6.支持jwt bear token 认证方式,当然你想用auth2.0,也有对应的库进行解析。
7.此次主要针对window版本的dll,linux调用方法一样,将路径换位自己的路径即可,文件名为.so
8.使用go mod 管理项目包【我使用的是jetbrain golang】,初始化 go mod init,下载包 go mod tidy
9.go的版本,windows 最好是 >= 1.14
自动化文档支持 yaag (无需注释,只要修改yaag源码的html模板) 和 10.swager 需要在接口上写注释及参数说明,即可)
二、虹软增值版4.0新增接口及改动
新增接口:
1、激活接口
2、离线激活接口
3、获取设备信息接口
4、图片质量检测
5、更新检测人脸信息接口
6、人脸遮挡检测
7、人脸额头检测
改动的接口:(主要是新增参数)
1、人脸检测
2、提取特征值
3、特征值比较
三、开始使用
1.修改配置文件
2.拷贝dll
(1) 第一种,gcc低版本,需要将dll文件拷贝至system32下;
(2)第二种,gcc高版本,需要将dll文件拷贝至mingw64的lib下,具体看你 mingw64配置及报错路径;
(3)第三种,gcc高版本,需要将dll文件拷贝当前项目的根目录;
(4)第四种,gcc高版本,指定dll相对路径,使用cgo 引用动态库:
/*
#cgo CFLAGS: -I./include
#cgo LDFLAGS: -L${SRCDIR}/lib -larcsoft_face_engine
#include <stdlib.h>
#include "./include/merror.h"
#include "./include/asvloffscreen.h"
#include "./include/arcsoft_face_sdk.h"
*/
import "C"
此处常见问题:
(1) import "C" 之前不能有换行
(2) ${SRCDIR} 在cgo里面表示当前目录的绝对路径
(3) 出现undefined reference to XXXX,此时有两种解决问题的思路:
第一种是头文件中的方法没有被
#ifdef __cplusplus
extern "C" {
#endif
你的方法()
#ifdef __cplusplus
}
#endif
#endif
包裹。
第二种解决办法:升级gcc版本,因为版本过低导致编译错误。
3.运行 常见问题
(1) 虹软很多数据类型没有暴露出来,使用过的时候,当枚举类的数据结构作为参数传入函数时,需要加上枚举的标识 enum。
(2) 使用C头文件中的枚举,可以直接用 C.XXXXX [XXX标识枚举结构体内的枚举数据]
/************************************************************************
* 初始化引擎
************************************************************************/
MRESULT ASFInitEngine(
enum ASF_DetectMode detectMode, // [in] AF_DETECT_MODE_VIDEO 视频模式:适用于摄像头预览,视频文件识别
// AF_DETECT_MODE_IMAGE 图片模式:适用于静态图片的识别
enum ASF_OrientPriority detectFaceOrientPriority, // [in] 检测脸部的角度优先值,参考 ArcFaceCompare_OrientPriority
MInt32 detectFaceMaxNum, // [in] 最大需要检测的人脸个数
MInt32 combinedMask, // [in] 用户选择需要检测的功能组合,可单个或多个
MHandle *hEngine // [out] 初始化返回的引擎handle
);
其它修改类似。
(3) cgo中数据类型转化,如:
指针 -> (*C.MPChar)(unsafe.Pointer(&deviceInfo) 、(*C.MUInt8)(unsafe.Pointer(&imgData[0]))
变量,强制转化 -> C.MInt32(abc),当然也可以使用断言,abc.(C.MInt32)
数组,主要采用切片的方式进行转化 -> (*[10]int32)(unsafe.Pointer(asfFaceInfo.faceID))[:faceNum:faceNum]
....
其它类似
(4) 如果代码出现一串内存地址,请及时升级gcc版本。
(5) 人脸特征值需要释放内存。
(6)【特别说明】
### 四、代码结构
```bash
├─.gitee
├─.idea
├─apidoc
├─attachment
│ ├─downloads
│ └─pics
│ ├─bind
│ ├─check
│ ├─info
│ └─slice
├─auth
├─common
├─database
├─docs
├─face // 人脸sdk主要位置
│ └─__4_0
│ ├─include
│ └─lib
├─logutils
├─middleware
├─routes
├─srv
└─utils
五、代码调用实例及说明
// 获取人脸信息
func GetFaceInfos(engine *FaceEngine, transId string, width, height int, imageData []uint8, info MultiFaceInfo, img []byte, isReg, isMask int32) (
ib bool, multi []*SingleFacePropertyFourth) {
if err := engine.ProcessPro(width-width%4, height, ColorFormatBGR24, imageData, info,
EnableAge|EnableGender|EnableFace3DAngle|EnableLiveness|EnableMaskDetect|EnableFaceLandMark,
); err != nil {
logutils.Logger.Error("图片活体检测失败.", zap.String("transId", transId), zap.String("error", err.Error()))
return
}
logutils.Logger.Info("图片活体检测成功.", zap.String("transId", transId))
var faceProperty []*SingleFacePropertyFourth
// 获取年龄
ageInfo, err := engine.GetAgePro()
if err != nil {
logutils.Logger.Error("获取年龄失败.", zap.String("transId", transId), zap.String("error", err.Error()))
return false, nil
}
logutils.Logger.Info("获取年龄成功.", zap.String("transId", transId))
// 获取性别
genderInfo, err := engine.GetGenderPro()
if err != nil {
logutils.Logger.Error("获取性别失败.", zap.String("transId", transId), zap.String("error", err.Error()))
return false, nil
}
logutils.Logger.Info("获取性别成功.", zap.String("transId", transId))
// 获取3DAngle
angleInfo, err := engine.GetFace3DAnglePro()
if err != nil {
logutils.Logger.Error("获取3DAngle失败.", zap.String("transId", transId), zap.String("error", err.Error()))
return false, nil
}
logutils.Logger.Info("获取3DAngle成功.", zap.String("transId", transId))
// 获取口罩遮挡
maskInfo, err := engine.GetMaskPro()
if err != nil {
logutils.Logger.Error("获取人脸遮挡失败.", zap.String("transId", transId), zap.String("error", err.Error()))
return false, nil
}
logutils.Logger.Info("获取人脸遮挡成功.", zap.String("transId", transId))
// 额头点位
landMark, err := engine.GetFaceLandMarkInfo()
if err != nil {
logutils.Logger.Error("获取人脸额头失败.", zap.String("transId", transId), zap.String("error", err.Error()))
return false, nil
}
logutils.Logger.Info("获取人脸额头成功.", zap.String("transId", transId))
//获取活体值
liveInfo, err := engine.GetLivenessScorePro()
if err != nil {
logutils.Logger.Error("获取活体值失败.", zap.String("transId", transId), zap.String("error", err.Error()))
return false, nil
}
logutils.Logger.Info("获取活体值成功.", zap.String("transId", transId))
maxInt := GetMaxFace(info.FaceRect)
for k, v := range info.FaceRect {
property := new(SingleFacePropertyFourth)
property.FaceRect = v
property.FaceOrient = info.FaceOrient[k]
property.Age = ageInfo.AgeArray[k]
property.Gender = genderInfo.GenderArray[k]
property.GenderType = ExplainAge(genderInfo.GenderArray[k])
property.Face3DAngle = angleInfo
property.MaskInfo = maskInfo
property.LandMarkInfo = landMark
property.Live = liveInfo.IsLive[k]
// 是否带眼镜
property.WearGlasses = info.WearGlasses[k]
property.LeftEyeClosed = info.LeftEyeClosed[k]
property.RightEyeClosed = info.RightEyeClosed[k]
// 提取人脸图片并以base64返回
resImage := CutImage(img, v)
// 转存提取的人脸
SaveImage("./attachment/pics/slice/"+transId+"/", "face_"+transId+"_"+strconv.Itoa(k)+".jpg", resImage, transId)
property.FaceImage = base64.StdEncoding.EncodeToString(resImage)
// 提取活体值
//pw,ph,imageD := ImageConvert(resImage,transId)
//liveInfo := GetLive(transId,pw,ph,imageD)
//if liveInfo != nil{
// property.Live = liveInfo.IsLive
// property.LiveType = ExplainLive(liveInfo.IsLive)
//}
// 提取人脸特征
sing := SingleFaceInfo{v, info.FaceOrient[k], info.FaceDataInfoList[k]}
_, feature := FeatureExtractUtil(engine, transId, width, height, imageData, sing, uint32(isReg), uint32(isMask))
property.Feature = feature
feature.Release()
if maxInt == k {
property.Max = 1
}
faceProperty = append(faceProperty, property)
}
return true, faceProperty
}
六、关于一些配置说明
1、本项目采用go-iris框架搭建完成。
2、新增接口主要新在routes/route.go中添加接口定义及方法,支持分级路由,多级路由,支持中间件验证,然后实现对应的方法即可。
3、iris 取出参数非常方便,支持 query、params、json、xml等格式,非常方便取出参数。
4、中间件使用jwt bearer token的方式验证,支持api调用次数等配置。
5、配置文件中有几个参数说明下:
# 是否是测试模式
test = true
# 同一个请求是否可以请求多次,项目中有配置api的使用总次数及统计使用次数(当然用的方法比较原始)
repeat = true
# 授权 如果 authorization = 1 则token请求的queryparams里, authorization= 0 则放Header里
authorization = 1
七、打包
在当前目录下运行 linux.bat即可
八、运行效果
九、开源说明
- 开源不易,请使用代码时,注明引用,谢谢~
了解更多人脸识别产品相关内容请到虹软视觉开放平台哦