net.gdface.cassdk.CasAndroidArmBridge Maven / Gradle / Ivy
package net.gdface.cassdk;
import net.gdface.license.GfLicenseProvider;
import net.gdface.utils.Judge;
import net.gdface.utils.SampleLog;
import static net.gdface.cassdk.CasAndroidConfigProvider.*;
import java.util.Iterator;
import java.util.ServiceLoader;
/**
* CASSDK for android/arm JNI 接口
* 应用层可以通过SPI加载机制提供授权信息,
* 也可以通过{@link #setLicenseKey(String)},{@link #setLicenseCode(String)}方法提供授权信息
* 此类为非线程安全的,不可多线程共享调用,需要在外部进一步封装实现线程安全
* @author guyadong
*
*/
public class CasAndroidArmBridge {
/**
* 应用层提供的{@link CasAndroidConfigProvider}接口实例,未提供则初始化为{@link DefaultCasAndroidConfig}实例
*/
public static final CasAndroidConfigProvider CONFIG = getConfigProvider();
final long[] detectHandle = new long[1];
final long[] featureHandle = new long[1];
/**
* 初始化状态
*/
private SdkStatus status=SdkStatus.SDK_UNINITIALIZED;
static {
try {
// 加载算法动态库
System.loadLibrary("FS_AndroidFaceSDK");
} catch (Exception e) {
SampleLog.log(e.getMessage());
throw new ExceptionInInitializerError(e);
}
}
CasAndroidArmBridge() {
}
/**
* SPI(Service Provider Interface)机制加载 {@link GfLicenseProvider}实例,
* 没有找到返回{@link DefaultCasAndroidConfig}实例
* @return
*/
private static CasAndroidConfigProvider getConfigProvider() {
ServiceLoader providers = ServiceLoader.load(CasAndroidConfigProvider.class);
Iterator itor = providers.iterator();
if(!itor.hasNext()){
return new DefaultCasAndroidConfig();
}
return itor.next();
}
/**
* 返回当前SDK初始化状态
* @return
*/
SdkStatus getStatus() {
return status;
}
/**
* 如果input非0结尾则添加'\0'返回,否则返回input
* @param input
* @return
*/
private static String zeroEnd(String input){
if(input == null){
return null;
}
if(input.endsWith("\0")){
return input;
}
return input+"\0";
}
/**
* 执行SDK(检测模块)初始化
* @param licenseKey 授权关键字
* @param licenseCode 授权码
* @param instance
* @return 初始化状态
*/
static SdkStatus fdInit(String licenseKey, String licenseCode,CasAndroidArmBridge 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(),
CONFIG.getProcessMinl(),
CONFIG.getProcessMaxl(),
CONFIG.getDetectThreshold(),
instance.detectHandle);
return SdkStatus.jniCode(fdFlag);
}
/**
* 执行SDK(识别模块)初始化
* @param licenseKey 授权关键字
* @param licenseCode 授权码
* @return 初始化状态
*/
private static SdkStatus ffInit(String licenseKey, String licenseCode,CasAndroidArmBridge instance) {
if(SdkStatus.SDK_INIT_OK == instance.status){
return instance.status;
}
licenseCode = zeroEnd(licenseCode);
String szFilePath = "\0";
String szCompanyNames = zeroEnd(licenseKey);
int ffFlag = FFInit(licenseCode.getBytes(),
szCompanyNames.getBytes(),
szFilePath.getBytes(),
instance.featureHandle);
return SdkStatus.jniCode(ffFlag);
}
/**
* 执行SDK(检测模块,识别模块)初始化,初始化失败则抛出异常
* @param licenseKey 授权关键字
* @param licenseCode 授权码
* @throws SdkInitException
*/
private void sdkInit(String licenseKey, String licenseCode) throws SdkInitException {
if(SdkStatus.SDK_INIT_OK == status){
return;
}
SdkStatus fdStatus = SdkStatus.SDK_UNINITIALIZED;
SdkStatus ffStatus = SdkStatus.SDK_UNINITIALIZED;
try{
fdStatus = fdInit(licenseKey, licenseCode, this);
if(fdStatus !=SdkStatus.SDK_INIT_OK){
status = fdStatus;
SampleLog.log("detect module: {}", status.msg);
throw new SdkInitException(status);
}
ffStatus = ffInit(licenseKey, licenseCode, this);
if(ffStatus !=SdkStatus.SDK_INIT_OK){
status = ffStatus;
SampleLog.log("feature 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]);
}
if(ffStatus !=SdkStatus.SDK_INIT_OK){
FFDestroy(featureHandle[0]);
}
}
}
}
/**
* SDK初始化
* 初始化前{@link #licenseKey}和{@link licenseCode}必须已经初始化
* @return
* @throws SdkInitException
*/
CasAndroidArmBridge init() throws SdkInitException{
String licenseKey = CasLicenseManager.getInstance().getLicenseKey();
String licenseCode = CasLicenseManager.getInstance().getLicenseCode();
if(Judge.isEmpty(licenseKey)){
throw new SdkInitException("EMPTY licenseKey,must call setLicenseKey() firstly");
}
if(Judge.isEmpty(licenseCode)){
throw new SdkInitException("EMPTY licenseCode,must call setLicenseCode() firstly");
}
sdkInit(licenseKey, licenseCode);
return this;
}
/**
* 人脸识别SDK资源释放
* @see #FDDestroy(long)
* @see #FFDestroy(long)
*/
void destroy() {
if(SdkStatus.SDK_INIT_OK == status){
status = SdkStatus.SDK_UNINITIALIZED;
FDDestroy(detectHandle[0]);
FFDestroy(featureHandle[0]);
}
}
public int detect(byte[] BGR, int width, int height, double[] rect){
int ret = FDDetect(detectHandle[0], BGR, width, height, rect);
if(ret<0){
throw new SdkRuntimeException(SdkStatus.jniCode(ret));
}
return ret;
}
public double[] feaExtract(byte[] BGR, int width, int height, double[] rect){
double[] buffer = new double[FEATURE_LEN];
int ret = FFFeaExtract(featureHandle[0], BGR, width, height, buffer, rect);
if(ret<0){
throw new SdkRuntimeException(SdkStatus.jniCode(ret));
}
return buffer;
}
public byte[] feaExtractByte(byte[] BGR, int width, int height, double[] rect){
byte[] buffer = new byte[FEATURE_BYTES];
int ret = FFFeaExtractByte(featureHandle[0], BGR, width, height, buffer, rect);
if(ret<0){
throw new SdkRuntimeException(SdkStatus.jniCode(ret));
}
return buffer;
}
/**
* 获取设备加密信息
* @param encryptionSerial [out]获取的设备加密信息
* @param licenseKey 授权关键字
* @return 成功(>0 加密信息长度)或错误代码(< 0)
*/
static native int FSGetDevicesSerial(byte[] encryptionSerial, byte[] licenseKey);
/**
* 人脸检测初始化函数
* @param licenseCode 授权码
* @param licenseKey 授权关键字
* @param path 授权码本地路径
* @param ProcessMinL 检测时,短边缩放 建议 360
* @param ProcessMaxL 检测时,长边缩放尺寸 建议 640
* @param detectThresld 检测阈值 建议 0.7
* @param handle 结构体
* @return 成功(0)或错误代码(< 0),see also {@link SdkStatus}
*/
private static native int FDInit(byte[] licenseCode, byte[] licenseKey, byte[] path, int ProcessMinL, int ProcessMaxL, double detectThresld, long[] handle);
/**
* 人脸检测模块资源释放函数
* @param handle
*/
static native void FDDestroy(long handle);
/**
* 对输入图像进行人脸检测,检测结果由rect返回,
* 检测到人脸返回>0的人脸个数
* @param handle
* @param BGR 待检测图像BGR格式
* @param width 图像宽度
* @param height 图像调试
* @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, double[] rect);
/**
* @return 人脸检测模块版本
*/
public static native String FDgetVersion();
/**
* 人脸识别初始化函数
* @param licenseCode 授权码
* @param licenseKey 授权关键字
* @param path 授权码本地路径
* @param handle 句柄
* @return 成功(0)或错误代码(< 0),see also {@link SdkStatus}
*/
private static native int FFInit(byte[] licenseCode, byte[] licenseKey, byte[] path, long[] handle);
/**
* 人脸识别模块资源释放函数
* @param handle 句柄
*/
private static native void FFDestroy(long handle);
/**
* 对输入图像中检测到的人脸提取特征
* @param handle 操作句柄
* @param BGR 待检测图像BGR格式
* @param width 图像宽度
* @param height 图像高度
* @param fea [out] 人脸特征 空间在外部申请,长度512
* @param rect 人脸位置及关键点信息 由人脸检测SDK 产生,参见 {@link #FDDetect(long, byte[], int, int, double[])}
* @return 成功(0)或错误代码(< 0),see also {@link SdkStatus}
*/
private static native int FFFeaExtract(long handle, byte[] BGR, int width, int height, double[] fea, double[] rect);
/**
* 人脸相似度比对函数
* 对人脸特征feaA和feaB进行相似度比对,返回相似度结果
* @param feaA
* @param feaB
* @return 相似度(0.0~1.0)
*/
public static native double FFSimilarity(double[] feaA, double[] feaB);
/**
* 对输入图像中检测到的人脸提取特征
* @param handle 操作句柄
* @param BGR 待检测图像BGR格式
* @param width 图像宽度
* @param height 图像高度
* @param fea [out] 人脸特征 空间在外部申请,长度4096
* @param rect 人脸位置及关键点信息 由人脸检测SDK 产生,参见 {@link #FDDetect(long, byte[], int, int, double[])}
* @return 成功(0)或错误代码(< 0),see also {@link SdkStatus}
*/
private static native int FFFeaExtractByte(long handle, byte[] BGR, int width, int height, byte[] fea, double[] rect);
/**
* 人脸相似度比对函数
* 对人脸特征feaA和feaB进行相似度比对,返回相似度结果
* @param feaA
* @param feaB
* @return 相似度(0.0~1.0)
*/
public static native double FFSimilarityByte(byte[] feaA, byte[] feaB);
/**
* @return 人脸识别模块版本
*/
public static native String FFgetVersion();
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy