调整了人脸识别界面

This commit is contained in:
zxj
2025-07-24 18:02:42 +08:00
parent 082011a939
commit 5b3773d277
34 changed files with 203 additions and 137 deletions
@@ -1,6 +1,7 @@
package com.sw.plate.utils.arcface;
import android.content.Context;
import android.util.Log;
import com.arcsoft.face.FaceEngine;
import com.arcsoft.face.enums.RuntimeABI;
@@ -14,6 +15,8 @@ import com.sw.plate.utils.arcface.facedb.entity.FaceEntity;
import java.util.List;
public class FaceApi {
private static final String TAG = "FaceApi";
public interface ActiveCallback {
void onSuccess(int code);
@@ -27,12 +30,12 @@ public class FaceApi {
* @param list
*/
public void updateFaceData(int index, List<FaceEntity> list) {
Log.d(TAG, "updateFaceData: index = " + index + ", listSize = " + list.size());
FaceDao faceDao = FaceDatabase.getInstance(App.getContext()).faceDao();
if (index == 0) {
faceDao.deleteAll();
faceDao.resetId();
}
faceDao.insert(list);
}
@@ -2,6 +2,8 @@ package com.sw.plate.utils.arcface.face;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import androidx.annotation.IntDef;
@@ -47,7 +49,6 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
@@ -529,7 +530,7 @@ public class FaceHelper implements FaceListener {
if (recognizeInfoMap.containsKey(trackId)) {
onFaceFeatureInfoGet(faceFeature, trackId, errorCode);
}
} catch (InterruptedException e) {
} catch (Exception e) {
Log.e(TAG, "onFaceFeatureInfoGet: 等待活体结果时退出界面会执行,正常现象,可注释异常代码块");
e.printStackTrace();
}
@@ -549,40 +550,35 @@ public class FaceHelper implements FaceListener {
}
}
// 定义一个Handler,用于处理延迟任务
private Handler delayHandler = new Handler(Looper.getMainLooper());
/**
* 延迟 {@link RecognizeConfiguration#getLivenessFailedRetryInterval()}后,重新进行活体检测
*
* @param trackId 人脸ID
*/
private void retryLivenessDetectDelayed(final Integer trackId) {
Observable.timer(recognizeConfiguration.getLivenessFailedRetryInterval(), TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Long>() {
Disposable disposable;
Log.d(TAG, "retryLivenessDetectDelayed: trackId = " + trackId + ", threadName =" + Thread.currentThread().getName());
Log.d(TAG, "retryLivenessDetectDelayed: Interval = " + recognizeConfiguration.getLivenessFailedRetryInterval());
@Override
public void onSubscribe(Disposable d) {
disposable = d;
delayFaceTaskCompositeDisposable.add(disposable);
}
// 创建延迟任务
Runnable delayTask = new Runnable() {
@Override
public void run() {
// 将该人脸状态置为UNKNOWN,帧回调处理时会重新进行活体检测
changeLiveness(trackId, LivenessInfo.UNKNOWN);
// 从集合中移除这个任务
delayFaceTaskList.remove(this);
}
};
@Override
public void onNext(Long aLong) {
// 将任务添加到集合中管理
delayFaceTaskList.add(delayTask);
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onComplete() {
// 将该人脸状态置为UNKNOWN,帧回调处理时会重新进行活体检测
changeLiveness(trackId, LivenessInfo.UNKNOWN);
delayFaceTaskCompositeDisposable.remove(disposable);
}
});
// 发送延迟任务
delayHandler.postDelayed(delayTask, recognizeConfiguration.getLivenessFailedRetryInterval());
}
/**
@@ -591,40 +587,33 @@ public class FaceHelper implements FaceListener {
* @param trackId 人脸ID
*/
private void retryRecognizeDelayed(final Integer trackId) {
Log.d(TAG, "retryRecognizeDelayed: trackId = " + trackId);
changeRecognizeStatus(trackId, RequestFeatureStatus.FAILED);
Observable.timer(recognizeConfiguration.getRecognizeFailedRetryInterval(), TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Long>() {
Disposable disposable;
@Override
public void onSubscribe(Disposable d) {
disposable = d;
delayFaceTaskCompositeDisposable.add(disposable);
}
// 创建延迟任务
Runnable delayTask = new Runnable() {
@Override
public void run() {
// 将该人脸特征提取状态置为FAILED,帧回调处理时会重新进行活体检测
changeRecognizeStatus(trackId, RequestFeatureStatus.TO_RETRY);
// 从集合中移除这个任务
delayFaceTaskList.remove(this);
}
};
@Override
public void onNext(Long aLong) {
// 将任务添加到集合中管理
delayFaceTaskList.add(delayTask);
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "retryRecognizeDelayed e = " + e);
e.printStackTrace();
}
@Override
public void onComplete() {
// 将该人脸特征提取状态置为FAILED,帧回调处理时会重新进行活体检测
changeRecognizeStatus(trackId, RequestFeatureStatus.TO_RETRY);
delayFaceTaskCompositeDisposable.remove(disposable);
}
});
// 发送延迟任务
delayHandler.postDelayed(delayTask, recognizeConfiguration.getRecognizeFailedRetryInterval());
}
// 需要在类中定义一个集合来管理所有的延迟任务,替代原来的CompositeDisposable
private List<Runnable> delayFaceTaskList = new ArrayList<>();
@Override
public void onFaceLivenessInfoGet(@Nullable LivenessInfo livenessInfo, Integer trackId, Integer errorCode) {
Log.d(TAG, "onFaceLivenessInfoGet: trackId = " + trackId);
if (livenessInfo != null) {
int liveness = livenessInfo.getLiveness();
Log.i(TAG, "onFaceLivenessInfoGet liveness:" + liveness);
@@ -0,0 +1,49 @@
package com.sw.plate.utils.arcface.face;
import android.util.Log;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
public class Test {
private static final String TAG = "Test";
private CompositeDisposable delayFaceTaskCompositeDisposable = new CompositeDisposable();
public void test1() {
Log.d(TAG, "test1: ");
Observable.timer(10, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Long>() {
Disposable disposable;
@Override
public void onSubscribe(Disposable d) {
disposable = d;
delayFaceTaskCompositeDisposable.add(disposable);
}
@Override
public void onNext(Long value) {
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete: ");
delayFaceTaskCompositeDisposable.remove(disposable);
}
});
}
}
@@ -9,8 +9,6 @@ import androidx.room.RoomDatabase;
import com.sw.plate.utils.arcface.facedb.dao.FaceDao;
import com.sw.plate.utils.arcface.facedb.entity.FaceEntity;
import java.io.File;
@Database(entities = {FaceEntity.class}, version = 1, exportSchema = false)
public abstract class FaceDatabase extends RoomDatabase {
public abstract FaceDao faceDao();
@@ -22,7 +20,9 @@ public abstract class FaceDatabase extends RoomDatabase {
synchronized (FaceDatabase.class) {
if (faceDatabase == null) {
faceDatabase = Room.databaseBuilder(context, FaceDatabase.class,
context.getExternalFilesDir("database") + File.separator + "faceDB.db").build();
context.getDatabasePath("faceDB.db").getPath()
// context.getExternalFilesDir("database") + File.separator + "faceDB.db"
).build();
}
}
}
@@ -4,7 +4,6 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Environment;
import android.util.Log;
import com.arcsoft.face.ErrorInfo;
@@ -354,8 +353,11 @@ public class FaceServer {
* @return 存放注册照的文件夹路径
*/
private String getImageDir() {
return App.getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES)
+ File.separator + "faceDB" + File.separator + "registerFaces";
// return App.getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES)
// + File.separator + "faceDB" + File.separator + "registerFaces";
return App.getContext().getFilesDir()
+ File.separator + "faceDB"
+ File.separator + "registerFaces";
}
/**