@superpigy
2023-07-25T12:57:26.000000Z
字数 5692
阅读 701
sdk集成
应用权限
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
build.gradle(:project)
maven { url 'https://jihulab.com/hamuna-sdk/aisdk/-/raw/main' }
build.gradle(:app)
android{
packagingOptions {
exclude 'lib/armeabi-v7a/libRSSupport.so'
exclude 'lib/arm64-v8a/librsjni.so'
exclude 'lib/armeabi-v7a/librsjni.so'
exclude 'lib/arm64-v8a/libRSSupport.so'
exclude 'lib/x86/libRSSupport.so'
exclude 'lib/x86/librsjni.so'
exclude 'META-INF/atomicfu.kotlin_module'
exclude 'lib/x86_64/libtensorflowlite_jni.so'
exclude 'META-INF/library_release.kotlin_module'
}
configurations {
all*.exclude group: 'com.google.guava', module: 'listenablefuture'
}
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
defaultConfig {
...
minSdkVersion 24
renderscriptTargetApi 18
renderscriptSupportModeEnabled true
ndk { abiFilters "armeabi-v7a" }
}
dependencies{
implementation "com.hamuna.ai:android-sdk:1.0.0.41.0"
}
}
Project Bulid Gradle
ext {
var = '4.0.1'
}
buildscript {
repositories {
mavenCentral()
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://jitpack.io' }
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath 'com.google.ar.sceneform:plugin:1.6.0'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61"
}
}
allprojects {
repositories {
mavenCentral()
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter' }
maven { url 'https://jitpack.io' }
maven {
url "https://gradle.finogeeks.club/repository/applet/"
credentials {
username "applet"
password "123321"
}
}
}
configurations.all {
resolutionStrategy {
force 'com.google.android.gms:play-services-gcm:16.1.0'
force 'com.google.android.gms:play-services-basement:16.2.0'
force 'com.google.android.gms:play-services-auth:16.0.1'
force 'com.google.firebase:firebase-messaging:18.0.0'
force 'com.google.firebase:firebase-common:17.0.0'
force 'com.google.firebase:firebase-iid:18.0.0'
force 'com.google.android.gms:play-services-stats:16.0.1'
force 'com.google.android.gms:play-services-base:16.0.1'
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
SDK里用到了高德SDK辅助定位,请在App项目中的AndroidManifest.xml中修改相对应的key
1) 初始化SDK
SDK.init({context}, {app}, {appid}, {appsecret})
2) 注册回调事件
SDK.registerAiCountingListener(r -> Log.e("number>>", "onNumEnd: " + r.items.size()));
3) 启动AI点数
SDK.aiCounting()
删除监听
SDK.unregisterAiCountingListener()
注意事项
a) 点数完成后,SDK不会主动退出拍摄界面,开发者可以根据以下代码获取当前Activity,并手动退出当前Activity
Activity currentCameraSession = getActivity()
b) 点数时,会有一段采样的时间,采样完毕后会自动进行结束回调
c) 回调返回信息包括图片,猪坐标以及图片旋转角度信息。
d) 请打开项目的NDK支持以及Renderscript支持
初始化SDK时,需调用setHttpFaceidQueuedCallbackAddr(建库成功回调) 和 setHttpFaceidMatchedCallbackAddr(比对结果回调) 来设置脸部识别系统的HTTP回调接口
新建脸部采集(新建识别池)
SDK.startNewFaceCapture(PoolInfo info)
class PoolInfo{
public String custom_id;
public String pool_name;
public Dictionary<String, String> extra;
public PoolType pool_type;
public bool dup_check; //是否开启重复采集检查
}
从已有识别池继续采集
SDK.continueFaceCapture(String pool_id)
脸部比对
SDK.faceRecognition(String pool_id)
删除脸部信息
SDK.faceDelete(String pool_id, String face_id)
SDK采集采用自适应离线队列后台上传机制,无法连接上网路则自动停止上传任务,直到连接上网络为止。
获取离线队列排队数据
List<CaptureInfo> offlineData = OfflineQueue.sharedQueue().Get()
暂停离线队列上传
OfflineQueue.sharedQueue().Pause()
恢复离线队列上传
OfflineQueue.sharedQueue().Resume()
查看离线队列是否运行
OfflineQueue.sharedQueue().Running()
CaptureInfo数据结构
public class BasicCaptureInfo {
public String type; // 类型,比对: match 或者是 采集: capture
public String pool_id; // 识别池id
public String pool_type; // 识别池类型,cow, yak, sheep, pig 等等
}
采集监听
SDK.registerCaptureSessionListener(new SDK.CaptureSessionDoneCallback() {
@Override //识别池创建
public void onPoolCreated(Map<String, Object> o) {
}
@Override // 已入MQ的采集信息
public void onCapturePrequeued(Map<String, Object> o) {
}
@Override //建库完成,不一定每次都能收到,以服务器回调为准
public void onClaimDone(Map<String, Object> o) {
/**
{
'pool_id': {pool_id},
'face_id': {face_id},
'pool_type': {},
'duplicated': {True/False},
'cover_url': {cover}
}
**/
}
});
控制牛脸采集输入
SDKConfigs.SetCaptureInputFeature(true/false);
脸部识别监听
SDK.registerAiMatchListener(new SDK.AiFaceMatchDoneCallback() {
@Override // 已入MQ的比对信息
public void onAiFaceMatchPrequeued(Map<String, Object> o) {
}
@Override // 服务器比对完成回调,不一定每次都能收到,以服务器回调为准
public void onDone(AiFaceMatchDone done) {
}
});
脸部比对后台回调接收数据格式
建库成功
{
'face_id': face_id, //牛脸ID
'pool_id': pool_id, // 识别池ID
'type': pool['pool_type'], // 识别池类型
'info': pool['pool_info'], // 识别池信息
'duplicated': dup, // 是否为重复采集
'noncer': ranstr(5) //随机字符串
}
比对成功
{
'similarity': 1,
'cover': e,
'info': {
'face_id': matched['id'],
'cover': matched['cover'],
'lat': matched['loc'][1],
'lng': matched['loc'][0],
'state': matched['state'],
'entrypoint': matched['entrypoint'],
'percentage': get_cosine_similarity
},
'timetag': time.time()
}
未找到匹配
{
'similarity': 0,
'cover': e,
'info': {},
'timetag': time.time()
}
加密协议 32BLOCK ECB + 自定义Padding
解密顺序:
1. AES ECB 解密(no padding)
2. unpad(密文)
const unpad = (text) => {
var t = ''
var c = ord(text[text.length - 1])
var l = text.length - c
for(var i=0;i<l;i++){
t += text[i]
}
return t
}
const ord = (text) => {
var str = text + ''
var code = str.charCodeAt(0)
if (code >= 0xD800 && code <= 0xDBFF) {
var hi = code
if (str.length === 1) {
return code
}
var low = str.charCodeAt(1)
return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000
}
if (code >= 0xDC00 && code <= 0xDFFF) {
return code
}
return code
}