فهرست منبع

完善人脸识别逻辑

gavin.chen 1 سال پیش
والد
کامیت
7b6218c205

+ 2 - 2
lib/architecture/storage/storage.dart

@@ -118,9 +118,9 @@ extension StorageServiceExt on StorageService {
   }
 
   /// 图片上传
-  Future<String?> upload(XFile xfile) async {
+  Future<String?> upload(XFile xfile, {String? fileType}) async {
     try {
-      final auth = await getAuth();
+      final auth = await getAuth(fileName: fileType);
       final bytes = await xfile.readAsBytes();
       Map<String, String> params = {};
       params['Authorization'] = auth.authorization!;

+ 0 - 10
lib/pages/facial_recognition/bindings.dart

@@ -1,10 +0,0 @@
-import 'package:get/get.dart';
-
-import 'controller.dart';
-
-class FacialRecognitionBinding implements Bindings {
-  @override
-  void dependencies() {
-    Get.lazyPut<FacialRecognitionController>(() => FacialRecognitionController());
-  }
-}

+ 65 - 45
lib/pages/facial_recognition/controller.dart

@@ -19,7 +19,9 @@ import 'index.dart';
 
 class FacialRecognitionController extends GetxController
     with WidgetsBindingObserver {
-  FacialRecognitionController();
+  FacialRecognitionController({required this.mode});
+
+  final FacialRecognitionMode mode;
 
   final state = FacialRecognitionState();
 
@@ -342,11 +344,29 @@ class FacialRecognitionController extends GetxController
   void onCaptureFaceButtonPressed() {
     // runDetectionTimer();
     /// 接口测试
-    rpcTest2();
+    ///
+    if (mode == FacialRecognitionMode.faceRecognition) {
+      doFacialRecognitionTimes = 0;
+      state.isRunningFaceRecognition = true;
+      doFacialRecognition(); // 人脸识别
+    } else {
+      rpcTest2(); // 人脸录入
+    }
   }
 
-  void rpcTest() async {
+  /// 人脸识别执行次数
+  int doFacialRecognitionTimes = 0;
+  void doFacialRecognition() async {
+    doFacialRecognitionTimes++;
+    if (doFacialRecognitionTimes == 10) {
+      // 尝试十次后宣告失败
+      state.isRunningFaceRecognition = false;
+      PromptBox.toast('人脸识别失败,请稍后重试');
+      return;
+    }
     if (kCameraController == null) {
+      state.isRunningFaceRecognition = false;
+      PromptBox.toast('相机启动失败,请稍后重试');
       return;
     }
     final XFile? file = await takePicture();
@@ -359,52 +379,40 @@ class FacialRecognitionController extends GetxController
 
       if (faceNum == 0) {
         PromptBox.toast('请将面部保持在识别框内');
-        return;
+        await Future.delayed(const Duration(seconds: 2));
       } else if (faceNum > 1) {
         PromptBox.toast('请保持只有一张面部在识别范围内');
-        return;
-      }
-
-      /// TODO 上传图像到云然后传给后端
-      final url = await rpc.storage.upload(file);
-      print('⭐⭐⭐⭐⭐⭐⭐⭐ url: $url');
-      try {
-        PatientBaseDTO result =
-            await rpc.patient.getPatientBaseByFaceImageAsync(
-          GetPatientBaseByFaceImageRequest(
-            token: Store.user.token,
-            image: url,
-          ),
+        await Future.delayed(const Duration(seconds: 2));
+      } else {
+        /// TODO 上传图像到云然后传给后端
+        final url = await rpc.storage.upload(
+          file,
+          fileType: 'png',
         );
-        print(result);
-        if (result.faceScanErrorType == FaceScanErrorTypeEnum.Success) {
-          PromptBox.toast('人脸识别成功,身份证号 ${result.cardNo}}');
-          finishFaceDetection(result);
-        } else {
-          // 暂先将 API 错误和 查无此人都归为识别错误
-          PromptBox.toast('人脸识别失败,请重试');
+        print('⭐⭐⭐⭐⭐⭐⭐⭐ url: $url');
+        try {
+          PatientBaseDTO result =
+              await rpc.patient.getPatientBaseByFaceImageAsync(
+            GetPatientBaseByFaceImageRequest(
+              token: Store.user.token,
+              image: url,
+            ),
+          );
+          print(result);
+          if (result.faceScanErrorType == FaceScanErrorTypeEnum.Success) {
+            PromptBox.toast('人脸识别成功,身份证号 ${result.cardNo}}');
+            finishFaceDetection(result);
+          } else {
+            // 暂先将 API 错误和 查无此人都归为识别错误
+            PromptBox.toast('人脸识别失败: $doFacialRecognitionTimes');
+            await Future.delayed(const Duration(seconds: 2));
+          }
+        } catch (e) {
+          logger.e("getPatientBaseByFaceImageAsync failed: $e", e);
         }
-      } catch (e) {
-        logger.e("getPatientBaseByFaceImageAsync failed: $e", e);
       }
-
-      // if (timer.tick == 1 || kFrameImageSize == Size.zero) {
-      //   Size imageSize = await getImageSize(file);
-      //   kFrameImageSize = imageSize;
-      // }
-      // int kTime = DateTime.now().millisecondsSinceEpoch;
-      // print('⭐⭐⭐⭐⭐⭐⭐⭐ capture time: ${kTime - lastCaptureTime} ms');
-      // lastCaptureTime = kTime;
-
-      // /// 记录用时 ms
-
-      // int endTime = DateTime.now().millisecondsSinceEpoch;
-      // print('⭐⭐⭐⭐⭐⭐⭐⭐ detection time: ${endTime - lastCaptureTime} ms');
-      // update(['face_bounding_box']);
-      // if (timer.tick >= 10) {
-      //   finishFaceDetection(); // TODO 接入真实的判断条件
-      // }
     }
+    doFacialRecognition();
   }
 
   /// 人脸录入测试
@@ -429,12 +437,15 @@ class FacialRecognitionController extends GetxController
       }
 
       /// TODO 上传图像到云然后传给后端
-      final url = await rpc.storage.upload(file);
+      final url = await rpc.storage.upload(
+        file,
+        fileType: 'png',
+      );
       print('⭐⭐⭐⭐⭐⭐⭐⭐ url: $url');
       try {
         bool result = await rpc.patient.savePatientBaseByFaceImageAsync(
           SavePatientBaseByFaceImageRequest(
-            cardNo: '320520200006190612',
+            cardNo: '320581199906190615',
             token: Store.user.token,
             image: url,
           ),
@@ -818,3 +829,12 @@ class FaceRecognitionResult {
     required this.address,
   });
 }
+
+/// 运行模式
+enum FacialRecognitionMode {
+  /// 人脸识别(用于登录)
+  faceRecognition,
+
+  /// 人脸录入
+  faceInput,
+}

+ 0 - 1
lib/pages/facial_recognition/index.dart

@@ -2,6 +2,5 @@ library facial_recognition;
 
 export './state.dart';
 export './controller.dart';
-export './bindings.dart';
 export './view.dart';
 export './models.dart';

+ 6 - 0
lib/pages/facial_recognition/state.dart

@@ -31,4 +31,10 @@ class FacialRecognitionState {
   final _isUsingFrontCamera = true.obs;
   set isUsingFrontCamera(value) => _isUsingFrontCamera.value = value;
   bool get isUsingFrontCamera => _isUsingFrontCamera.value;
+
+  /// 是否正在进行人脸识别
+  final _isRunningFaceRecognition = false.obs;
+  set isRunningFaceRecognition(value) =>
+      _isRunningFaceRecognition.value = value;
+  bool get isRunningFaceRecognition => _isRunningFaceRecognition.value;
 }

+ 10 - 6
lib/pages/facial_recognition/view.dart

@@ -5,12 +5,13 @@ import 'index.dart';
 import 'widgets/widgets.dart';
 
 class FacialRecognitionPage extends GetView<FacialRecognitionController> {
-  const FacialRecognitionPage({Key? key}) : super(key: key);
+  const FacialRecognitionPage({Key? key, required this.mode}) : super(key: key);
+  final FacialRecognitionMode mode;
 
   @override
   Widget build(BuildContext context) {
     return GetBuilder<FacialRecognitionController>(
-      init: FacialRecognitionController(),
+      init: FacialRecognitionController(mode: mode),
       builder: (_) {
         return Scaffold(
           appBar: AppBar(title: const Text("人脸识别")),
@@ -94,8 +95,11 @@ class FacialRecognitionPage extends GetView<FacialRecognitionController> {
   }
 
   Widget _switchCameraLens() {
-    return Obx(
-      () => GestureDetector(
+    return Obx(() {
+      if (controller.state.isRunningFaceRecognition) {
+        return Container();
+      }
+      return GestureDetector(
         onTap: () {
           if (controller.state.isUsingFrontCamera) {
             controller.openBackCamera();
@@ -127,7 +131,7 @@ class FacialRecognitionPage extends GetView<FacialRecognitionController> {
             ],
           ),
         ),
-      ),
-    );
+      );
+    });
   }
 }

+ 23 - 3
lib/pages/facial_recognition/widgets/camera_for_face.dart

@@ -43,9 +43,11 @@ class CameraForFace extends GetView<FacialRecognitionController> {
         ),
         Align(
           alignment: Alignment.centerRight,
-          child: Container(
-            child: _captureButton(),
-          ),
+          child: Obx(() => Container(
+                child: controller.state.isRunningFaceRecognition
+                    ? _recognizing()
+                    : _captureButton(),
+              )),
         ),
         Align(
           alignment: Alignment.bottomCenter,
@@ -78,4 +80,22 @@ class CameraForFace extends GetView<FacialRecognitionController> {
       ),
     );
   }
+
+  /// 识别中状态标识
+  Widget _recognizing() {
+    return Container(
+      margin: const EdgeInsets.only(right: 60),
+      width: 100,
+      height: 100,
+      decoration: BoxDecoration(
+        color: Colors.white,
+        borderRadius: BorderRadius.circular(50),
+      ),
+      child: const Center(
+        child: CircularProgressIndicator(
+          color: Colors.blue,
+        ),
+      ),
+    );
+  }
 }

+ 3 - 1
lib/pages/patient/create/controller.dart

@@ -183,7 +183,9 @@ class CreatePatientController extends FControllerBase with HomeNavMixin {
   /// 点击人脸识别
   void onFaceIdLoginClicked() async {
     final FaceRecognitionResult? result = await Get.to<FaceRecognitionResult>(
-      () => const FacialRecognitionPage(),
+      () => const FacialRecognitionPage(
+        mode: FacialRecognitionMode.faceRecognition,
+      ),
     );
     if (result != null && result.success) {
       PromptBox.toast("录入成功");