feat(face): 添加人脸识别距离检测和环境切换时的人脸数据重置功能

- 在FaceHelper中添加人脸宽度小于200像素时的过滤逻辑,避免远距离识别人脸
- 注释掉LoginByFaceActivity中的重复识别状态判断逻辑
- 在PlcSettingActivity中添加协程支持用于异步处理人脸数据清除操作
- 实现环境切换时清空所有人脸数据并重新获取用户人脸缓存的功能
- 修改UserViewModel中回调逻辑,当第一页无数据时返回false而非true
This commit is contained in:
2026-04-02 19:11:51 +08:00
parent 4cbe318ab2
commit 66a0c399ec
4 changed files with 46 additions and 18 deletions
@@ -772,13 +772,13 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
lifecycleScope = lifecycleScope, lifecycleScope = lifecycleScope,
onTick = { remaining -> onTick = { remaining ->
loadLogInfo("resetRecognizeState剩余时间:$remaining") loadLogInfo("resetRecognizeState剩余时间:$remaining")
if (judgeRecognizeState()) return@startCountDown // if (judgeRecognizeState()) return@startCountDown
loadLogInfo("initCountTime onTick = $remaining") loadLogInfo("initCountTime onTick = $remaining")
binding.tvToInit.text = "$remaining" binding.tvToInit.text = "$remaining"
}, },
onFinish = { onFinish = {
loadLogInfo("resetRecognizeState倒计时结束") loadLogInfo("resetRecognizeState倒计时结束")
if (judgeRecognizeState()) return@startCountDown // if (judgeRecognizeState()) return@startCountDown
if (facePreviewInfoList.isNullOrEmpty()) { if (facePreviewInfoList.isNullOrEmpty()) {
goInitActivity() goInitActivity()
} else { } else {
@@ -802,20 +802,20 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
// recognizeViewModel.onPreviewFrame(emptyFrame, true) // recognizeViewModel.onPreviewFrame(emptyFrame, true)
} }
private fun judgeRecognizeState(): Boolean { // private fun judgeRecognizeState(): Boolean {
val rectColor = binding.dualCameraFaceRectView.rectColor // val rectColor = binding.dualCameraFaceRectView.rectColor
if (rectColor == RecognizeColor.COLOR_SUCCESS && currentUserId.isNullOrBlank() // if (rectColor == RecognizeColor.COLOR_SUCCESS && currentUserId.isNullOrBlank()
.not() && facePreviewInfoList.isNullOrEmpty().not() // .not() && facePreviewInfoList.isNullOrEmpty().not()
) { // ) {
//人未离开,再次识别 // //人未离开,再次识别
loadLogInfo("userId=$currentUserId") // loadLogInfo("userId=$currentUserId")
openPlateDebouncer.debounce { // openPlateDebouncer.debounce {
openPlate(currentUserId) // openPlate(currentUserId)
} // }
return true // return true
} // }
return false // return false
} // }
fun goInitActivity() { fun goInitActivity() {
val intent = Intent(context, InitActivity::class.java) val intent = Intent(context, InitActivity::class.java)
@@ -3,7 +3,9 @@ package com.sw.platecabinet.activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import androidx.lifecycle.lifecycleScope
import com.sw.plate.utils.ToastUtils import com.sw.plate.utils.ToastUtils
import com.sw.plate.utils.arcface.faceserver.FaceServer
import com.sw.platecabinet.databinding.ActivityPlcSettingBinding import com.sw.platecabinet.databinding.ActivityPlcSettingBinding
import com.sw.platecabinet.databinding.ItemTitleTimeBinding import com.sw.platecabinet.databinding.ItemTitleTimeBinding
import com.sw.platecabinet.dialog.EnvSwitchDialog import com.sw.platecabinet.dialog.EnvSwitchDialog
@@ -11,6 +13,9 @@ import com.sw.platecabinet.ext.clickWithDebounce
import com.sw.platecabinet.utils.mego.PlcCallback import com.sw.platecabinet.utils.mego.PlcCallback
import com.sw.platecabinet.utils.mego.PlcHelper import com.sw.platecabinet.utils.mego.PlcHelper
import com.sw.platecabinet.utils.mego.PlcStatus import com.sw.platecabinet.utils.mego.PlcStatus
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/** /**
* PLC 控制设置界面 * PLC 控制设置界面
@@ -43,7 +48,22 @@ class PlcSettingActivity : BaseActivity<ActivityPlcSettingBinding>() {
initParamButtons() initParamButtons()
initStatusButton() initStatusButton()
binding.btnSwitchEnv.setOnClickListener { binding.btnSwitchEnv.setOnClickListener {
EnvSwitchDialog(this).show() EnvSwitchDialog(context = this, onEnvChanged = {
showWaitingDialog("重置人脸数据中……")
lifecycleScope.launch {
withContext(Dispatchers.IO) {
FaceServer.getInstance().clearAllFaces()
}
}
userViewModel.getUserFaceCache(pageNo = 1, callback = { state, errMsg ->
hideWaitingDialog()
if (state) {
ToastUtils.showToast("人脸数据已更新")
} else {
ToastUtils.showToast(errMsg)
}
})
}).show()
} }
} }
@@ -64,7 +64,7 @@ class UserViewModel : BaseViewModel() {
SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true) SPUtil.getInstance().put(GlobalKey.KEY_FIRST_RUN, true)
val list: List<UserFaceModel> = response.data ?: emptyList() val list: List<UserFaceModel> = response.data ?: emptyList()
if (pageNo == 1 && list.isEmpty()) { if (pageNo == 1 && list.isEmpty()) {
callback(true, "暂无数据") callback(false, "暂无数据")
return@launchWithLoading return@launchWithLoading
} }
val faceEntityList = list.map { val faceEntityList = list.map {
@@ -343,6 +343,14 @@ public class FaceHelper implements FaceListener {
refreshTrackId(faceInfoList); refreshTrackId(faceInfoList);
if (faceInfoList.isEmpty()) { if (faceInfoList.isEmpty()) {
return facePreviewInfoList; return facePreviewInfoList;
} else {
FaceInfo currentFaceInfo = faceInfoList.get(0);
// L.e("currentFaceInfo width=" + currentFaceInfo.getRect().width() +
// "---height" + currentFaceInfo.getRect().height());
if (currentFaceInfo.getRect().width() < 200) {//距离远(人脸小),不识别
clearLeftFace(facePreviewInfoList);
return facePreviewInfoList;
}
} }
if (!onlyDetectLiveness) { if (!onlyDetectLiveness) {
code = ftEngine.process(rgbNv21, previewSize.width, previewSize.height, FaceEngine.CP_PAF_NV21, faceInfoList, code = ftEngine.process(rgbNv21, previewSize.width, previewSize.height, FaceEngine.CP_PAF_NV21, faceInfoList,