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
The newest version!
package net.facelib.mtfsdk;
import static net.facelib.jni.BridgeLog.BRIDEG_LOGGER;
import java.util.Arrays;
import com.gitee.l0km.com4j.base.ConditionChecks;
import com.gitee.l0km.com4j.base.SimpleLog;
import com.gitee.l0km.ximage.MatType;
import net.facelib.akcore.LicenseManager;
import net.facelib.jni.SdkStatus;
import net.facelib.sdk.ImageSupport;
import net.facelib.jni.BaseJniBridge;
import net.facelib.jni.FacelibRuntimeParam;
import net.facelib.jni.SdkInitException;
import net.facelib.jni.SdkRuntimeException;
/**
* MTFSDK detect module for android/arm JNI 接口
* 此类为非线程安全的,不可多线程共享调用,需要在外部进一步封装实现线程安全
* @author guyadong
*
*/
public class DetectAndroidArmBridge extends BaseJniBridge{
/** 活体检测的授权管理器实例,NOTE:与父类不同 */
private final long[] detectHandle = new long[]{-1};
/**
* 初始化状态
*/
private volatile SdkStatus status =SdkStatus.SDK_UNINITIALIZED;
static {
try {
BRIDEG_LOGGER.log("loadLibrary FS_AndroidDetectSDK");
// 加载算法动态库
System.loadLibrary("FS_AndroidDetectSDK");
} catch (Exception e) {
BRIDEG_LOGGER.log(e.getMessage());
throw new ExceptionInInitializerError(e);
}
}
public DetectAndroidArmBridge() {
}
@Override
public SdkStatus getStatus() {
return status;
}
@Override
protected void sdkInit(String licenseFile, String licenseKey, String licenseCode) throws SdkInitException {
if(SdkStatus.SDK_INIT_OK == status){
return;
}
try{
// 检测模块初始化,不需要授权忽略所有输入的授权参数
int fdFlag = FDInit(
"\0".getBytes(),
"\0".getBytes(),
"\0".getBytes(),
"\0",
detectHandle);
BRIDEG_LOGGER.log("FDInit detectHandle: [{}] fdFlag={}",detectHandle[0],fdFlag);
status = SdkStatus.jniCode(fdFlag);
BRIDEG_LOGGER.log("detect module: {}", this);
ConditionChecks.checkTrue(status == SdkStatus.SDK_INIT_OK, SdkInitException.class, status);
}finally {
// 如果没有初始化成功,则销毁已经初始化模块
if(status !=SdkStatus.SDK_INIT_OK){
BRIDEG_LOGGER.log("FDDestroy caused by init fail {}",this);
FDDestroy(detectHandle[0]);
}
}
}
@Override
protected void sdkUninit() {
if(detectHandle[0] >= 0){
BRIDEG_LOGGER.log("FDDestroy {}",this);
status = SdkStatus.SDK_UNINITIALIZED;
FDDestroy(detectHandle[0]);
detectHandle[0] = -1;
}
}
@Override
protected LicenseManager licenseManager() {
return null;
}
////////////////////////////////////
/**
* 对输入图像进行人脸检测,检测结果由rect返回,
* 检测到人脸返回>0的人脸个数,
* 返回的是21个元素的脸部信息 可配合FDGetDetectInfo拿到人脸角度 人脸数量<=3
* @param matType 图像矩阵类型
* @param matData 图像矩阵
* @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(MatType matType, byte[] matData, int width, int height, int detectMod, double[] rect){
// BRIDEG_LOGGER.log("before FDDetect {} width={},height={}",this,width, height);
byte[] bgr = ImageSupport.toBGR(matType, matData, width, height);
int ret = FDDetect(detectHandle[0], bgr, width, height, detectMod, rect);
if(ret<0){
SdkStatus code = SdkStatus.jniCode(ret);
BRIDEG_LOGGER.log("FDDetect code={} {}",code,this);
throw new SdkRuntimeException(code);
}
return ret;
}
/**
* 对输入图像进行人脸检测返回最大人脸,检测结果由rect返回,
* @param matType 图像矩阵类型
* @param matData 图像矩阵
* @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(MatType matType, byte[] matData, int width, int height, int detectMod, double[] rect){
// BRIDEG_LOGGER.log("before FDDetectMaxFace {} width={},height={}",this,width, height);
byte[] bgr = ImageSupport.toBGR(matType, matData, width, height);
int ret = FDDetectMaxFace(detectHandle[0], bgr, width, height, detectMod, rect);
if(ret<0){
SdkStatus code = SdkStatus.jniCode(ret);
BRIDEG_LOGGER.log("FDDetectMaxFace code={} {}",code,this);
throw new SdkRuntimeException(code);
}
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){
SdkStatus code = SdkStatus.jniCode(ret);
BRIDEG_LOGGER.log("FSFacePosInterrelate code={} {}",code,this);
throw new SdkRuntimeException(code);
}
return ret;
}
public int setFacePosStatus(int facePos, int flag){
int ret = FSSetFacePosStatus(detectHandle[0], facePos, flag);
if(ret<0){
SdkStatus code = SdkStatus.jniCode(ret);
BRIDEG_LOGGER.log("FSSetFacePosStatus code={} {}",code,this);
throw new SdkRuntimeException(code);
}
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(String name, Object value) throws SdkRuntimeException {
FacelibRuntimeParam r = FacelibRuntimeParam.valueOf(name);
switch (r) {
case detectThreadNumber:
int detectThreadNumber = value != null ? (Integer) value : MtfsdkConstant.DEFAULT_DETECT_THREAD_NUMBER;
if(detectThreadNumber > 0){
int ret = FDSetThreadsNumber(detectHandle[0], detectThreadNumber);
if(ret != 0){
SdkStatus code = SdkStatus.jniCode(ret);
BRIDEG_LOGGER.log("FDSetThreadsNumber code={} {}",code,this);
throw new SdkRuntimeException(code);
}
}
break;
case minFaceSize:
int minFaceSize = value != null ? (Integer) value : MtfsdkConstant.DEFAULT_DETECT_MIN_FACE_SIZE;
if(minFaceSize >= 0){
int ret = FDSetMinFaceSize(detectHandle[0], minFaceSize);
if(ret != 0){
SdkStatus code = SdkStatus.jniCode(ret);
BRIDEG_LOGGER.log("FDSetMinFaceSize code={} {}",code,this);
throw new SdkRuntimeException(code);
}
}
break;
default:
throw new IllegalArgumentException(SimpleLog.logString("INVALID parameter name: {}",name));
}
return this;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("DetectAndroidArmBridge [detectHandle=");
builder.append(Arrays.toString(detectHandle));
builder.append(", status=");
builder.append(status);
builder.append("]");
return builder.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy