FaceRecog/Distribution/Readme.md

241 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 人脸识别 Android SDK 集成指南 (V1.0)
本文档为人脸识别 C++ 核心库 (libface_sdk_jni.so) 提供了详尽的 Android 集成步骤和 API 使用说明。
## 1. 概述
本 SDK 提供了在 Android 设备上本地运行的高性能人脸识别功能。SDK 核心基于 C++ 实现1:1 转译自 Python 端的 7 模型推理管线,确保了特征向量的完全兼容。
SDK 提供的主要 Java API 接口包括:
特征提取: extractFeature(Bitmap bitmap)
特征比较: compare(float[] feat1, float[] feat2)
关键特性
C++ 核心: 所有计算均在 C++ 层完成,性能高,内存可控。
7 模型管线: 完整复现了 Python 端的 7 模型管线(旋转、检测、姿态、关键点、对齐、识别),保证了高识别精度。
质量过滤: 内置姿态角Yaw/Pitch过滤自动拒绝低质量人脸。
手动捆绑: SDK 手动捆绑了所有必要的依赖库 (ONNX Runtime, OpenCV, C++ STL),确保了在不同设备上的一致性,避免了因 Gradle 依赖版本不匹配导致的崩溃。
## 2. SDK 包内容
分发的 SDK 包含三个部分:
1. Java 接口
SDK_Wrapper/
└── com/
└── facesdk/
└── wrapper/
└── FaceSDKWrapper.java (SDK 公开的 Java API)
2. Native 库 (C++)
SDK_Libs/
└── arm64-v8a/
├── libface_sdk_jni.so (✅ 您的核心 SDK 库)
├── libonnxruntime.so (依赖: ONNX 1.23.2 完整版)
├── libopencv_java4.so (依赖: OpenCV 4.12.0)
└── libc++_shared.so (依赖: C++ 标准库)
注意: 本 SDK 目前仅支持 arm64-v8a 架构。这覆盖了市面上 99% 以上的现代 Android 设备。
3. AI 模型
SDK_Models/
├── faceboxesv2-640x640.onnx
├── face_landmarker_pts5_net1.onnx
├── face_landmarker_pts5_net2.onnx
├── face_recognizer.onnx
├── fsanet-conv.onnx
├── fsanet-var.onnx
└── model_gray_mobilenetv2_rotcls.onnx
## 3. 集成指南
请按照以下步骤将 SDK 集成到您的 Android Studio 项目中。
步骤 1: 复制 Java 接口
在 Android Studio 的 "Project" 视图中,导航到 app/src/main/java/。
将 FaceSDKWrapper.java 文件复制到您项目的 Java 源码目录中例如com.yourcompany.yourapp.sdk/)。
重要: 打开 FaceSDKWrapper.java 文件,将其顶部的 package com.facesdk.wrapper; 声明修改为您自己的包名,例如 package com.yourcompany.yourapp.sdk;。
步骤 2: 复制 Native 库 (.so)
在 Android Studio 的 "Project" 视图中,导航到 app/src/main/。
右键点击 main -> New -> Directory。
创建 jniLibs 文件夹。
右键点击 jniLibs -> New -> Directory。
创建 arm64-v8a 文件夹。
将 SDK_Libs/arm64-v8a/ 目录下的所有 4 个 .so 文件复制到您刚创建的 app/src/main/jniLibs/arm64-v8a/ 目录中。
步骤 3: 复制 AI 模型 (.onnx)
在 Android Studio 的 "Project" 视图中,导航到 app/src/main/。
右键点击 main -> New -> Directory。
创建 assets 文件夹。
将 SDK_Models/ 目录下的所有 7 个 .onnx 文件复制到您刚创建的 app/src/main/assets/ 目录中。
步骤 4: 配置 build.gradle.kts (或 build.gradle)
这是最关键的一步。我们需要告诉 Gradle 在打包 App 时包含我们的手动库。
打开您的 app/build.gradle.kts (或 build.gradle) 文件。
移除 (或不要添加) onnxruntime 和 opencv 的 implementation 依赖。我们已经手动提供了它们。
在 android { ... } 代码块中,添加 sourceSets 和 ndk 配置:
如果是 build.gradle.kts (Kotlin 脚本):
Kotlin
```android {
// ... (namespace, compileSdk, 等)
defaultConfig {
// ... (applicationId, minSdk, targetSdk, 等)
// 强制 Gradle 只打包和使用 arm64-v8a 架构的库
// 这可以防止在 x86 模拟器上发生库不匹配的崩溃
ndk {
abiFilters.add("arm64-v8a")
}
}
// (保持这个 sourceSets 块不变,即使它看起来是空的)
sourceSets {
getByName("main") {
// 明确告知 Gradle 我们的 jniLibs 目录在哪里
jniLibs.srcDirs("src/main/jniLibs")
}
}
// ... (buildTypes, compileOptions, 等)
}```
如果是 build.gradle (Groovy 脚本):
Groovy
```android {
// ... (namespace, compileSdk, 等)
defaultConfig {
// ... (applicationId, minSdk, targetSdk, 等)
}
sourceSets {
main {
// 明确告知 Gradle 我们的 jniLibs 目录在哪里
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
// 强制 Gradle 只打包和使用 arm64-v8a 架构的库
ndk {
abiFilters 'arm64-v8a'
}
// ... (buildTypes, compileOptions, 等)
}
```点击 "Sync Now" 同步您的项目。
至此,集成已全部完成!
4. API 使用指南 (Java)
FaceSDKWrapper.java 会自动处理模型复制和 C++ 库加载。
1. 初始化 SDK
您必须在后台线程中初始化 SDK因为它包含耗时的模型复制操作仅限首次启动
Java
```import com.facesdk.wrapper.FaceSDKWrapper; // 确保导入您修改了包名的类
public class MyApplication extends Application {
private FaceSDKWrapper sdkWrapper;
private volatile boolean isSdkInitialized = false;
@Override
public void onCreate() {
super.onCreate();
// 在后台线程初始化 SDK
new Thread(() -> {
sdkWrapper = new FaceSDKWrapper();
boolean success = sdkWrapper.init(getApplicationContext());
if (success) {
isSdkInitialized = true;
Log.i("MyApplication", "人脸识别 SDK 初始化成功!");
} else {
Log.e("MyApplication", "人脸识别 SDK 初始化失败!");
}
}).start();
}
// 提供一个全局获取 SDK 实例的方法
public FaceSDKWrapper getSdkWrapper() {
return (isSdkInitialized) ? sdkWrapper : null;
}
}```
(您也可以不在 Application 中初始化,而是在 Activity 中,如我们的测试项目所示)
2. 提取特征 (必须在后台线程)
特征提取是一个CPU 密集型操作(运行 7 个模型)。严禁在 UI 主线程上调用它,否则会导致 App 冻结。
Java
```// (在您的 Activity 或 ViewModel 中)
// 假设您已从 Application 中获取了 sdkWrapper 实例
public void runExtraction(Bitmap faceBitmap) {
if (sdkWrapper == null) {
Log.e("MyActivity", "SDK 尚未初始化。");
return;
}
// 必须在后台线程中运行
new Thread(() -> {
// 1. 调用 C++ 核心库
final float[] features = sdkWrapper.extractFeature(faceBitmap);
// 2. 在 UI 线程上处理结果
runOnUiThread(() -> {
if (features != null) {
Log.i("MyActivity", "特征提取成功!维度: " + features.length);
// TODO: 使用特征向量 (例如,与数据库比对)
} else {
Log.w("MyActivity", "特征提取失败 (未检测到合格人脸或出错)");
// TODO: 提示用户
}
});
}).start();
}```
3. 比较特征
这是一个非常快速的操作,可以在任何线程上调用。
Java
```float[] featureA = ... // (来自 extractFeature)
float[] featureB = ... // (来自数据库)
float similarity = sdkWrapper.compare(featureA, featureB);
// 相似度是一个 -1.0 到 1.0 之间的浮点数 (余弦相似度)
Log.i("MyActivity", "人脸相似度: " + similarity);```
4. 释放 SDK
在您的主 Activity (或 Application) 退出时,调用 release() 来释放 C++ 占用的内存。
Java
```// (在您的 MainActivity 中)
@Override
protected void onDestroy() {
super.onDestroy();
if (sdkWrapper != null) {
sdkWrapper.release();
}
}```