Quellcode durchsuchen

对接新的人脸配置参数

RandyWei vor 5 Jahren
Ursprung
Commit
18071ee236

+ 21 - 16
.idea/workspace.xml

@@ -22,15 +22,12 @@
     <select />
   </component>
   <component name="ChangeListManager">
-    <list default="true" id="7945bc75-c964-46e8-bae6-c93a89a0a56f" name="Default Changelist" comment="更新百度人脸SDK">
+    <list default="true" id="7945bc75-c964-46e8-bae6-c93a89a0a56f" name="Default Changelist" comment="优化初始化回调">
       <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
       <change beforePath="$PROJECT_DIR$/android/src/main/kotlin/dev/bughub/plugin/fltbdface/FltbdfacePlugin.kt" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/kotlin/dev/bughub/plugin/fltbdface/FltbdfacePlugin.kt" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/android/src/main/kotlin/dev/bughub/plugin/fltbdface/face/BdFaceLivenessActivity.kt" beforeDir="false" />
       <change beforePath="$PROJECT_DIR$/android/src/main/kotlin/dev/bughub/plugin/fltbdface/face/FaceDelegate.kt" beforeDir="false" afterPath="$PROJECT_DIR$/android/src/main/kotlin/dev/bughub/plugin/fltbdface/face/FaceDelegate.kt" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/android/src/main/kotlin/dev/bughub/plugin/fltbdface/face/FacePlugin.kt" beforeDir="false" />
-      <change beforePath="$PROJECT_DIR$/example/lib/face_service.dart" beforeDir="false" afterPath="$PROJECT_DIR$/example/lib/face_service.dart" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/lib/face/face_plugin.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/face/face_plugin.dart" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/test/fltbdface_test.dart" beforeDir="false" afterPath="$PROJECT_DIR$/test/fltbdface_test.dart" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/lib/face/face_config.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/face/face_config.dart" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/lib/face/face_environment.dart" beforeDir="false" afterPath="$PROJECT_DIR$/lib/face/face_environment.dart" afterDir="false" />
     </list>
     <option name="SHOW_DIALOG" value="false" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -178,7 +175,14 @@
       <option name="project" value="LOCAL" />
       <updated>1605664146177</updated>
     </task>
-    <option name="localTasksCounter" value="16" />
+    <task id="LOCAL-00016" summary="优化初始化回调">
+      <created>1605763863822</created>
+      <option name="number" value="00016" />
+      <option name="presentableId" value="LOCAL-00016" />
+      <option name="project" value="LOCAL" />
+      <updated>1605763863823</updated>
+    </task>
+    <option name="localTasksCounter" value="17" />
     <servers />
   </component>
   <component name="Vcs.Log.Tabs.Properties">
@@ -205,36 +209,37 @@
     <MESSAGE value="build配置" />
     <MESSAGE value="readme" />
     <MESSAGE value="更新百度人脸SDK" />
-    <option name="LAST_COMMIT_MESSAGE" value="更新百度人脸SDK" />
+    <MESSAGE value="优化初始化回调" />
+    <option name="LAST_COMMIT_MESSAGE" value="优化初始化回调" />
   </component>
   <component name="WindowStateProjectService">
     <state x="760" y="271" key="AndroidProcessChooserDialog" timestamp="1605763330779">
       <screen x="0" y="25" width="1920" height="992" />
     </state>
     <state x="760" y="271" key="AndroidProcessChooserDialog/0.25.1920.992@0.25.1920.992" timestamp="1605763330779" />
-    <state width="1878" height="488" key="GridCell.Tab.0.bottom" timestamp="1605763748109">
+    <state width="1878" height="488" key="GridCell.Tab.0.bottom" timestamp="1605766698686">
       <screen x="0" y="25" width="1920" height="992" />
     </state>
     <state width="1878" height="619" key="GridCell.Tab.0.bottom/0.23.1920.1000@0.23.1920.1000" timestamp="1605573761281" />
     <state width="1878" height="620" key="GridCell.Tab.0.bottom/0.23.1920.1001@0.23.1920.1001" timestamp="1605259102878" />
