ArcSoft4.0_Go

518 阅读5分钟

一、项目说明

虹软官网传送门 ,有不同平台和不同版本的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即可

八、运行效果

在这里插入图片描述 在这里插入图片描述

九、开源说明

  • 开源不易,请使用代码时,注明引用,谢谢~

了解更多人脸识别产品相关内容请到虹软视觉开放平台