700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Android开发之虹软人脸识别活体检测基本步骤

Android开发之虹软人脸识别活体检测基本步骤

时间:2022-11-07 11:59:04

相关推荐

Android开发之虹软人脸识别活体检测基本步骤

首先,我简单说下虹软的人脸识别基本步骤:

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;}@Overridepublic 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>() {@Overridepublic 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>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic 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));}}@Overridepublic void onError(Throwable e) {}@Overridepublic void onComplete() {}});

4.开始注册你的人脸到虹软本地数据库,为了进行人脸对比,以下是注册的主要方法

@Overridepublic 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>() {@Overridepublic 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(putation()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<Boolean>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic 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() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.dismiss();finish();}}).show();}}@Overridepublic void onError(Throwable e) {Toast.makeText(RegisterAndRecognizeActivity.this, "人脸注册失败了!", Toast.LENGTH_SHORT).show();registerStatus = REGISTER_STATUS_DONE;}@Overridepublic 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>() {@Overridepublic void subscribe(ObservableEmitter<CompareResult> emitter) {// Log.i(TAG, "subscribe: fr search start = " + System.currentTimeMillis() + " trackId = " + requestId);//下面的人脸比对信息CompareResult compareResult = FaceServer.getInstance().getTopOfFaceLib(frFace);// Log.i(TAG, "subscribe: fr search end = " + System.currentTimeMillis() + " trackId = " + requestId);if (compareResult == null) {emitter.onError(null);} else {emitter.onNext(compareResult);}}}).subscribeOn(putation()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<CompareResult>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(CompareResult compareResult) {if (compareResult == null || compareResult.getUserName() == null) {requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED);faceHelper.addName(requestId, "VISITOR " + requestId);return;}Log.i(TAG, "onNext:查询到的结果:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).format(System.currentTimeMillis()) + " trackId = " + requestId + " similar = " + compareResult.getSimilar());if (compareResult.getSimilar() > SIMILAR_THRESHOLD) {boolean isAdded = false;if (compareResultList == null) {requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED);faceHelper.addName(requestId, "VISITOR " + requestId);return;}for (CompareResult compareResult1 : compareResultList) {if (compareResult1.getTrackId() == requestId) {isAdded = true;break;}}if (!isAdded) {//对于多人脸搜索,假如最大显示数量为 MAX_DETECT_NUM 且有新的人脸进入,则以队列的形式移除if (compareResultList.size() >= MAX_DETECT_NUM) {compareResultList.remove(0);adapter.notifyItemRemoved(0);}//添加显示人员时,保存其trackIdcompareResult.setTrackId(requestId);compareResultList.add(compareResult);adapter.notifyItemInserted(compareResultList.size() - 1);}requestFeatureStatusMap.put(requestId, RequestFeatureStatus.SUCCEED);Toast.makeText(RegisterAndRecognizeActivity.this, "人脸比对成功,相似度:" + compareResult.getSimilar(), Toast.LENGTH_LONG).show();//调用下单接口mPresenter.orderDinner(valueParams);faceHelper.addName(requestId, compareResult.getUserName());} else {requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED);faceHelper.addName(requestId, "VISITOR " + requestId);Toast.makeText(RegisterAndRecognizeActivity.this, "人脸比对失败,相似度:" + compareResult.getSimilar(), Toast.LENGTH_LONG).show();}}@Overridepublic void onError(Throwable e) {requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED);}@Overridepublic void onComplete() {}});}

6.也可以进行活体检测,主要代码:

final FaceListener faceListener = new FaceListener() {@Overridepublic void onFail(Exception e) {Log.e(TAG, "onFail: " + e.getMessage());}//请求FR的回调@Overridepublic void onFaceFeatureInfoGet(@Nullable final FaceFeature faceFeature, final Integer requestId) {//FR成功if (faceFeature != null) {//Log.i(TAG, "onPreview: fr end = " + System.currentTimeMillis() + " trackId = " + requestId);//不做活体检测的情况,直接搜索if (!livenessDetect) {// searchFace(faceFeature, requestId);}//活体检测通过,搜索特征else if (livenessMap.get(requestId) != null && livenessMap.get(requestId) == LivenessInfo.ALIVE) {runOnUiThread(new Runnable() {@Overridepublic void run() {showToast("活体检测通过");}});if (isComplete) {//确认活体,开始对比searchFace(faceFeature, requestId);} else {//开始注册if (registerStatus == REGISTER_STATUS_DONE) {registerStatus = REGISTER_STATUS_READY;}}}//活体检测未出结果,延迟100ms再执行该函数else if (livenessMap.get(requestId) != null && livenessMap.get(requestId) == LivenessInfo.UNKNOWN) {getFeatureDelayedDisposables.add(Observable.timer(WAIT_LIVENESS_INTERVAL, TimeUnit.MILLISECONDS).subscribe(new Consumer<Long>() {@Overridepublic void accept(Long aLong) {onFaceFeatureInfoGet(faceFeature, requestId);}}));}//活体检测失败else {runOnUiThread(new Runnable() {@Overridepublic void run() {showToast("活体检测失败");}});// requestFeatureStatusMap.put(requestId, RequestFeatureStatus.NOT_ALIVE);}}//FR 失败else {requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED);}}};

上面的代码看起来可能很凌乱,我说的只是基本的思路

所以我将核心完整代码粘贴如下:

RegisterAndRecognizeActivity.java这个是人脸识别,人脸注册,活体检测,人脸对比的主要页面的代码

import android.Manifest;import android.content.pm.ActivityInfo;import android.content.pm.PackageManager;import android.content.res.Configuration;import android.graphics.Point;import android.hardware.Camera;import android.os.Build;import android.os.Bundle;import android.support.annotation.NonNull;import android.support.annotation.Nullable;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.DefaultItemAnimator;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.util.DisplayMetrics;import android.util.Log;import android.view.View;import android.view.ViewTreeObserver;import android.view.WindowManager;import poundButton;import android.widget.Switch;import android.widget.Toast;import com.arcsoft.face.AgeInfo;import com.arcsoft.face.ErrorInfo;import com.arcsoft.face.FaceEngine;import com.arcsoft.face.FaceFeature;import com.arcsoft.face.GenderInfo;import com.arcsoft.face.LivenessInfo;import com.arcsoft.face.VersionInfo;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.List;import java.util.Locale;import java.util.Set;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.TimeUnit;import io.reactivex.Observable;import io.reactivex.ObservableEmitter;import io.reactivex.ObservableOnSubscribe;import io.reactivex.Observer;import io.reactivex.android.schedulers.AndroidSchedulers;import io.positeDisposable;import io.reactivex.disposables.Disposable;import io.reactivex.functions.Consumer;import io.reactivex.schedulers.Schedulers;/*** @author 轻飞扬* 3月7日10:48:09*/public class RegisterAndRecognizeActivity extends AppCompatActivity implements ViewTreeObserver.OnGlobalLayoutListener {private static final String TAG = "RegisterAndRecognize";private static final int MAX_DETECT_NUM = 10;/*** 当FR成功,活体未成功时,FR等待活体的时间*/private static final int WAIT_LIVENESS_INTERVAL = 50;private CameraHelper cameraHelper;private DrawHelper drawHelper;private Camera.Size previewSize;/*** 优先打开的摄像头*/private Integer cameraID = Camera.CameraInfo.CAMERA_FACING_FRONT;private FaceEngine faceEngine;private FaceHelper faceHelper;private List<CompareResult> compareResultList;private ShowFaceInfoAdapter adapter;/*** 活体检测的开关*/private boolean livenessDetect = true;/*** 注册人脸状态码,准备注册*/private static final int REGISTER_STATUS_READY = 0;/*** 注册人脸状态码,注册中*/private static final int REGISTER_STATUS_PROCESSING = 1;/*** 注册人脸状态码,注册结束(无论成功失败)*/private static final int REGISTER_STATUS_DONE = 2;private int registerStatus = REGISTER_STATUS_DONE;private int afCode = -1;private ConcurrentHashMap<Integer, Integer> requestFeatureStatusMap = new ConcurrentHashMap<>();private ConcurrentHashMap<Integer, Integer> livenessMap = new ConcurrentHashMap<>();private CompositeDisposable getFeatureDelayedDisposables = new CompositeDisposable();/*** 相机预览显示的控件,可为SurfaceView或TextureView*/private View previewView;/*** 绘制人脸框的控件*/private FaceRectView faceRectView;private Switch switchLivenessDetect;private static final int ACTION_REQUEST_PERMISSIONS = 0x001;private static final float SIMILAR_THRESHOLD = 0.8F;private Toast toast = null;/*** 所需的所有权限信息*/private static final String[] NEEDED_PERMISSIONS = new String[]{Manifest.permission.CAMERA,Manifest.permission.READ_PHONE_STATE};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//设置视频模式全方向人脸检测ConfigUtil.setFtOrient(this, FaceEngine.ASF_OP_0_HIGHER_EXT);setContentView(R.layout.activity_register_and_recognize);//保持亮屏getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {WindowManager.LayoutParams attributes = getWindow().getAttributes();attributes.systemUiVisibility = View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;getWindow().setAttributes(attributes);}// Activity启动后就锁定为启动时的方向switch (getResources().getConfiguration().orientation) {case Configuration.ORIENTATION_PORTRAIT:setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);break;case Configuration.ORIENTATION_LANDSCAPE:setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);break;default:break;}//本地人脸库初始化FaceServer.getInstance().init(this);previewView = findViewById(R.id.texture_preview);//在布局结束后才做初始化操作previewView.getViewTreeObserver().addOnGlobalLayoutListener(this);faceRectView = findViewById(R.id.face_rect_view);switchLivenessDetect = findViewById(R.id.switch_liveness_detect);switchLivenessDetect.setChecked(livenessDetect);switchLivenessDetect.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {livenessDetect = isChecked;}});RecyclerView recyclerShowFaceInfo = findViewById(R.id.recycler_view_person);compareResultList = new ArrayList<>();adapter = new ShowFaceInfoAdapter(compareResultList, this);recyclerShowFaceInfo.setAdapter(adapter);DisplayMetrics dm = getResources().getDisplayMetrics();int spanCount = (int) (dm.widthPixels / (getResources().getDisplayMetrics().density * 100 + 0.5f));recyclerShowFaceInfo.setLayoutManager(new GridLayoutManager(this, spanCount));recyclerShowFaceInfo.setItemAnimator(new DefaultItemAnimator());}private void showToast(String s) {if (toast == null) {toast = Toast.makeText(this, s, Toast.LENGTH_SHORT);toast.show();} else {toast.setText(s);toast.show();}}/*** 初始化引擎*/private void initEngine() {faceEngine = new FaceEngine();afCode = faceEngine.init(this, FaceEngine.ASF_DETECT_MODE_VIDEO, ConfigUtil.getFtOrient(this),16, MAX_DETECT_NUM, FaceEngine.ASF_FACE_RECOGNITION | FaceEngine.ASF_FACE_DETECT | FaceEngine.ASF_LIVENESS);VersionInfo versionInfo = new VersionInfo();faceEngine.getVersion(versionInfo);Log.i(TAG, "initEngine: init: " + afCode + " version:" + versionInfo);if (afCode != ErrorInfo.MOK) {Toast.makeText(this, getString(R.string.init_failed, afCode), Toast.LENGTH_SHORT).show();}}/*** 销毁引擎*/private void unInitEngine() {if (afCode == ErrorInfo.MOK) {afCode = faceEngine.unInit();Log.i(TAG, "unInitEngine: " + afCode);}}@Overrideprotected void onDestroy() {if (cameraHelper != null) {cameraHelper.release();cameraHelper = null;}//faceHelper中可能会有FR耗时操作仍在执行,加锁防止crashif (faceHelper != null) {synchronized (faceHelper) {unInitEngine();}ConfigUtil.setTrackId(this, faceHelper.getCurrentTrackId());faceHelper.release();} else {unInitEngine();}if (getFeatureDelayedDisposables != null) {getFeatureDelayedDisposables.dispose();getFeatureDelayedDisposables.clear();}FaceServer.getInstance().unInit();super.onDestroy();}private boolean checkPermissions(String[] neededPermissions) {if (neededPermissions == null || neededPermissions.length == 0) {return true;}boolean allGranted = true;for (String neededPermission : neededPermissions) {allGranted &= ContextCompat.checkSelfPermission(this, neededPermission) == PackageManager.PERMISSION_GRANTED;}return allGranted;}private void initCamera() {DisplayMetrics metrics = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metrics);final FaceListener faceListener = new FaceListener() {@Overridepublic void onFail(Exception e) {Log.e(TAG, "onFail: " + e.getMessage());}//请求FR的回调@Overridepublic void onFaceFeatureInfoGet(@Nullable final FaceFeature faceFeature, final Integer requestId) {//FR成功if (faceFeature != null) {//Log.i(TAG, "onPreview: fr end = " + System.currentTimeMillis() + " trackId = " + requestId);//不做活体检测的情况,直接搜索if (!livenessDetect) {searchFace(faceFeature, requestId);}//活体检测通过,搜索特征else if (livenessMap.get(requestId) != null && livenessMap.get(requestId) == LivenessInfo.ALIVE) {runOnUiThread(new Runnable() {@Overridepublic void run() {showToast("活体检测通过");}});searchFace(faceFeature, requestId);}//活体检测未出结果,延迟100ms再执行该函数else if (livenessMap.get(requestId) != null && livenessMap.get(requestId) == LivenessInfo.UNKNOWN) {getFeatureDelayedDisposables.add(Observable.timer(WAIT_LIVENESS_INTERVAL, TimeUnit.MILLISECONDS).subscribe(new Consumer<Long>() {@Overridepublic void accept(Long aLong) {onFaceFeatureInfoGet(faceFeature, requestId);}}));}//活体检测失败else {runOnUiThread(new Runnable() {@Overridepublic void run() {showToast("活体检测失败");}});requestFeatureStatusMap.put(requestId, RequestFeatureStatus.NOT_ALIVE);}}//FR 失败else {requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED);}}};CameraListener cameraListener = new CameraListener() {@Overridepublic void onCameraOpened(Camera camera, int cameraId, int displayOrientation, boolean isMirror) {previewSize = camera.getParameters().getPreviewSize();drawHelper = new DrawHelper(previewSize.width, previewSize.height, previewView.getWidth(), previewView.getHeight(), displayOrientation, cameraId, isMirror);faceHelper = new FaceHelper.Builder().faceEngine(faceEngine).frThreadNum(MAX_DETECT_NUM).previewSize(previewSize).faceListener(faceListener).currentTrackId(ConfigUtil.getTrackId(RegisterAndRecognizeActivity.this.getApplicationContext())).build();}@Overridepublic 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>() {@Overridepublic 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(putation()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<Boolean>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(Boolean success) {String result = success ? "register success!" : "register failed!";Toast.makeText(RegisterAndRecognizeActivity.this, result, Toast.LENGTH_SHORT).show();registerStatus = REGISTER_STATUS_DONE;}@Overridepublic void onError(Throwable e) {Toast.makeText(RegisterAndRecognizeActivity.this, "register failed!", Toast.LENGTH_SHORT).show();registerStatus = REGISTER_STATUS_DONE;}@Overridepublic 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());}}}}@Overridepublic void onCameraClosed() {Log.i(TAG, "onCameraClosed: ");}@Overridepublic void onCameraError(Exception e) {Log.i(TAG, "onCameraError: " + e.getMessage());}@Overridepublic void onCameraConfigurationChanged(int cameraID, int displayOrientation) {if (drawHelper != null) {drawHelper.setCameraDisplayOrientation(displayOrientation);}Log.i(TAG, "onCameraConfigurationChanged: " + cameraID + " " + displayOrientation);}};cameraHelper = new CameraHelper.Builder().previewViewSize(new Point(previewView.getMeasuredWidth(), previewView.getMeasuredHeight())).rotation(getWindowManager().getDefaultDisplay().getRotation()).specificCameraId(cameraID != null ? cameraID : Camera.CameraInfo.CAMERA_FACING_FRONT).isMirror(false).previewOn(previewView).cameraListener(cameraListener).build();cameraHelper.init();}@Overridepublic 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) {initEngine();initCamera();if (cameraHelper != null) {cameraHelper.start();}} else {Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_SHORT).show();}}}/*** 删除已经离开的人脸** @param facePreviewInfoList 人脸和trackId列表*/private void clearLeftFace(List<FacePreviewInfo> facePreviewInfoList) {Set<Integer> keySet = requestFeatureStatusMap.keySet();if (compareResultList != null) {for (int i = compareResultList.size() - 1; i >= 0; i--) {if (!keySet.contains(compareResultList.get(i).getTrackId())) {compareResultList.remove(i);adapter.notifyItemRemoved(i);}}}if (facePreviewInfoList == null || facePreviewInfoList.size() == 0) {requestFeatureStatusMap.clear();livenessMap.clear();return;}for (Integer integer : keySet) {boolean contained = false;for (FacePreviewInfo facePreviewInfo : facePreviewInfoList) {if (facePreviewInfo.getTrackId() == integer) {contained = true;break;}}if (!contained) {requestFeatureStatusMap.remove(integer);livenessMap.remove(integer);}}}private void searchFace(final FaceFeature frFace, final Integer requestId) {Observable.create(new ObservableOnSubscribe<CompareResult>() {@Overridepublic void subscribe(ObservableEmitter<CompareResult> emitter) {// Log.i(TAG, "subscribe: fr search start = " + System.currentTimeMillis() + " trackId = " + requestId);//下面的人脸比对信息CompareResult compareResult = FaceServer.getInstance().getTopOfFaceLib(frFace);// Log.i(TAG, "subscribe: fr search end = " + System.currentTimeMillis() + " trackId = " + requestId);if (compareResult == null) {emitter.onError(null);} else {emitter.onNext(compareResult);}}}).subscribeOn(putation()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<CompareResult>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(CompareResult compareResult) {if (compareResult == null || compareResult.getUserName() == null) {requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED);faceHelper.addName(requestId, "VISITOR " + requestId);return;}Log.i(TAG, "onNext:查询到的结果:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA).format(System.currentTimeMillis()) + " trackId = " + requestId + " similar = " + compareResult.getSimilar());if (compareResult.getSimilar() > SIMILAR_THRESHOLD) {boolean isAdded = false;if (compareResultList == null) {requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED);faceHelper.addName(requestId, "VISITOR " + requestId);return;}for (CompareResult compareResult1 : compareResultList) {if (compareResult1.getTrackId() == requestId) {isAdded = true;break;}}if (!isAdded) {//对于多人脸搜索,假如最大显示数量为 MAX_DETECT_NUM 且有新的人脸进入,则以队列的形式移除if (compareResultList.size() >= MAX_DETECT_NUM) {compareResultList.remove(0);adapter.notifyItemRemoved(0);}//添加显示人员时,保存其trackIdcompareResult.setTrackId(requestId);compareResultList.add(compareResult);adapter.notifyItemInserted(compareResultList.size() - 1);}requestFeatureStatusMap.put(requestId, RequestFeatureStatus.SUCCEED);Toast.makeText(RegisterAndRecognizeActivity.this, "人脸比对成功,相似度:" + compareResult.getSimilar(), Toast.LENGTH_LONG).show();faceHelper.addName(requestId, compareResult.getUserName());} else {requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED);faceHelper.addName(requestId, "VISITOR " + requestId);Toast.makeText(RegisterAndRecognizeActivity.this, "人脸比对失败,相似度:" + compareResult.getSimilar(), Toast.LENGTH_LONG).show();}}@Overridepublic void onError(Throwable e) {requestFeatureStatusMap.put(requestId, RequestFeatureStatus.FAILED);}@Overridepublic void onComplete() {}});}/*** 将准备注册的状态置为{@link #REGISTER_STATUS_READY}** @param view 注册按钮*/public void register(View view) {if (registerStatus == REGISTER_STATUS_DONE) {registerStatus = REGISTER_STATUS_READY;}}/*** 在{@link #previewView}第一次布局完成后,去除该监听,并且进行引擎和相机的初始化*/@Overridepublic void onGlobalLayout() {previewView.getViewTreeObserver().removeOnGlobalLayoutListener(this);if (!checkPermissions(NEEDED_PERMISSIONS)) {ActivityCompat.requestPermissions(this, NEEDED_PERMISSIONS, ACTION_REQUEST_PERMISSIONS);} else {initEngine();initCamera();}}}

mainactivity.java请求权限和激活引擎页面

import android.Manifest;import android.content.Intent;import android.content.pm.PackageManager;import android.os.Bundle;import android.support.annotation.NonNull;import android.support.v4.app.ActivityCompat;import android.support.v4.content.ContextCompat;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Toast;import com.arcsoft.face.ErrorInfo;import com.arcsoft.face.FaceEngine;import io.reactivex.Observable;import io.reactivex.ObservableEmitter;import io.reactivex.ObservableOnSubscribe;import io.reactivex.Observer;import io.reactivex.android.schedulers.AndroidSchedulers;import io.reactivex.disposables.Disposable;import io.reactivex.schedulers.Schedulers;/*** @author DELL*/public class MainActivity extends AppCompatActivity {private Toast toast = null;private static final int ACTION_REQUEST_PERMISSIONS = 0x001;/*** 所需的所有权限信息*/private static final String[] NEEDED_PERMISSIONS = new String[]{Manifest.permission.CAMERA,Manifest.permission.READ_PHONE_STATE};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void requestPermission(View view) {if (!checkPermissions(NEEDED_PERMISSIONS)) {ActivityCompat.requestPermissions(this, NEEDED_PERMISSIONS, ACTION_REQUEST_PERMISSIONS);return;}activeEngine();}/*** 激活引擎*/private void activeEngine() {Observable.create(new ObservableOnSubscribe<Integer>() {@Overridepublic void subscribe(ObservableEmitter<Integer> emitter) throws Exception {FaceEngine faceEngine = new FaceEngine();int activeCode = faceEngine.active(MainActivity.this, Constants.APP_ID, Constants.SDK_KEY);emitter.onNext(activeCode);}}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<Integer>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(Integer activeCode) {if (activeCode == ErrorInfo.MOK) {showToast(getString(R.string.active_success));//跳转页面goToFaceIdentification();} else if (activeCode == ErrorInfo.MERR_ASF_ALREADY_ACTIVATED) {// showToast(getString(R.string.already_activated));goToFaceIdentification();} else {// activeCode:94209表示未联网showToast(getString(R.string.active_failed, activeCode));}}@Overridepublic void onError(Throwable e) {}@Overridepublic void onComplete() {}});}@Overridepublic 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) {//激活引擎activeEngine();} else {Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_SHORT).show();}}}private void showToast(String s) {if (toast == null) {toast = Toast.makeText(this, s, Toast.LENGTH_SHORT);toast.show();} else {toast.setText(s);toast.show();}}private boolean checkPermissions(String[] neededPermissions) {if (neededPermissions == null || neededPermissions.length == 0) {return true;}boolean allGranted = true;for (String neededPermission : neededPermissions) {allGranted &= ContextCompat.checkSelfPermission(this, neededPermission) == PackageManager.PERMISSION_GRANTED;}return allGranted;}/*** 打打开人脸识别的方法(注册)*/private void goToFaceIdentification() {Intent intent = new Intent(MainActivity.this, RegisterAndRecognizeActivity.class);startActivity(intent);}}

可以下载我的安装包体验下:​​​​​​​

链接: /s/1tKevp5huoJOlKPU-cwhj5g 提取码: 2yyj 复制这段内容后打开百度网盘手机App,操作更方便哦

体验完apk后可以下载源码:点击下载(注意: 解压后是导入module,不是导入project!!!!!)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。