|
@@ -3,8 +3,6 @@ package com.ethan.psbc.ui.dialogs
|
|
|
import android.Manifest
|
|
|
import android.content.Context
|
|
|
import android.content.pm.PackageManager
|
|
|
-import android.content.res.AssetManager
|
|
|
-import android.os.Environment
|
|
|
import android.util.Log
|
|
|
import android.view.View
|
|
|
import android.widget.Toast
|
|
@@ -15,13 +13,16 @@ import androidx.camera.view.PreviewView
|
|
|
import androidx.core.app.ActivityCompat
|
|
|
import androidx.core.content.ContextCompat
|
|
|
import androidx.lifecycle.LifecycleOwner
|
|
|
+import cn.face.sdk.FaceDetTrack
|
|
|
+import cn.face.sdk.FaceInfo
|
|
|
import cn.face.sdk.FaceInterface
|
|
|
import cn.face.sdk.FaceRecog
|
|
|
import com.ethan.psbc.R
|
|
|
-import com.ethan.psbc.constants.ConstantApp
|
|
|
import com.ethan.psbc.databinding.DialogValidateFaceBinding
|
|
|
+import com.ethan.psbc.managers.impls.ImplFaceManager
|
|
|
import com.lxj.xpopup.impl.FullScreenPopupView
|
|
|
-import java.io.*
|
|
|
+import org.koin.core.component.KoinComponent
|
|
|
+import org.koin.core.component.inject
|
|
|
import java.nio.ByteBuffer
|
|
|
import java.util.concurrent.ExecutorService
|
|
|
import java.util.concurrent.Executors
|
|
@@ -30,7 +31,7 @@ import java.util.concurrent.Executors
|
|
|
* <p>人脸验证界面</p>
|
|
|
* @author gy
|
|
|
*/
|
|
|
-class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext){
|
|
|
+class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext), KoinComponent {
|
|
|
|
|
|
|
|
|
|
|
@@ -41,151 +42,25 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext){
|
|
|
}
|
|
|
|
|
|
|
|
|
- init {
|
|
|
- initSdk(mContext)
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- private lateinit var faceConfigFile:File
|
|
|
-
|
|
|
- var faceHandleRet:Int=-1
|
|
|
-
|
|
|
-
|
|
|
|
|
|
- fun initSdk(mContext:Context){
|
|
|
|
|
|
|
|
|
- try {
|
|
|
- Log.d("demo", "访问外部文件权限" + Environment.getExternalStorageState())
|
|
|
|
|
|
|
|
|
- val dirPath= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
|
|
|
|
|
+ val mFace:ImplFaceManager by inject()
|
|
|
|
|
|
|
|
|
- //createModelFileAll(dirPath, mContext.assets)
|
|
|
-
|
|
|
- faceConfigFile = File(dirPath, "CWR_Config_1_1.xml")
|
|
|
-
|
|
|
-
|
|
|
- Log.d("demo", "初始化人脸识别SDK")
|
|
|
- FaceRecog.getInstance();
|
|
|
- faceHandleRet = FaceRecog.cwCreateRecogHandle(faceConfigFile.absolutePath, ConstantApp.faceLicense, 0)
|
|
|
- Log.d("demo", "获取SDK句柄:$faceHandleRet")
|
|
|
- if (faceHandleRet >= FaceInterface.cw_errcode_t.CW_UNKNOWN_ERR) {
|
|
|
- faceHandleRet = -1
|
|
|
- } else {
|
|
|
- faceHandleRet = 0
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- }catch (e:Exception){
|
|
|
- Log.d("demo", "人脸SDK加载失败:"+e.message)
|
|
|
- faceHandleRet = -1
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- fun createModelFileAll(modelDirPath: String, assetManager: AssetManager) {
|
|
|
- val parentDir = "CWModels"
|
|
|
- var fileNameList: List<String?>? = null
|
|
|
- var files: Array<String?>? = null
|
|
|
-
|
|
|
- var fileAbsPath = ""
|
|
|
- fileAbsPath = if (modelDirPath.endsWith("/")) {
|
|
|
- modelDirPath
|
|
|
- } else {
|
|
|
- "$modelDirPath/"
|
|
|
- }
|
|
|
- mkDir(modelDirPath)
|
|
|
- try {
|
|
|
- files = assetManager.list(parentDir)
|
|
|
- fileNameList =files?.toCollection(ArrayList())
|
|
|
- } catch (e: IOException) {
|
|
|
- Log.e("demo", e.message!!)
|
|
|
- }
|
|
|
-
|
|
|
- for (fileName in fileNameList!!) {
|
|
|
- Log.e("demo", fileName!!)
|
|
|
- val modelFile = File(fileAbsPath + fileName)
|
|
|
- if (!modelFile.exists()) {
|
|
|
- copyRawFileToSdcard(parentDir + File.separator + fileName, assetManager, fileAbsPath + fileName)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- fun mkDir(dirPath: String) {
|
|
|
- val dirArray = dirPath.split("/".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
|
|
- var pathTemp = ""
|
|
|
- for (i in 1 until dirArray.size) {
|
|
|
- pathTemp = pathTemp + "/" + dirArray[i]
|
|
|
- val newF = File(dirArray[0] + pathTemp)
|
|
|
- if (!newF.exists()) {
|
|
|
- newF.mkdir()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- fun copyRawFileToSdcard(rawFileName: String?, assetManager: AssetManager, outPutFileAbs: String?) {
|
|
|
- var inputStream: InputStream? = null
|
|
|
- try {
|
|
|
- inputStream = assetManager.open(rawFileName!!)
|
|
|
- } catch (e: IOException) {
|
|
|
- Log.e("tag", e.message!!)
|
|
|
- }
|
|
|
-
|
|
|
- if (inputStream != null) inputStreamToFile(inputStream, outPutFileAbs)
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- fun inputStreamToFile(inputStream: InputStream, absPath: String?) {
|
|
|
- val outputStream = ByteArrayOutputStream()
|
|
|
-
|
|
|
-
|
|
|
- val bufferSize = 1024
|
|
|
- val buffer = ByteArray(bufferSize)
|
|
|
- var length: Int
|
|
|
-
|
|
|
- try {
|
|
|
- while (inputStream.read(buffer).also { length = it } != -1) {
|
|
|
- outputStream.write(buffer, 0, length)
|
|
|
- }
|
|
|
- } finally {
|
|
|
- inputStream.close()
|
|
|
- outputStream.close()
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- try {
|
|
|
- val imgBytes = outputStream.toByteArray()
|
|
|
- val fos = FileOutputStream(absPath, false)
|
|
|
- fos.write(imgBytes)
|
|
|
- fos.close()
|
|
|
- } catch (e: IOException) {
|
|
|
- e.printStackTrace()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
+ var faceHandleRet:Int=-1
|
|
|
|
|
|
override fun onCreate() {
|
|
|
super.onCreate()
|
|
|
mBinding = DialogValidateFaceBinding.bind(popupContentView)
|
|
|
+ val faceHandleRet:Int=mFace.initSdk()
|
|
|
+ this.faceHandleRet=faceHandleRet
|
|
|
+ runCamera(this, mBinding.mPreviewView, faceHandleRet, context = context)
|
|
|
mBinding.cameraLayout.visibility= View.VISIBLE
|
|
|
mBinding.mPreviewView.bringToFront()
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- runCamera( this ,mBinding.mPreviewView,faceHandleRet)
|
|
|
-
|
|
|
}
|
|
|
|
|
|
|
|
@@ -197,7 +72,7 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext){
|
|
|
private lateinit var imageAnalysis: ImageAnalysis
|
|
|
|
|
|
|
|
|
- fun runCamera(lifecycleOwner:LifecycleOwner, previewView: PreviewView?, handle:Int){
|
|
|
+ fun runCamera(lifecycleOwner:LifecycleOwner, previewView: PreviewView?, handle:Int,context: Context){
|
|
|
|
|
|
if( PackageManager.PERMISSION_GRANTED!= ContextCompat.checkSelfPermission(context , Manifest.permission.CAMERA)){
|
|
|
ActivityCompat.requestPermissions(context as AppCompatActivity, arrayOf(Manifest.permission.CAMERA),1)
|
|
@@ -246,16 +121,42 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext){
|
|
|
buffer.get(data)
|
|
|
|
|
|
|
|
|
- if(handle==-1){
|
|
|
- Log.d("demo", "SDK无法使用")
|
|
|
- }else{
|
|
|
- val iFeaLen:Int = FaceRecog.cwGetFeatureLength(handle)
|
|
|
- Log.d("demo", "获取到人脸特征长度${iFeaLen}")
|
|
|
- }
|
|
|
+ //第一步调用人脸跟踪API分析图像流特征
|
|
|
|
|
|
|
|
|
|
|
|
+ if(handle==-1){
|
|
|
+ Log.d("demo", "SDK无法使用:SDK未初始化加载成功")
|
|
|
+ }else {
|
|
|
+ Log.d("demo", "SDK可以使用")
|
|
|
+ try{
|
|
|
+ val iFeaLen =FaceRecog.cwGetFeatureLength(handle)
|
|
|
+ Log.d("demo", "获取到人脸特征长度:${iFeaLen}")
|
|
|
+
|
|
|
+ var pFaceBuffer=Array(3){_ ->FaceInfo()}
|
|
|
+ val faceDetRet:Int= FaceDetTrack.cwFaceDetection(handle,data,0, 0, FaceInterface.cw_img_form_t.CW_IMAGE_BINARY, 0, 0, FaceInterface.cw_op_t.CW_OP_ALIGN , pFaceBuffer)
|
|
|
+ if (faceDetRet >= FaceInterface.cw_errcode_t.CW_UNKNOWN_ERR) {
|
|
|
+ Log.d("demo", "检测到人脸异常:${faceDetRet}" )
|
|
|
+ }else if(faceDetRet<1){
|
|
|
+ Log.d("demo", "未检测到人脸:${faceDetRet}" )
|
|
|
+ }else{
|
|
|
+ Log.d("demo", "检测到人脸" )
|
|
|
+ val btFeature=ByteArray(iFeaLen)
|
|
|
+ FaceRecog.cwGetFaceFeature(handle,pFaceBuffer[0].alignedData,pFaceBuffer[0].alignedW,
|
|
|
+ pFaceBuffer[0].alignedH,pFaceBuffer[0].nChannels, btFeature)
|
|
|
+
|
|
|
+ var scores=FloatArray(1)
|
|
|
+ FaceRecog.cwComputeMatchScore(handle,btFeature,btFeature,1,scores)
|
|
|
+ Log.d("demo", "检测到相似度为:${scores[0]}" )
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }catch (e:Exception){
|
|
|
+ Log.d("demo", "人脸识别异常:${e.message}")
|
|
|
+ }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
|
@@ -287,6 +188,12 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext){
|
|
|
}
|
|
|
|
|
|
|
|
|
+ override fun onDismiss() {
|
|
|
+ mFace.release(this.faceHandleRet)
|
|
|
+ super.onDismiss()
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
|