everywindchase 1 год назад
Родитель
Сommit
f06614b952

+ 1 - 1
app/build.gradle

@@ -10,7 +10,7 @@ android {
         applicationId "com.ethan.psbc"
         minSdk libs.versions.minSdk.get().toInteger()
         targetSdk libs.versions.compileSdk.get().toInteger()
-        versionCode 30
+        versionCode 32
         versionName "1.1.6"
         setProperty('archivesBaseName', "PSBC-$versionName-$versionCode-" + (new Date()).format('yyyyMMdd'))
         ndk { abiFilters    "armeabi","x86","x86_64","armeabi-v7a","arm64-v8a" }

+ 15 - 1
app/src/main/AndroidManifest.xml

@@ -7,6 +7,8 @@
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
 
+
+
     <uses-permission android:name="android.permission.CAMERA" />
 
     <queries>
@@ -17,6 +19,15 @@
 
 
 
+    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE "/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+
+
+
+
+
+
     <application
         android:name=".apps.Application"
         android:allowBackup="false"
@@ -26,7 +37,10 @@
         android:supportsRtl="true"
         android:theme="@style/AppTheme"
         android:usesCleartextTraffic="true"
-        tools:ignore="LockedOrientationActivity,DiscouragedApi">
+        tools:ignore="LockedOrientationActivity,DiscouragedApi"
+
+        android:requestLegacyExternalStorage="true"
+        >
 
         <activity
             android:name=".ui.activities.ActivitySplash"

+ 26 - 0
app/src/main/assets/CWModels/CWR_Config_1_1.xml

@@ -0,0 +1,26 @@
+<VERSION>180523_se_128</VERSION>
+<ModelType>modelp</ModelType>
+<CloudWalk>	
+ 	<MODELP>
+		<MODEL>
+			<NETS>
+				<NET>
+					<Model>feature.bin</Model>
+					<Weights>featureWeight.bin</Weights>
+					<OutFeature>feature_norm</OutFeature>
+				</NET>
+			</NETS>
+			<PCA> 
+				<Model>pca_proj.bin</Model>
+			</PCA>
+			<LDA> 
+				<Mu>-147.2</Mu>
+				<Sigma>0.02416</Sigma>
+				<Model>mdl.bin</Model>
+			</LDA>
+			<TRANS> 
+				<Flip>false</Flip>
+			</TRANS>
+		</MODEL>
+	</MODELP>
+</CloudWalk>

+ 96 - 0
app/src/main/assets/CWModels/_configs_frontend_x86_arm.xml

@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+<opencv_storage>
+<!-- VIP Frontend Configurations by Cloudwalk. -->
+<!-- 如果使用默认参数值,注释相应行即可 -->
+<VIP_Frontend>
+  <!-- 创建句柄所需初始化参数 -->
+  <Face_INIT_Params>
+    <!-- 前端worker数,范围1~6. 默认3. (建议根据实际设备性能和应用情景设置最佳值,如E5上10路建议设为2或者3) -->
+    <Worker_Num>3</Worker_Num>
+    <!-- 检测器尺度计算worker数,范围1~6,默认3,可根据实际情况启动多workers -->
+    <Worker_DETS_Num>3</Worker_DETS_Num>
+    <!-- 检测器滑窗计算worker数,范围1~6,默认1,可根据实际情况启动多workers(效果不如尺度并行,核心数很多时建议进行分配) -->
+    <Worker_DETW_Num>2</Worker_DETW_Num>
+    <!-- 加载模型方式(0-文件方式),dl版暂时支持文件模式 -->
+    <Model_Mode>0</Model_Mode>
+    <!-- 人脸检测器模型(文件方式时有效, DL版) -->
+    <str_face_detect_model_dl>faceDetector_3_15deepnet1_4_3.mdl</str_face_detect_model_dl>
+    <!-- 人脸检测器模型(文件方式时有效, 非DL版) -->
+    <str_face_detect_model>faceDetector_2_4.mdl</str_face_detect_model>
+    <!-- dl关键点检测器模型(文件方式时有效) -->
+    <str_face_keypt_model_dl>landmarks_2_0_2.bin</str_face_keypt_model_dl>
+    <!-- 质量分检测器模型(文件方式时有效) -->
+    <str_face_quality_model>face_quality_4_2.bin</str_face_quality_model>
+    <!-- Face_INIT_Params -->
+    </Face_INIT_Params>
+  <!-- 接口功能参数 -->
+  <Face_DetTrack_Params>
+    <!-- 每帧最大人脸数 -->
+    <Faces_Num_Max_Frame>20</Faces_Num_Max_Frame>
+    <!-- 检出性能,范围1-10,越大检出率越低,但误检越小. 默认2 -->
+    <Neighbors_Num_Min>2</Neighbors_Num_Min>
+    <!-- 检测精细度,范围1.1 ~ 1.80,越大速度越快,但越不精细. 默认1.20 -->
+    <scale_up_ratio>1.2000000476837158e+000</scale_up_ratio>
+    <!-- 检测精细度,范围0.9 ~ 0.3,越小速度越快,但越不精细. 默认0.709 -->
+    <scale_up_ratio_dl>7.0899999141693115e-001</scale_up_ratio_dl>
+    <!-- 检测精细度,范围大于等于1,越大速度越慢,但越精细。默认2(此参数建议不动) -->
+    <step_win_in_pixel_dl>2</step_win_in_pixel_dl>
+    <!-- 检测精细度,范围0.1 ~ 0.25,越大速度越快,但越不精细. 默认0.13 -->
+    <Win_Step_Ratio>1.2999999523162842e-001</Win_Step_Ratio>
+    <!-- 局部检测子图扩展比例,范围[1.4,3.0],默认1.80 -->
+    <Local_ImgSize_Expand_Ratio>1.7999999523162842e+000</Local_ImgSize_Expand_Ratio>
+    <!-- 局部检测人脸扩展比,范围[1.2~1.5],默认1.30 -->
+    <Local_FaceSize_Range_Ratio>1.2999999523162842e+000</Local_FaceSize_Range_Ratio>
+    <!-- 跟踪开关下,后续计算(关键点或对齐或质量分)开关打开时的隔帧参数,范围[0,2],0-所有检测人脸都进行后续计算,1-仅全局检测人脸不计算,2-每隔一帧进行后续计算. 默认2 -->
+    <Post_Detect_Frequency>0</Post_Detect_Frequency>
+    <!-- 没有检测到的人脸是否进行“串联+跟踪”.0关闭,非0开启,默认1开启 -->
+    <Lost_Track>1</Lost_Track>
+    <!-- 预跟踪帧数,默认2 -->
+    <Frame_Num_For_New>2</Frame_Num_For_New>
+    <!-- 检测性能水平,相当于检测图缩小比例,范围(1~6).数字越小缩小比例越大,反之亦然.默认1,如果性能不好建议6(不做任何缩放),如果检测超大图可设置1~5. -->
+    <Perfmon_Level>1</Perfmon_Level>
+    <!-- 图像预处理方式, 0-不做任何处理, 1-高斯模糊预处理, 其他-不错处理, 默认0不做预处理. -->
+    <Image_Preprocess_Mode>0</Image_Preprocess_Mode>
+    <!-- 对齐人脸图颜色空间类型:1-灰度图;2-双通道图;3-彩色图 -->
+    <ImgAligned_Color_Mode>1</ImgAligned_Color_Mode>
+    <!-- 静态误检过滤所需人脸框数量,为正则启动过滤,为0或者为负则不启动,默认0不启动。 -->
+    <Fake_Face_Filter_Aggregate>0.</Fake_Face_Filter_Aggregate>
+    <!-- 是否过滤比设定的最小人脸还小的人脸,0-不过滤,非0-过滤 -->
+    <face_filter_over_small>1</face_filter_over_small>
+    <!-- 等时间间距选最佳人脸策略下的第一阶段如果有人脸过此阈值,直接抛出该阶段的最佳人脸 -->
+    <best_face_first_threshold>8.0000001192092896e-001</best_face_first_threshold>
+    <!-- 是否打开检测器属性:1-打开,其他关闭。默认打开。 -->
+    <open_property_by_detector>0</open_property_by_detector>
+    <!-- 检测角度过滤阈值,建议0.125。值越大速度越快,越多的人脸(质量较差的)被滤掉,折中考虑. -->
+    <filt_by_detected_angle_threshold>0</filt_by_detected_angle_threshold>
+    <!-- 是否启动快速质量分模式(使用关键点得分作为质量总分,其他质量分项将无意义),1开启,其他关闭 -->
+    <fast_quality_mode>0</fast_quality_mode>
+    <!-- 算法是否复用用户传进来的图像data. -->
+    <frame_data_reused>1</frame_data_reused>
+    <!-- 总分开关 -->
+    <Quality_TotalScore_Switch>1</Quality_TotalScore_Switch>
+    <!-- 模糊光照分开关 -->
+    <Quality_IMG_Switch>0</Quality_IMG_Switch>
+    <!-- 肤色真假分开关 -->
+    <Quality_Skinness_Switch>1</Quality_Skinness_Switch>
+    <!-- 姿态(角度)分开关 -->
+    <Quality_Pose_Switch>0</Quality_Pose_Switch>
+    <!-- 眼睛分开关 -->
+    <Quality_EyeOpenness_Switch>0</Quality_EyeOpenness_Switch>
+    <!-- 嘴巴分开关 -->
+    <Quality_MouthOpenness_Switch>0</Quality_MouthOpenness_Switch>
+    <!-- 黑框眼镜分开关 -->
+    <Quality_BlackFrameglass_Switch>0</Quality_BlackFrameglass_Switch>
+    <!-- 墨镜分开关 -->
+    <Quality_Sunglass_Switch>0</Quality_Sunglass_Switch>
+    <!-- 眼睛被遮挡分开关 -->
+    <Quality_EyeOcclusion_Switch>0</Quality_EyeOcclusion_Switch>
+    <!-- mog清晰度分开关 -->
+    <Quality_MogClearness_Switch>0</Quality_MogClearness_Switch>
+    <!-- 所有质量开关综合 -->
+    <All_Score_Switch>0</All_Score_Switch>
+    <!-- Face_DetTrack_Params -->
+    </Face_DetTrack_Params>
+  <!-- VIP Frontend Configurations by Cloudwalk. -->
+  </VIP_Frontend>
+</opencv_storage>

BIN
app/src/main/assets/CWModels/feature.bin


BIN
app/src/main/assets/CWModels/featureWeight.bin


BIN
app/src/main/assets/CWModels/mdl.bin


BIN
app/src/main/assets/CWModels/pca_proj.bin


+ 19 - 0
app/src/main/java/com/ethan/psbc/ui/activities/ActivityLogin.kt

@@ -1,9 +1,14 @@
 package com.ethan.psbc.ui.activities
 
+import android.Manifest
 import android.app.Activity
+import android.content.pm.PackageManager
 import android.os.Bundle
 import android.view.View
 import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
+import androidx.core.content.ContextCompat
 import androidx.lifecycle.lifecycleScope
 import com.ethan.psbc.commons.IViewOnNoDoubleClickListener
 import com.ethan.psbc.databinding.ActivityLoginBinding
@@ -52,7 +57,21 @@ internal class ActivityLogin : ActivityBase(), KoinComponent, IViewOnNoDoubleCli
 
 
 
+        if( PackageManager.PERMISSION_GRANTED!= ContextCompat.checkSelfPermission( mContext   , Manifest.permission.WRITE_EXTERNAL_STORAGE)){
+            ActivityCompat.requestPermissions(mContext    as AppCompatActivity, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),1)
+            Toast.makeText(mContext    as AppCompatActivity, "申请外部写权限", Toast.LENGTH_SHORT).show()
+        }else{
+            Toast.makeText(mContext    as AppCompatActivity, "已拥有外部写权限", Toast.LENGTH_SHORT).show()
+        }
+
 
