人脸识别小于阈值时增加重试次数,降低识别错误情况
This commit is contained in:
@@ -1,27 +1,21 @@
|
|||||||
package com.sw.platecabinet.activity
|
package com.sw.platecabinet.activity
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Point
|
import android.graphics.Point
|
||||||
import android.hardware.Camera
|
import android.hardware.Camera
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.CountDownTimer
|
import android.os.CountDownTimer
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.util.Log
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewTreeObserver
|
import android.view.ViewTreeObserver
|
||||||
import androidx.activity.viewModels
|
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import com.arcsoft.face.ErrorInfo
|
import com.arcsoft.face.ErrorInfo
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.sw.platecabinet.socket.TcpClientListenerImpl
|
import com.sw.platecabinet.socket.TcpClientListenerImpl
|
||||||
import com.sw.inbound.utils.DateTimeUtils
|
import com.sw.inbound.utils.DateTimeUtils
|
||||||
import com.sw.plate.App
|
|
||||||
import com.sw.plate.utils.Base64
|
import com.sw.plate.utils.Base64
|
||||||
import com.sw.plate.utils.ToastUtils
|
import com.sw.plate.utils.ToastUtils
|
||||||
import com.sw.plate.utils.arcface.ConfigUtil
|
import com.sw.plate.utils.arcface.ConfigUtil
|
||||||
@@ -44,34 +38,22 @@ import com.sw.plate.utils.arcface.viewmodel.RecognizeViewModel.REGISTER_STATUS_R
|
|||||||
import com.sw.platecabinet.GlobalData
|
import com.sw.platecabinet.GlobalData
|
||||||
import com.sw.platecabinet.MyApp
|
import com.sw.platecabinet.MyApp
|
||||||
import com.sw.platecabinet.R
|
import com.sw.platecabinet.R
|
||||||
import com.sw.platecabinet.adapter.LogAdapter
|
|
||||||
import com.sw.platecabinet.databinding.ActivityLoginFaceBinding
|
import com.sw.platecabinet.databinding.ActivityLoginFaceBinding
|
||||||
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
|
import com.sw.platecabinet.databinding.ItemTitleTimeBinding
|
||||||
import com.sw.platecabinet.ext.gone
|
|
||||||
import com.sw.platecabinet.ext.invisible
|
|
||||||
import com.sw.platecabinet.ext.visible
|
|
||||||
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
import com.sw.platecabinet.model.response.EquipmentUserInfo
|
||||||
import com.sw.platecabinet.socket.LanServer
|
import com.sw.platecabinet.socket.LanServer
|
||||||
import com.sw.platecabinet.socket.LanServerListenerImpl
|
import com.sw.platecabinet.socket.LanServerListenerImpl
|
||||||
import com.sw.platecabinet.socket.TcpClient
|
import com.sw.platecabinet.socket.TcpClient
|
||||||
import com.sw.platecabinet.utils.Debouncer
|
import com.sw.platecabinet.utils.Debouncer
|
||||||
import com.sw.platecabinet.utils.IntervalExecutor
|
|
||||||
import com.sw.platecabinet.utils.PermissionHelper
|
import com.sw.platecabinet.utils.PermissionHelper
|
||||||
import com.sw.platecabinet.utils.PlateUtils
|
import com.sw.platecabinet.utils.PlateUtils
|
||||||
import com.sw.platecabinet.utils.SoundPoolUtil
|
import com.sw.platecabinet.utils.SoundPoolUtil
|
||||||
import com.sw.platecabinet.utils.SpTool
|
import com.sw.platecabinet.utils.SpTool
|
||||||
import com.sw.platecabinet.utils.countDownByFlow
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.concurrent.Executors
|
|
||||||
import java.util.concurrent.ScheduledExecutorService
|
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
import kotlin.math.log
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 人脸识别
|
* 人脸识别
|
||||||
@@ -252,21 +234,11 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
|
|
||||||
recognizeViewModel.recognizeUserId.observe(this, Observer { result: CompareResult? ->
|
recognizeViewModel.recognizeUserId.observe(this, Observer { result: CompareResult? ->
|
||||||
loadLogInfo("collectFace,recognizeUserId observe userId = ${result?.faceEntity?.userName}")
|
loadLogInfo("collectFace,recognizeUserId observe userId = ${result?.faceEntity?.userName}")
|
||||||
val similar = result?.similar?:0f
|
if (faceUseSwitch) {
|
||||||
binding.tvSimilarValue.text="$similar"
|
loadFaceRecognizeResult2(result)
|
||||||
val similarPass = result?.isSimilarPass?:false
|
|
||||||
if (similarPass.not()) {
|
|
||||||
loadLogInfo("collectFace,recognizeUserId 未识别到人脸信息,开始采集")
|
|
||||||
isCollectFace = true
|
|
||||||
collectFace()
|
|
||||||
return@Observer
|
return@Observer
|
||||||
}
|
}
|
||||||
currentUserId = result?.faceEntity?.userName
|
loadFaceRecognizeResult(result)
|
||||||
if (tempUserId != currentUserId) {
|
|
||||||
SoundPoolUtil.getInstance().play("success", 0)
|
|
||||||
}
|
|
||||||
// plateEnable = true
|
|
||||||
openPlate(currentUserId)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
recognizeViewModel.drawRectInfoText.observe(this, Observer { info ->
|
recognizeViewModel.drawRectInfoText.observe(this, Observer { info ->
|
||||||
@@ -274,6 +246,84 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人脸识别开关,true-loadFaceRecognizeResult2,false-loadFaceRecognizeResult
|
||||||
|
*/
|
||||||
|
private var faceUseSwitch = true
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 识别失败重试次数
|
||||||
|
*/
|
||||||
|
private var retryFailCount = 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 识别失败最大次数
|
||||||
|
*/
|
||||||
|
private val maxFailCount = 5
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人脸失败阈值
|
||||||
|
*/
|
||||||
|
private val faceFailThreshold = 0.3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置阈值,默认值为0.8
|
||||||
|
*/
|
||||||
|
private val faceSuccessThreshold by lazy { ConfigUtil.getRecognizeThreshold(this) }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据相似度similar>设定阈值0.8作为识别成功判断,
|
||||||
|
* 如果similar<0.3作为识别失败判断,
|
||||||
|
* 如果similar>=0.3&&similar<=0.8时,暂时不作为失败情况,再识别5次如果similar<0.8则作为识别失败处理
|
||||||
|
*/
|
||||||
|
private fun loadFaceRecognizeResult2(result: CompareResult?) {
|
||||||
|
val similar = result?.similar?:0f
|
||||||
|
binding.tvSimilarValue.text="$similar"
|
||||||
|
loadLogInfo("collectFace,recognizeUserId 人脸识别配置阈值为:${faceSuccessThreshold},失败阈值为:${faceFailThreshold},相似度为:${similar},失败次数为:${retryFailCount}")
|
||||||
|
if (similar > faceSuccessThreshold) {
|
||||||
|
//大于识别阈值,作为识别成功判断
|
||||||
|
currentUserId = result?.faceEntity?.userName
|
||||||
|
if (tempUserId != currentUserId) {
|
||||||
|
SoundPoolUtil.getInstance().play("success", 0)
|
||||||
|
}
|
||||||
|
openPlate(currentUserId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
loadLogInfo("collectFace,recognizeUserId 人脸识别相似度为:${similar},失败次数为:${retryFailCount}")
|
||||||
|
if (similar < faceFailThreshold || retryFailCount >= maxFailCount) {
|
||||||
|
//小于识别错误阈值,或者识别失败次数大于等于最大失败次数,作为识别失败判断
|
||||||
|
loadLogInfo("collectFace,recognizeUserId 未识别到人脸信息,开始采集")
|
||||||
|
isCollectFace = true
|
||||||
|
collectFace()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//满足similar >= faceFailThreshold && similar <= successThreshold时进行重试
|
||||||
|
retryFailCount++
|
||||||
|
loadLogInfo("collectFace,recognizeUserId 人脸识别失败次数为:${retryFailCount}")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据相似度similar>设定阈值0.8作为识别是否成功来加载人脸识别结果
|
||||||
|
*/
|
||||||
|
private fun loadFaceRecognizeResult(result: CompareResult?) {
|
||||||
|
val similar = result?.similar?:0f
|
||||||
|
binding.tvSimilarValue.text="$similar"
|
||||||
|
val similarPass = result?.isSimilarPass?:false
|
||||||
|
if (similarPass.not()) {
|
||||||
|
loadLogInfo("collectFace,recognizeUserId 未识别到人脸信息,开始采集")
|
||||||
|
isCollectFace = true
|
||||||
|
collectFace()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
currentUserId = result?.faceEntity?.userName
|
||||||
|
if (tempUserId != currentUserId) {
|
||||||
|
SoundPoolUtil.getInstance().play("success", 0)
|
||||||
|
}
|
||||||
|
// plateEnable = true
|
||||||
|
openPlate(currentUserId)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询餐盘数据
|
* 查询餐盘数据
|
||||||
*/
|
*/
|
||||||
@@ -559,6 +609,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
}, 1000)
|
}, 1000)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
retryFailCount = 0
|
||||||
binding.tvSimilarValue.text=""
|
binding.tvSimilarValue.text=""
|
||||||
isCollectFace = false
|
isCollectFace = false
|
||||||
plateEnable = true
|
plateEnable = true
|
||||||
@@ -595,7 +646,7 @@ class LoginByFaceActivity : BaseActivity<ActivityLoginFaceBinding>(),
|
|||||||
// goInitActivity()
|
// goInitActivity()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val totalTimeInMillis = 10 * 1000L
|
private val totalTimeInMillis = 15 * 1000L
|
||||||
fun initCountTime() {
|
fun initCountTime() {
|
||||||
countDownTimer = object : CountDownTimer(totalTimeInMillis, 1000) {
|
countDownTimer = object : CountDownTimer(totalTimeInMillis, 1000) {
|
||||||
override fun onTick(millisUntilFinished: Long) {
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
|
|||||||
Reference in New Issue
Block a user