-    <state width="1878" height="488" key="GridCell.Tab.0.bottom/0.25.1920.992@0.25.1920.992" timestamp="1605763748109" />
-    <state width="1878" height="488" key="GridCell.Tab.0.center" timestamp="1605763748108">
+    <state width="1878" height="488" key="GridCell.Tab.0.bottom/0.25.1920.992@0.25.1920.992" timestamp="1605766698686" />
+    <state width="1878" height="488" key="GridCell.Tab.0.center" timestamp="1605766698686">
       <screen x="0" y="25" width="1920" height="992" />
     </state>
     <state width="1878" height="619" key="GridCell.Tab.0.center/0.23.1920.1000@0.23.1920.1000" timestamp="1605573761280" />
     <state width="1878" height="620" key="GridCell.Tab.0.center/0.23.1920.1001@0.23.1920.1001" timestamp="1605259102877" />
-    <state width="1878" height="488" key="GridCell.Tab.0.center/0.25.1920.992@0.25.1920.992" timestamp="1605763748108" />
-    <state width="1878" height="488" key="GridCell.Tab.0.left" timestamp="1605763748108">
+    <state width="1878" height="488" key="GridCell.Tab.0.center/0.25.1920.992@0.25.1920.992" timestamp="1605766698686" />
+    <state width="1878" height="488" key="GridCell.Tab.0.left" timestamp="1605766698686">
       <screen x="0" y="25" width="1920" height="992" />
     </state>
     <state width="1878" height="619" key="GridCell.Tab.0.left/0.23.1920.1000@0.23.1920.1000" timestamp="1605573761280" />
     <state width="1878" height="620" key="GridCell.Tab.0.left/0.23.1920.1001@0.23.1920.1001" timestamp="1605259102877" />
-    <state width="1878" height="488" key="GridCell.Tab.0.left/0.25.1920.992@0.25.1920.992" timestamp="1605763748108" />
-    <state width="1878" height="488" key="GridCell.Tab.0.right" timestamp="1605763748108">
+    <state width="1878" height="488" key="GridCell.Tab.0.left/0.25.1920.992@0.25.1920.992" timestamp="1605766698686" />
+    <state width="1878" height="488" key="GridCell.Tab.0.right" timestamp="1605766698686">
       <screen x="0" y="25" width="1920" height="992" />
     </state>
     <state width="1878" height="619" key="GridCell.Tab.0.right/0.23.1920.1000@0.23.1920.1000" timestamp="1605573761280" />
     <state width="1878" height="620" key="GridCell.Tab.0.right/0.23.1920.1001@0.23.1920.1001" timestamp="1605259102877" />
-    <state width="1878" height="488" key="GridCell.Tab.0.right/0.25.1920.992@0.25.1920.992" timestamp="1605763748108" />
+    <state width="1878" height="488" key="GridCell.Tab.0.right/0.25.1920.992@0.25.1920.992" timestamp="1605766698686" />
   </component>
 </project>

+ 9 - 5
android/src/main/kotlin/dev/bughub/plugin/fltbdface/FltbdfacePlugin.kt

@@ -82,7 +82,7 @@ public class FltbdfacePlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
 
                 val brightnessValue: Float? = call.argument<Double>("brightnessValue")?.toFloat()
 
-                val cropFaceValue: Int? = call.argument<Int>("cropFaceValue")
+                val cropHeight: Int? = call.argument<Int>("cropHeight")
 
                 val headPitchValue: Int? = call.argument<Int>("headPitchValue")
                 val headRollValue: Int? = call.argument<Int>("headRollValue")
@@ -90,14 +90,18 @@ public class FltbdfacePlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
                 val minFaceSize: Int? = call.argument<Int>("minFaceSize")
                 val notFaceValue: Float? = call.argument<Double>("notFaceValue")?.toFloat()
                 val occlusionValue: Float? = call.argument<Double>("occlusionValue")?.toFloat()