+
+        if( PackageManager.PERMISSION_GRANTED!= ContextCompat.checkSelfPermission( mContext   , Manifest.permission.MANAGE_EXTERNAL_STORAGE)){
+            ActivityCompat.requestPermissions(mContext    as AppCompatActivity, arrayOf(Manifest.permission.MANAGE_EXTERNAL_STORAGE),1)
+            Toast.makeText(mContext    as AppCompatActivity, "申请外部写权限2", Toast.LENGTH_SHORT).show()
+        }else{
+            Toast.makeText(mContext    as AppCompatActivity, "已拥有外部写权限2", Toast.LENGTH_SHORT).show()
+        }
     }
 
     override suspend fun onCreateBySuspend(savedInstanceState: Bundle?) {

+ 2 - 2
app/src/main/java/com/ethan/psbc/ui/dialogs/DialogValidateFace.kt

@@ -27,8 +27,8 @@ class DialogValidateFace( mContext: Context) : FullScreenPopupView(mContext){
     override  fun onCreate() {
         super.onCreate()
         mBinding = DialogValidateFaceBinding.bind(popupContentView)
-       //mBinding.cameraScan.bringToFront()
-
+        mBinding.mPreviewView.bringToFront()
+        mBinding.cameraScan.mPreview=mBinding.mPreviewView
 
 
 

+ 54 - 23
app/src/main/java/com/ethan/psbc/ui/widgets/CameraScanView.kt

@@ -4,6 +4,7 @@ import android.Manifest
 import android.content.Context
 import android.content.pm.PackageManager
 import android.graphics.*
+import android.os.Environment
 import android.util.AttributeSet
 import android.util.Log
 import android.view.SurfaceHolder
@@ -13,16 +14,18 @@ import androidx.appcompat.app.AppCompatActivity
 import androidx.camera.core.*
 import androidx.camera.core.Camera
 import androidx.camera.lifecycle.ProcessCameraProvider
+import androidx.camera.view.PreviewView
 import androidx.core.app.ActivityCompat
 import androidx.core.content.ContextCompat
-import cn.face.sdk.FaceDetTrack
 import cn.face.sdk.FaceInterface
-import cn.face.sdk.FaceParam
+import cn.face.sdk.FaceRecog
+import java.io.File
 import java.nio.ByteBuffer
 import java.util.concurrent.ExecutorService
 import java.util.concurrent.Executors
 import kotlin.math.min
 
+
 class CameraScanView(mContext: Context, attrs:AttributeSet?, defStyleAttr:Int) : SurfaceView(mContext,attrs,defStyleAttr) {
 
     constructor(context: Context) : this(context, null)
@@ -30,14 +33,45 @@ class CameraScanView(mContext: Context, attrs:AttributeSet?, defStyleAttr:Int) :
 
     private val mLogger: org.slf4j.Logger = org.slf4j.LoggerFactory.getLogger(this.javaClass)
 
-    private lateinit var holder:SurfaceHolder
+    private var holder:SurfaceHolder
 
     private var mSurfaceCallback= SurfaceCallback(mContext)
 
+    private lateinit    var faceConfigFile:File
+
     init {
         holder=getHolder()
         holder.addCallback(mSurfaceCallback)
 
+       Log.d("demo","访问外部文件权限"+Environment.getExternalStorageState())
+
+
+
+        val  dir:File = File(Environment.getExternalStorageDirectory().absolutePath + File.separator ,"CWModels")
+
+        if(!dir.exists()) {
+            dir.mkdir()
+        }
+
+        faceConfigFile=File(dir,"CWR_Config_1_1.xml")
+        faceConfigFile.createNewFile()
+
+        mContext.assets.open("CWModels/CWR_Config_1_1.xml").use {
+            faceConfigFile.writeText(it.reader(charset = Charsets.UTF_8).readText())
+        }
+
+       val licence:String="MDQwNTE3NWQyNTkzNGM4MmQ3ZDk2MmQyM2UzODBhMmI1YjFjNjdjd2F1dGhvcml6Zd3n5+Xk5+fk/OXm5+fg5ef15efn5+Xk4Mfl4OXm5uvliObm6+Xm5uuR5ebm6+Xm5qLr5ebm6+Xmrubg5ufr5+v95+vn4OTk59Dk5ubr5+vn1uvn5+fm5Of+5g=="
+        Log.d("demo", "正在识别图像信息")
+        FaceRecog.getInstance();
+        val ret: Int = FaceRecog.cwCreateRecogHandle(  faceConfigFile.path, licence,0)
+        if (ret >= FaceInterface.cw_errcode_t.CW_UNKNOWN_ERR) {
+            Log.d("demo", "启用识别程序SDK失败")
+        } else {
+            Log.d("demo", "启用识别程序SDK成功")
+            var iFeaLen:Int = FaceRecog.cwGetFeatureLength(ret)
+            Log.d("demo", "获取到人脸特征长度${iFeaLen}")
+
+        }
 
 
     }
@@ -66,6 +100,8 @@ class CameraScanView(mContext: Context, attrs:AttributeSet?, defStyleAttr:Int) :
     private var mCenterY:Float=0.0f
     private var mCenterX:Float=0.0f
     private var mRadius:Float=160f
+
+    lateinit   var mPreview:PreviewView
     override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec)
         mWidth = (measuredWidth - paddingLeft - paddingRight).toFloat()
@@ -79,9 +115,11 @@ class CameraScanView(mContext: Context, attrs:AttributeSet?, defStyleAttr:Int) :
         }
 
 
-        mSurfaceCallback.mCenterX=this@CameraScanView.mCenterX;
-        mSurfaceCallback.mCenterY=this@CameraScanView.mCenterY;
-        mSurfaceCallback.mRadius=this@CameraScanView.mRadius;
+        mSurfaceCallback.mCenterX=this@CameraScanView.mCenterX
+        mSurfaceCallback.mCenterY=this@CameraScanView.mCenterY
+        mSurfaceCallback.mRadius=this@CameraScanView.mRadius
+        mSurfaceCallback.mPreview=this@CameraScanView.mPreview
+        mSurfaceCallback.faceConfigFile=this@CameraScanView.faceConfigFile
     }
 
 
@@ -118,6 +156,8 @@ class CameraScanView(mContext: Context, attrs:AttributeSet?, defStyleAttr:Int) :
          var mCenterY:Float=0.0f
          var mCenterX:Float=0.0f
          var mRadius:Float=160f
+        lateinit   var mPreview:PreviewView
+        var faceConfigFile:File?=null
 
 
         override fun surfaceCreated(holder: SurfaceHolder) {
@@ -159,10 +199,13 @@ class CameraScanView(mContext: Context, attrs:AttributeSet?, defStyleAttr:Int) :
             canvas.drawCircle(mCenterX, mCenterY, mRadius, mCirclePaint)
 
             holder.unlockCanvasAndPost(canvas);
+
+
+            runCamera(tContext,holder,mPreview)
         }
 
         override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
-            runCamera(tContext,holder)
+
         }
 
         override fun surfaceDestroyed(holder: SurfaceHolder) {
@@ -173,7 +216,7 @@ class CameraScanView(mContext: Context, attrs:AttributeSet?, defStyleAttr:Int) :
 
 
 
-        fun runCamera(context: Context,holder: SurfaceHolder){
+        fun runCamera(context: Context,holder: SurfaceHolder,previewView: PreviewView?){
 
             if( PackageManager.PERMISSION_GRANTED!= ContextCompat.checkSelfPermission(context    , Manifest.permission.CAMERA)){
                 ActivityCompat.requestPermissions(context    as AppCompatActivity, arrayOf(Manifest.permission.CAMERA),1)
@@ -184,7 +227,7 @@ class CameraScanView(mContext: Context, attrs:AttributeSet?, defStyleAttr:Int) :
 
 
             val  cameraSelector: CameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()
-            // mBinding.btnDemoView.implementationMode= PreviewView.ImplementationMode.COMPATIBLE
+
 
 
 
@@ -222,22 +265,10 @@ class CameraScanView(mContext: Context, attrs:AttributeSet?, defStyleAttr:Int) :
                     buffer.rewind()
                     buffer.get(data)
 
+                    faceConfigFile?.path
 
 
-                    Log.d("demo", "正在识别图像信息")
-                    FaceDetTrack.getInstance()
-                    val ret: Int = FaceDetTrack.cwCreateDetHandle("", licence)
-                    if (ret >= FaceInterface.cw_errcode_t.CW_UNKNOWN_ERR) {
-                        Log.d("demo", "启用识别程序SDK失败")
-                    } else {
-                        Log.d("demo", "启用识别程序SDK成功")
-                        val faceParam = FaceParam()
-                        FaceDetTrack.cwGetFaceParam(ret, faceParam)
-                        faceParam.minSize = 30
-                        faceParam.maxSize = 400;
-                        FaceDetTrack.cwSetFaceParam(ret, faceParam, "");
 
-                    }
 
 
 
@@ -263,7 +294,7 @@ class CameraScanView(mContext: Context, attrs:AttributeSet?, defStyleAttr:Int) :
 
 
 
-                //preview?.setSurfaceProvider()
+                preview?.setSurfaceProvider(previewView?.surfaceProvider)
 
 
 

+ 11 - 9
app/src/main/res/layout/dialog_validate_face.xml

@@ -24,17 +24,19 @@
             app:layout_constraintRight_toRightOf="parent"
             app:layout_constraintTop_toTopOf="parent"
             >
-            <androidx.camera.view.PreviewView
-                android:id="@+id/mPreviewView"
-                android:layout_width="0dp"
-                android:layout_height="0dp"
-                app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintLeft_toLeftOf="parent"
-                app:layout_constraintRight_toRightOf="parent"
-                app:layout_constraintTop_toTopOf="parent" />
-          \
         </com.ethan.psbc.ui.widgets.CameraScanView>
 
+
+
+        <androidx.camera.view.PreviewView
+            android:id="@+id/mPreviewView"
+            android:layout_width="50dp"
+            android:layout_height="50dp"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintRight_toRightOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
     </androidx.constraintlayout.widget.ConstraintLayout>