首先,我简单说下虹软的人脸识别基本步骤:
1.你的设置好设置视频模式方向用于人脸检测
有如下几个可设置方向
//设置视频模式全方向人脸检测
ConfigUtil.setFtOrient(this, FaceEngine.ASF_OP_0_ONLY);
ConfigUtil.setFtOrient(this, FaceEngine.ASF_OP_90_ONLY);
ConfigUtil.setFtOrient(this, FaceEngine.ASF_OP_180_ONLY);
ConfigUtil.setFtOrient(this, FaceEngine.ASF_OP_270_ONLY);
ConfigUtil.setFtOrient(this, FaceEngine.ASF_OP_0_HIGHER_EXT);
2.以下设置之前记得先获取相应的权限<相机和读取SD卡权限>
if (!checkPermissions(NEEDED_PERMISSIONS)) {
ActivityCompat.requestPermissions(this, NEEDED_PERMISSIONS, ACTION_REQUEST_PERMISSIONS);
return;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == ACTION_REQUEST_PERMISSIONS) {
boolean isAllGranted = true;
for (int grantResult : grantResults) {
isAllGranted &= (grantResult == PackageManager.PERMISSION_GRANTED);
}
if (isAllGranted) {
//拿到相机个读取SD卡权限后再激活引擎
activeEngine();
} else {
Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_SHORT).show();
}
}
}
3.你的先激活引擎
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
FaceEngine faceEngine = new FaceEngine();
int activeCode = faceEngine.active(RegisterAndRecognizeActivity.this, Constants.APP_ID, Constants.SDK_KEY);
emitter.onNext(activeCode);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer activeCode) {
if (activeCode == ErrorInfo.MOK) {
showToast(getString(R.string.active_success));
initEngine();
initCamera();
if (cameraHelper != null) {
//启动相机
cameraHelper.start();
}
} else if (activeCode == ErrorInfo.MERR_ASF_ALREADY_ACTIVATED) {
// showToast(getString(R.string.already_activated));
initEngine();
initCamera();
if (cameraHelper != null) {
//启动相机
cameraHelper.start();
}
} else {
// activeCode:94209表示未联网
showToast(getString(R.string.active_failed, activeCode));
}
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
4.开始注册你的人脸到虹软本地数据库,为了进行人脸对比,以下是注册的主要方法
@Override
public void onPreview(final byte[] nv21, Camera camera) {
if (faceRectView != null) {
faceRectView.clearFaceInfo();
}
List<FacePreviewInfo> facePreviewInfoList = faceHelper.onPreviewFrame(nv21);
if (facePreviewInfoList != null && faceRectView != null && drawHelper != null) {
List<DrawInfo> drawInfoList = new ArrayList<>();
for (int i = 0; i < facePreviewInfoList.size(); i++) {
String name = faceHelper.getName(facePreviewInfoList.get(i).getTrackId());
drawInfoList.add(new DrawInfo(facePreviewInfoList.get(i).getFaceInfo().getRect(), GenderInfo.UNKNOWN, AgeInfo.UNKNOWN_AGE, LivenessInfo.UNKNOWN,
name == null ? String.valueOf(facePreviewInfoList.get(i).getTrackId()) : name));
}
drawHelper.draw(faceRectView, drawInfoList);
}
if (registerStatus == REGISTER_STATUS_READY && facePreviewInfoList != null && facePreviewInfoList.size() > 0) {
registerStatus = REGISTER_STATUS_PROCESSING;
Observable.create(new ObservableOnSubscribe<Boolean>() {
@Override
public void subscribe(ObservableEmitter<Boolean> emitter) {
boolean success = FaceServer.getInstance().register(RegisterAndRecognizeActivity.this, nv21.clone(), previewSize.width, previewSize.height, "registered " + faceHelper.getCurrentTrackId());
emitter.onNext(success);
}
})
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Boolean>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Boolean success) {
String result = success ? "人脸注册成功!" : "人脸注册失败!";
Toast.makeText(RegisterAndRecognizeActivity.this, result, Toast.LENGTH_SHORT).show();
registerStatus = REGISTER_STATUS_DONE;
if (success) {
//人脸注册成功,弹框提示,点击按钮退出
new AlertDialog.Builder(RegisterAndRecognizeActivity.this).setTitle("注册人脸").setMessage("人脸注册成功!").setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
}).show();
}
}
@Override
public void onError(Throwable e) {
Toast.makeText(RegisterAndRecognizeActivity.this, "人脸注册失败了!", Toast.LENGTH_SHORT).show();
registerStatus = REGISTER_STATUS_DONE;
}
@Override
public void onComplete() {
}
});
}
clearLeftFace(facePreviewInfoList);
if (facePreviewInfoList != null && facePreviewInfoList.size() > 0 && previewSize != null) {
for (int i = 0; i < facePreviewInfoList.size(); i++) {
if (livenessDetect) {
livenessMap.put(facePreviewInfoList.get(i).getTrackId(), facePreviewInfoList.get(i).getLivenessInfo().getLiveness());
}
/**
* 对于每个人脸,若状态为空或者为失败,则请求FR(可根据需要添加其他判断以限制FR次数),
* FR回传的人脸特征结果在{@link FaceListener#onFaceFeatureInfoGet(FaceFeature, Integer)}中回传
*/
if (requestFeatureStatusMap.get(facePreviewInfoList.get(i).getTrackId()) == null
|| requestFeatureStatusMap.get(facePreviewInfoList.get(i).getTrackId()) == RequestFeatureStatus.FAILED) {
requestFeatureStatusMap.put(facePreviewInfoList.get(i).getTrackId(), RequestFeatureStatus.SEARCHING);
faceHelper.requestFaceFeature(nv21, facePreviewInfoList.get(i).getFaceInfo(), previewSize.width, previewSize.height, FaceEngine.CP_PAF_NV21, facePreviewInfoList.get(i).getTrackId());
// Log.i(TAG, "onPreview: fr start = " + System.currentTimeMillis() + " trackId = " + facePreviewInfoList.get(i).getTrackId());
}
}
}
}
5.注册成功后就可以进行人脸比对了
private void searchFace(final FaceFeature frFace, final Integer requestId) {
Observable
.create(new ObservableOnSubscribe<CompareResult>() {
@Override
public void subscribe(ObservableEmitter<CompareResult> emitter) {
// Log.i(TAG, "subscribe: fr s