1. SDK下載
當前最新版SDK地址
其實整個SDK裏面只用到三個核心文件、三個util腳本,當然如果不想自己創建工程,它裏面有一個demo是可以直接跑的。
2. 核心文件導入
SDK包含三個核心文件:
- MGFaceppSDK-0.5.2.aar :裏面包含SDK 的接口,一般使用最多的接口都封裝在這裏;
- MGLicenseManagerSDK-0.3.1.aar :授權SDK,專門負責檢驗授權,每次應用啓動第一件事就是檢測授權;
- megviifacepp_0_5_2_model :做人臉檢測的模型文件,曠視將其合併壓縮(很好奇爲什麼能做的這麼小)。
兩個.aar
文件位於:~\MegviiFacepp_Android_0.5.2\Android-Demo\Android-Demo\faceppdemo\libs
,將它們拷貝到YourProject\app\libs
;模型文件位於~\MegviiFacepp_Android_0.5.2\Android-Demo\Android-Demo\faceppdemo\src\main\res\raw
,將其拷貝到YourProject\app\src\main\res\raw
(文件夾raw
可能並不存在,手動創建就好)。
在 AS 中修改module
的配置文件build.gradle
:在dependencies
結構中添加如下兩行
compile(name: 'MGLicenseManagerSDK-0.3.1', ext: 'aar')
compile(name: 'MGFaceppSDK-0.5.2', ext: 'aar')
在android
結構中添加如下代碼
repositories {
flatDir {
dirs 'libs'
}
}
注意:官方文檔給出的是compile
命令,在最新的Android框架中可能會提示使用implementation
去替代;name
需要跟你使用的SDK版本保持一致,否則會報錯。接下來重新編譯工程即可:菜單欄Build -> Clean Project-> Rebuild Project
。成功之後可以在工程中使用如下命令導入和使用SDK:
import com.megvii.facepp.sdk.Facepp;
import com.megvii.licensemanager.sdk.LicenseManager;
3. util腳本
這三個腳本其實並不是必需的,但是確實是要用到裏面的一些方法,那既然官方寫好了那我們直接用就好。
- SharedUtil.java:用來存儲數據的
- ConUtil.java:一些實用的方法
- Util.java:你的API_Key、Secret_Key就放在這兒
直接將這三個文件拷貝到YourProject\app\src\main\java\com\**\**\util
下面,然後修改每個文件頭部的package
,修改Util.java
的key
值爲你自己就好。key
值需要到官網註冊賬號,然後新建API,綁定Bundle(在“應用管理”中可以看到),Bundle的ID最好是跟項目的applicationId
保持一致(我試過不一樣也能用好像~)。
4. 聯網授權
SDK分爲離線授權和聯網授權兩種,離線授權就是你買它的SDK,他給你的時候就把權限寫在SDK裏面了;聯網授權一般是在免費使用版本中,每一次使用SDK的時候需要通過網絡訪問來獲取權限,這裏以聯網授權的版本爲例。
- 聯網授權SDK(試用版)有效期爲 1 天,有效期內可免費授權五次,同一APP重複使用、不卸載安裝都只會在首次進行聯網授權(卸載重裝會佔用一次),之後會將License文件保存在本地,直到License過期。
- 聯網授權需要幾個權限:
INTERNET
,ACCESS_NETWORK_STATE
,然後還有關於圖像數據的讀寫、相機權限等需要自己添加,最好是動態授權。
聯網授權最關鍵的代碼部分:
private void network() {
// 獲取聯網授權類型
int type = Facepp.getSDKAuthType(ConUtil.getFileContent(this, R.raw.megviifacepp_0_5_2_model));
if ( type == 2) {// 非聯網授權
authState(true,0,"");
return;
}
// 開始聯網授權
final LicenseManager licenseManager = new LicenseManager(this);
String uuid = ConUtil.getUUIDString(this); // 手機唯一序列號
long apiName = Facepp.getApiName(); // 大概是SDK的版本名稱,API自己獲取不用管
licenseManager.setAuthTimeBufferMillis(0); // 設置時間緩衝,猜測可能跟SDK的License期限有關
// 回調
licenseManager.takeLicenseFromNetwork(
Util.CN_LICENSE_URL, // 聯網授權地址
uuid,
Util.API_KEY,
Util.API_SECRET,
apiName,
"1", // 使用期限,試用版本只能是1天
new LicenseManager.TakeLicenseCallback() {
@Override
public void onSuccess() {
authState(true,0,"");
}
@Override
public void onFailed(int i, byte[] bytes) {
if (TextUtils.isEmpty(Util.API_KEY)||TextUtils.isEmpty(Util.API_SECRET)) {
if (!ConUtil.isReadKey(MainActivity.this)) {
authState(false,1001,"");
}else{
authState(false,1001,"");
}
}else{
String msg="";
if (bytes!=null&&bytes.length>0){
msg= new String(bytes);
}
authState(false,i,msg);
}
}
});
}
private void authState(boolean isSuccess,int code,String msg) {
if (isSuccess) { // 聯網授權成功
Log.d("聯網授權", "成功");
Intent intent = new Intent();
intent.setClass(this, FaceActionActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
} else { // 聯網授權失敗
Log.d(code, msg);
}
}
最爲關鍵的就是licenseManager.takeLicenseFromNetwork
,它裏面重寫了onSuccess
、onFailed
函數,分別會在授權成功/失敗時調用。授權成功的話我們會讓它跳轉至FaceActionActivity.class
,同時銷燬當前的MainActivity
,然後在FaceActionActivity
裏進行人臉關鍵點的檢測,這樣做的原因是:聯網授權的network
(其實就是裏面的licenseManager.takeLicenseFromNetwork
)是一個異步事件,需要在它的OnSuccess
裏面做檢測,如果在這之後做檢測可能會有問題。
官方給出的一些說明好像跟實際應用開發並不一致,比如關於權限次數:官方文檔寫明一個API_Key一天有五次機會,也就是說如果你把當前的API_Key刪除,重新創建一個API_Key會擁有新的五次機會,但實踐證明不會。可以能會得到以下的返回錯誤:
- LICENSE_NOT_FOUND:刪除次數已滿的API_Key,使用新建的API_Key,可能會得到這個錯誤(它以爲你用了正式API_Key,但是本地並沒有找到);
- MG_RETCODE_INVALID_LICENSE:授權失敗;
- DAILY_QUOTA_EXCEEDED:當前API_Key免費使用次數達到上限。
5. 調用SDK實現人臉關鍵點檢測
(1)初始化實例,然後加載模型
Facepp facepp = new Facepp();
String errorCode = facepp.init(this, ConUtil.getFileContent(this, R.raw.megviifacepp_0_5_2_model), 1);
這裏可能會存在R.raw
不存在的問題,關掉項目重新打開一下就好;最後一個參數表示是否只檢測單個人臉,0表示否,1表示是。一般如果聯網授權沒問題,這裏的errorCode
返回值是null
,否則會返回具體的錯誤信息。
(2)檢測參數設置
// 設置檢測器參數(這裏只列出一部分)
Facepp.FaceppConfig faceppConfig = new Facepp.FaceppConfig();
faceppConfig.detectionMode = Facepp.FaceppConfig.DETECTION_MODE_TRACKING_FAST; // 檢測模式:FAST,ROUBUST
faceppConfig.minFaceSize = 1; // 最小人臉尺寸
faceppConfig.roi_right = w; // 感興趣區域
faceppConfig.roi_bottom = h;
facepp.setFaceppConfig(faceppConfig);
(3)人臉檢測,獲取數據
// 檢測人臉,最後一個參數是輸入圖像的格式
final Facepp.Face[] faces = facepp.detect(imgData, w, h, Facepp.IMAGEMODE_NV21);
// 獲取人臉數據
facepp.getLandmarkRaw(faces[0], Facepp.FPP_GET_LANDMARK106);
facepp.get3DPose(faces[0]);
檢測人臉的時候輸入數據類型是byte[]
,官方給出支持 NV21、BGR 格式的檢測(就是detect方法的最後一個參數),但是親測好像只支持NV21,所以最好是將圖像轉成 NV21 格式的byte[]
;如果把BGR數據送進去,最後檢測到的人臉數量爲0。
關於SDK能夠獲取到的數據可以看官方文檔,基本上就是關鍵點、頭部3D-pose、人臉屬性等,有些事收費才能獲取的,但是關鍵點和頭部3D-pose是免費的。