-                val checkFaceQuality: Boolean? = call.argument<Boolean>("checkFaceQuality")
-                val faceDecodeNumberOfThreads: Int? = call.argument<Int>("faceDecodeNumberOfThreads")
+                val scale: Float? = call.argument<Double>("scale")?.toFloat()
+                val eyeClosedValue: Float? = call.argument<Float>("eyeClosedValue")
+                val isOpenSound: Boolean = call.argument<Boolean>("isSound") ?: true
+                val cacheImageNum: Int? = call.argument<Int>("cacheImageNum")
                 val livenessRandomCount: Int? = call.argument<Int>("livenessRandomCount")
+                val secType: Int? = call.argument<Int>("secType")
 
 
                 delegate?.setFaceConfig(livenessTypeList, livenessRandom = livenessRandom, blurnessValue = blurnessValue, brightnessValue = brightnessValue,
-                        cropFaceValue = cropFaceValue, headPitchValue = headPitchValue, headRollValue = headRollValue, headYawValue = headYawValue, minFaceSize = minFaceSize,
-                        notFaceValue = notFaceValue, occlusionValue = occlusionValue, checkFaceQuality = checkFaceQuality, faceDecodeNumberOfThreads = faceDecodeNumberOfThreads, livenessRandomCount = livenessRandomCount)
+                        headPitchValue = headPitchValue, headYawValue = headYawValue, headRollValue = headRollValue, minFaceSize = minFaceSize, notFaceValue = notFaceValue,
+                        occlusionValue = occlusionValue, livenessRandomCount = livenessRandomCount, eyeClosedValue = eyeClosedValue, cacheImageNum = cacheImageNum,
+                        isOpenSound = isOpenSound, scale = scale, cropHeight = cropHeight, secType = secType)
 
                 result.success(null)
             }

+ 99 - 42
android/src/main/kotlin/dev/bughub/plugin/fltbdface/face/FaceDelegate.kt

@@ -59,12 +59,32 @@ class FaceDelegate(var activity: Activity, var binaryMessenger: BinaryMessenger?
         })
     }
 
