net.facelib.mtfsdk.DetectAndroidArmBridge Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mtfsdk-android-common Show documentation
Show all versions of mtfsdk-android-common Show documentation
mtfsdk common(detection included) for android
package net.facelib.mtfsdk;
import net.facelib.jni.BaseJniBridge;
import net.facelib.jni.SdkInitException;
import net.facelib.jni.SdkRuntime.RuntimeParam;
import net.facelib.jni.SdkRuntimeException;
import net.facelib.jni.SdkStatus;
import net.gdface.license.LicenseManager;
import net.gdface.utils.Assert;
import net.gdface.utils.SimpleLog;
/**
* MTFSDK detect module for android/arm JNI 接口
* 此类为非线程安全的,不可多线程共享调用,需要在外部进一步封装实现线程安全
* @author guyadong
*
*/
public class DetectAndroidArmBridge extends BaseJniBridge{
static final LicenseManager DEFAULT_LICENSE_MANAGER = new DetectLicenseManager();
/** 活体检测的授权管理器实例,NOTE:与父类不同 */
final long[] detectHandle = new long[1];
/**
* 初始化状态
*/
private SdkStatus status=SdkStatus.SDK_UNINITIALIZED;
static {
try {
// 加载算法动态库
System.loadLibrary("FS_AndroidDetectSDK");
} catch (Exception e) {
SimpleLog.log(e.getMessage());
throw new ExceptionInInitializerError(e);
}
}
public DetectAndroidArmBridge() {
}
@Override
protected SdkStatus getStatus() {
return status;
}
/**
* 执行SDK(检测模块)初始化
* @param licenseKey 授权关键字
* @param licenseCode 授权码
* @param instance
* @return 初始化状态
*/
static SdkStatus fdInit(String licenseKey, String licenseCode,DetectAndroidArmBridge instance) {
if(SdkStatus.SDK_INIT_OK == instance.status){
return instance.status;
}
licenseCode = zeroEnd(licenseCode);
String szFilePath = "\0";
String szCompanyNames = zeroEnd(licenseKey);
// 检测模块初始化
int fdFlag = FDInit(licenseCode.getBytes(),
szCompanyNames.getBytes(),
szFilePath.getBytes(),
szFilePath,
instance.detectHandle);
return SdkStatus.jniCode(fdFlag);
}
@Override
protected void sdkInit(String licenseKey, String licenseCode) throws SdkInitException {
if(SdkStatus.SDK_INIT_OK == status){
return;
}
SdkStatus fdStatus = SdkStatus.SDK_UNINITIALIZED;
try{
fdStatus = fdInit(licenseKey, licenseCode, this);
if(fdStatus !=SdkStatus.SDK_INIT_OK){
status = fdStatus;
SimpleLog.log("detect module: {}", status.msg);
throw new SdkInitException(status);
}
// 检测模块和识别模块都初始化成功则置状态为成功
status = SdkStatus.SDK_INIT_OK;
}finally {
// 如果没有完全初始化成功,则destroy已经初始化模块
if(status != SdkStatus.SDK_INIT_OK){
if(fdStatus !=SdkStatus.SDK_INIT_OK){
FDDestroy(detectHandle[0]);
}
}
}
}
@Override
protected void destroy() {
if(SdkStatus.SDK_INIT_OK == status){
status = SdkStatus.SDK_UNINITIALIZED;
FDDestroy(detectHandle[0]);
}
}
@Override
protected LicenseManager licenseManager() {
return getLicenseManager(DEFAULT_LICENSE_MANAGER);
}
////////////////////////////////////
/**
* 对输入图像进行人脸检测,检测结果由rect返回,
* 检测到人脸返回>0的人脸个数,
* 返回的是21个元素的脸部信息 可配合FDGetDetectInfo拿到人脸角度 人脸数量<=3
* @param BGR 待检测图像BGR格式
* @param width 图像宽度
* @param height 图像高度
* @param detectMod 0:用于检测图片,1:用于视频的循环检测
* @param rect 用于返回人脸位置及关键点信息
* @return 检测到的人脸个数(>0)或者错误代码(< 0),see also {@link SdkStatus}
* @see #FDDetect(long, byte[], int, int, int, double[])
*/
public int detect(byte[] BGR, int width, int height, int detectMod, double[] rect){
int ret = FDDetect(detectHandle[0], BGR, width, height, detectMod, rect);
if(ret<0){
throw new SdkRuntimeException(SdkStatus.jniCode(ret));
}
return ret;
}
/**
* 对输入图像进行人脸检测返回最大人脸,检测结果由rect返回,
* @param BGR 待检测图像BGR格式
* @param width 图像宽度
* @param height 图像高度
* @param detectMod 0:用于检测图片,1:用于视频的循环检测
* @param rect 用于返回人脸位置及关键点信息
* @return 检测到的人脸个数1,或者错误代码(< 0),see also {@link SdkStatus}
* @see #FDDetectMaxFace(long, byte[], int, int, int, double[])
*/
public int detectMaxFace(byte[] BGR, int width, int height, int detectMod, double[] rect){
int ret = FDDetectMaxFace(detectHandle[0], BGR, width, height, detectMod, rect);
if(ret<0){
throw new SdkRuntimeException(SdkStatus.jniCode(ret));
}
return ret;
}
public int facePosInterrelate(int faceNums, double rectRate, double[] faceRect, double[] faceRectInfo){
int ret = FSFacePosInterrelate(detectHandle[0], faceNums, rectRate,faceRect, faceRectInfo);
if(ret<0){
throw new SdkRuntimeException(SdkStatus.jniCode(ret));
}
return ret;
}
public int setFacePosStatus(int facePos, int flag){
int ret = FSSetFacePosStatus(detectHandle[0], facePos, flag);
if(ret<0){
throw new SdkRuntimeException(SdkStatus.jniCode(ret));
}
return ret;
}
/**
* 人脸检测初始化函数
* @param licenseCode 授权码
* @param licenseKey 授权关键字
* @param path 授权码文件本地路径
* @param faceDetectionModelPath_ 模型路径
* @param handle [out]结构体
* @return 成功(0)或错误代码(< 0),see also {@link SdkStatus}
*/
private static native int FDInit(byte[] licenseCode, byte[] licenseKey, byte[] path, String faceDetectionModelPath_, long[] handle);
/**
* 人脸检测模块资源释放函数
* @param handle
*/
static native void FDDestroy(long handle);
/**
* 对输入图像进行人脸检测,检测结果由rect返回,
* 检测到人脸返回>0的人脸个数,
* 返回的是21个元素的脸部信息 可配合FDGetDetectInfo拿到人脸角度 人脸数量<=3
* @param handle
* @param BGR 待检测图像BGR格式
* @param width 图像宽度
* @param height 图像调试
* @param detectMod 0:用于检测图片,1:用于视频的循环检测
* @param rect 用于返回人脸位置及关键点信 息,大小在外部申请 (61 * MAX_FACE_COUNT)
* rect格式:61 个数据为一组,依次为 人脸坐标(left, top, width, height)
* 人脸质量 人脸姿态(roll yaw pitch) 人脸清晰度 人脸亮度 人脸关键点(25*2)
* 人脸检测框置信度
* @return 检测到的人脸个数(>0)或者错误代码(< 0),see also {@link SdkStatus}
*/
private static native int FDDetect(long handle, byte[] BGR, int width, int height, int detectMod, double[] rect);
/**
* 对输入图像进行人脸检测返回最大人脸,检测结果由rect返回,
* 返回的是21个元素的脸部信息 可配合FDGetDetectInfo拿到人脸角度 人脸数量 = 1
* @param handle
* @param BGR 待检测图像BGR格式
* @param width 图像宽度
* @param height 图像高度
* @param detectMod 0:用于检测图片,1:用于视频的循环检测
* @param rect 用于返回人脸位置及关键点信 息,大小在外部申请 (61 * MAX_FACE_COUNT)
* rect格式:61 个数据为一组,依次为 人脸坐标(left, top, width, height)
* 人脸质量 人脸姿态(roll yaw pitch) 人脸清晰度 人脸亮度 人脸关键点(25*2)
* 人脸检测框置信度
* @return 检测到的人脸个数1,或者错误代码(< 0),see also {@link SdkStatus}
*/
private static native int FDDetectMaxFace(long handle, byte[] BGR, int width, int height, int detectMod, double[] rect);
private static native int FDSetMinFaceSize(long handle, int minSize);
private static native int FDSetThreadsNumber(long handle, int threadsNumber);
/**
* @return 人脸检测模块版本
*/
public static native String FDgetVersion();
/**
* 位置关联
* 在人脸检测函数后用到,无论有无检测到人脸,均需要调用,从属于检测系列
* @param handle
* @param faceNums 人脸个数
* @param rectRate
* @param faceRect 人脸信息(人脸检测数据rect) 21个元素
* @param faceRectInfo 返回的标记,最后一个元素为是否成功比对的标志,其他为人脸信息
* @return 位置关联总个数
*/
private static native int FSFacePosInterrelate(long handle, int faceNums, double rectRate ,double[] faceRect, double[] faceRectInfo);
/**
* 人脸标记(成功后)
*人脸识别成功后调用,告知该人脸已经识别成功,不用重复提取特征进行特征提取
* @param facePos 人脸数组位置下班
* @param flag 标记成功 1
* @return 0成功 不为0失败
*/
private static native int FSSetFacePosStatus(long handle, int facePos, int flag);
@Override
public DetectAndroidArmBridge setRuntimeParam(RuntimeParam name, Object value) throws SdkRuntimeException {
Assert.notNull(name, "name");
switch (name) {
case detectThreadNumber:
int detectThreadNumber = value != null ? (Integer) value : MtfsdkConstant.DEFAULT_DETECT_THREAD_NUMBER;
if(detectThreadNumber > 0){
int code = FDSetThreadsNumber(detectHandle[0], detectThreadNumber);
if(code != 0){
status = SdkStatus.jniCode(code);
throw new SdkRuntimeException(status);
}
}
break;
case minFaceSize:
int minFaceSize = value != null ? (Integer) value : MtfsdkConstant.DEFAULT_DETECT_MIN_FACE_SIZE;
if(minFaceSize >= 0){
int code = FDSetMinFaceSize(detectHandle[0], minFaceSize);
if(code != 0){
status = SdkStatus.jniCode(code);
throw new SdkRuntimeException(status);
}
}
break;
default:
throw new IllegalArgumentException(SimpleLog.logString("INVALID parameter name: {}",name));
}
return this;
}
}