-    fun setFaceConfig(livenessTypeList: List<Int>, livenessRandom: Boolean = false, blurnessValue: Float?,
-                      brightnessValue: Float?, cropFaceValue: Int?,
-                      headPitchValue: Int?, headRollValue: Int?,
-                      headYawValue: Int?, minFaceSize: Int?,
-                      notFaceValue: Float?, occlusionValue: Float?,
-                      checkFaceQuality: Boolean?, faceDecodeNumberOfThreads: Int?, livenessRandomCount: Int?) {
+
+    /**
+     * 设置人脸配置
+     *
+     * @param livenessTypeList 活动动作列表
+     * @param livenessRandom 活动动作是否随机
+     * @param blurnessValue 设置模糊度阈值
+     * @param brightnessValue 设置光照阈值(范围0-255)
+     * @param headPitchValue 设置人脸姿态角阈值
+     * @param headRollValue
+     * @param headYawValue 设置人脸姿态角阈值
+     * @param minFaceSize 设置可检测的最小人脸阈值
+     * @param notFaceValue 设置可检测到人脸的阈值
+     * @param occlusionValue 设置遮挡阈值
+     * @param livenessRandomCount
+     * @param eyeClosedValue 设置闭眼阈值
+     * @param cacheImageNum 设置图片缓存数量
+     * @param isOpenSound 设置开启提示音
+     * @param scale 原图缩放系数
+     * @param cropHeight 抠图高的设定,为了保证好的抠图效果,我们要求高宽比是4:3,所以会在内部进行计算,只需要传入高即可
+     * @param secType 加密类型,0:Base64加密,上传时image_sec传false;1:百度加密文件加密,上传时image_sec传true
+     */
+    fun setFaceConfig(livenessTypeList: List<Int>, livenessRandom: Boolean = false, blurnessValue: Float?, brightnessValue: Float?,
+                      headPitchValue: Int?, headRollValue: Int?, headYawValue: Int?, minFaceSize: Int?, notFaceValue: Float?,
+                      occlusionValue: Float?, livenessRandomCount: Int?, eyeClosedValue: Float?, cacheImageNum: Int?, isOpenSound: Boolean = true,
+                      scale: Float?, cropHeight: Int?, secType: Int?) {
         val config = FaceSDKManager.getInstance().faceConfig
         // SDK初始化已经设置完默认参数(推荐参数),您也根据实际需求进行数值调整
         val livenessList = arrayListOf<LivenessTypeEnum>()
@@ -72,61 +92,98 @@ class FaceDelegate(var activity: Activity, var binaryMessenger: BinaryMessenger?
             livenessList.add(LivenessTypeEnum.values()[it])
         }
 
-        config.setLivenessTypeList(livenessList)
+        // 设置活体动作,通过设置list,LivenessTypeEunm.Eye, LivenessTypeEunm.Mouth,
+        // LivenessTypeEunm.HeadUp, LivenessTypeEunm.HeadDown, LivenessTypeEunm.HeadLeft,
+        // LivenessTypeEunm.HeadRight, LivenessTypeEunm.HeadLeftOrRight
+        config.livenessTypeList = livenessList
+        // 设置动作活体是否随机
+        config.isLivenessRandom = livenessRandom
+
+        config.livenessRandomCount = livenessRandomCount ?: 0
 
-        config.setLivenessRandom(livenessRandom)
+        // 设置可检测的最小人脸阈值
+        if (null == minFaceSize)
+            config.minFaceSize = FaceEnvironment.VALUE_MIN_FACE_SIZE
+        else
+            config.minFaceSize = minFaceSize
 
-        config.setLivenessRandomCount(livenessRandomCount ?: 0)
+        // 设置可检测到人脸的阈值
+        if (null == notFaceValue)
+            config.notFaceValue = FaceEnvironment.VALUE_NOT_FACE_THRESHOLD
+        else
+            config.notFaceValue = notFaceValue
 
+        // 设置模糊度阈值
         if (null == blurnessValue)
-            config.setBlurnessValue(FaceEnvironment.VALUE_BLURNESS)
+            config.blurnessValue = FaceEnvironment.VALUE_BLURNESS
         else
-            config.setBlurnessValue(blurnessValue)
+            config.blurnessValue = blurnessValue
 
+        // 设置光照阈值(范围0-255)
         if (null == brightnessValue)
-            config.setBrightnessValue(FaceEnvironment.VALUE_BRIGHTNESS)
+            config.brightnessValue = FaceEnvironment.VALUE_BRIGHTNESS
         else
-            config.setBrightnessValue(brightnessValue)
+            config.brightnessValue = brightnessValue
 
-//        if (null == cropFaceValue)
-//            config.setCropFaceValue(FaceEnvironment.VALUE_CROP_FACE_SIZE)
-//        else
-//            config.setCropFaceValue(cropFaceValue)
-
-        if (null == headPitchValue)
-            config.setHeadPitchValue(FaceEnvironment.VALUE_HEAD_PITCH)
+        // 设置遮挡阈值
+        if (null == occlusionValue)
+            config.occlusionValue = FaceEnvironment.VALUE_OCCLUSION
         else
-            config.setHeadPitchValue(headPitchValue)
+            config.occlusionValue = occlusionValue
 
-        if (null == headRollValue)
-            config.setHeadRollValue(FaceEnvironment.VALUE_HEAD_ROLL)
+        // 设置人脸姿态角阈值
+        if (null == headPitchValue)
+            config.headPitchValue = FaceEnvironment.VALUE_HEAD_PITCH
         else
-            config.setHeadRollValue(headRollValue)
-
+            config.headPitchValue = headPitchValue
         if (null == headYawValue)
-            config.setHeadYawValue(FaceEnvironment.VALUE_HEAD_YAW)
+            config.headYawValue = FaceEnvironment.VALUE_HEAD_YAW
         else
-            config.setHeadYawValue(headYawValue)
+            config.headYawValue = headYawValue
 
-        if (null == minFaceSize)
-            config.setMinFaceSize(FaceEnvironment.VALUE_MIN_FACE_SIZE)
-        else
-            config.setMinFaceSize(minFaceSize)
+        // 设置闭眼阈值
+        if (eyeClosedValue == null) {
+            config.eyeClosedValue = FaceEnvironment.VALUE_CLOSE_EYES
+        } else {
+            config.eyeClosedValue = eyeClosedValue
+        }
 
-        if (null == notFaceValue)
-            config.setNotFaceValue(FaceEnvironment.VALUE_NOT_FACE_THRESHOLD)
-        else
-            config.setNotFaceValue(notFaceValue)
+        // 设置图片缓存数量
+        if (cacheImageNum == null) {
+            config.cacheImageNum = FaceEnvironment.VALUE_CACHE_IMAGE_NUM
+        } else {
+            config.cacheImageNum = cacheImageNum
+        }
 
-        if (null == occlusionValue)
-            config.setOcclusionValue(FaceEnvironment.VALUE_OCCLUSION)
-        else
-            config.setOcclusionValue(occlusionValue)
+        // 设置开启提示音
+        config.isSound = isOpenSound
 
+        // 原图缩放系数
+        if (scale == null) {
+            config.scale = FaceEnvironment.VALUE_SCALE
+        } else {
+            config.scale = scale
+        }
+
+        // 抠图高的设定,为了保证好的抠图效果,我们要求高宽比是4:3,所以会在内部进行计算,只需要传入高即可
+        if (cropHeight == null) {
+            config.cropHeight = FaceEnvironment.VALUE_CROP_HEIGHT
+        } else {
+            config.cropHeight = cropHeight
+        }
+
+        // 加密类型,0:Base64加密,上传时image_sec传false;1:百度加密文件加密,上传时image_sec传true
+        if (secType == null) {
+            config.secType = FaceEnvironment.VALUE_SEC_TYPE;
+        } else {
+            config.secType = secType
+        }
+
+        if (null == headRollValue)
+            config.headRollValue = FaceEnvironment.VALUE_HEAD_ROLL
+        else
+            config.headRollValue = headRollValue
 
-//        config.setCheckFaceQuality(checkFaceQuality ?: false)
-//
-//        config.setFaceDecodeNumberOfThreads(faceDecodeNumberOfThreads ?: 2)
 
         FaceSDKManager.getInstance().faceConfig = config
     }

+ 21 - 20
lib/face/face_config.dart

@@ -20,8 +20,8 @@ class FaceConfig {
   /// 图像中人脸偏头阀值
   var headRollValue = FaceEnvironment.VALUE_HEAD_ROLL;
 
-  /// 裁剪图像中人脸时的大小
-  var cropFaceValue = FaceEnvironment.VALUE_CROP_FACE_SIZE;
+  /// 抠图高的设定,为了保证好的抠图效果,我们要求高宽比是4:3,所以会在内部进行计算,只需要传入高即可
+  var cropHeight = FaceEnvironment.VALUE_CROP_HEIGHT;
 
   /// 图像能被检测出人脸的最小人脸值
   var minFaceSize = FaceEnvironment.VALUE_MIN_FACE_SIZE;
@@ -29,27 +29,27 @@ class FaceConfig {
   /// 图像能被检测出人脸阀值
   var notFaceValue = FaceEnvironment.VALUE_NOT_FACE_THRESHOLD;
 
-  /// 人脸采集图片数量阀值
-  var maxCropImageNum = FaceEnvironment.VALUE_MAX_CROP_IMAGE_NUM;
-
-  /// 是否进行人脸图片质量检测
-  var isCheckFaceQuality = FaceEnvironment.VALUE_IS_CHECK_QUALITY;
-
   /// 是否开启提示音
   var isSound = true;
 
-  /// 是否进行检测
-  var sVerifyLive = true;
-
-  /// 人脸检测时开启的进程数,建议为CPU核数
-  var faceDecodeNumberOfThreads = 0;
-
   /// 是否随机活体检测动作
   var isLivenessRandom = false;
 
   /// 随机活体检测动作数
   var livenessRandomCount = FaceEnvironment.VALUE_LIVENESS_DEFAULT_RANDOM_COUNT;
 
+  /// 闭眼阈值
+  var eyeClosedValue = FaceEnvironment.VALUE_CLOSE_EYES;
+
+  /// 图片缓存数量
+  var cacheImageNum = FaceEnvironment.VALUE_CACHE_IMAGE_NUM;
+
+  /// 原图缩放系数
+  var scale = FaceEnvironment.VALUE_SCALE;
+
+  /// 加密类型,0:Base64加密,上传时image_sec传false;1:百度加密文件加密,上传时image_sec传true
+  var secType = FaceEnvironment.VALUE_SEC_TYPE;
+
   /// 活体检测的动作类型列表
   List<LivenessType> livenessTypeList = [
     LivenessType.Eye,
@@ -68,17 +68,18 @@ class FaceConfig {
       'headPitchValue': this.headPitchValue,
       'headYawValue': this.headYawValue,
       'headRollValue': this.headRollValue,
-      'cropFaceValue': this.cropFaceValue,
+      'cropHeight': this.cropHeight,
       'minFaceSize': this.minFaceSize,
       'notFaceValue': this.notFaceValue,
-      'maxCropImageNum': this.maxCropImageNum,
-      'isCheckFaceQuality': this.isCheckFaceQuality,
       'isSound': this.isSound,
-      'sVerifyLive': this.sVerifyLive,
-      'faceDecodeNumberOfThreads': this.faceDecodeNumberOfThreads,
       'isLivenessRandom': this.isLivenessRandom,
       'livenessRandomCount': this.livenessRandomCount,
-      'livenessTypeList': this.livenessTypeList.map((item) => item.index).toList(),
+      'livenessTypeList':
+          this.livenessTypeList.map((item) => item.index).toList(),
+      'eyeClosedValue': this.eyeClosedValue,
+      'cacheImageNum': this.cacheImageNum,
+      'scale': this.scale,
+      'secType': this.secType
     };
   }
 }

+ 12 - 6
lib/face/face_environment.dart

@@ -1,15 +1,21 @@
 class FaceEnvironment {
-  static const VALUE_BRIGHTNESS = 40.0;
-  static const VALUE_BLURNESS = 0.5;
+  static const VALUE_BRIGHTNESS = 82.0;
+  static const VALUE_MAX_BRIGHTNESS = 200.0;
+  static const VALUE_BLURNESS = 0.3;
   static const VALUE_OCCLUSION = 0.5;
-  static const VALUE_HEAD_PITCH = 10;
-  static const VALUE_HEAD_YAW = 10;
-  static const VALUE_HEAD_ROLL = 10;
-  static const VALUE_CROP_FACE_SIZE = 400;
+  static const VALUE_HEAD_PITCH = 8;
+  static const VALUE_HEAD_YAW = 8;
+  static const VALUE_HEAD_ROLL = 8;
+  static const VALUE_CROP_HEIGHT = 640;
+  static const VALUE_CROP_WIDTH = 480;
   static const VALUE_MIN_FACE_SIZE = 200;
   static const VALUE_NOT_FACE_THRESHOLD = 0.6;
   static const VALUE_IS_CHECK_QUALITY = true;
   static const VALUE_DECODE_THREAD_NUM = 2;
   static const VALUE_LIVENESS_DEFAULT_RANDOM_COUNT = 3;
   static const VALUE_MAX_CROP_IMAGE_NUM = 1;
+  static const VALUE_CLOSE_EYES = 0.7;
+  static const VALUE_CACHE_IMAGE_NUM = 3;
+  static const VALUE_SCALE = 1.0;
+  static const VALUE_SEC_TYPE = 0;
 }