diff --git a/hb_server/apps/hrm/serializers.py b/hb_server/apps/hrm/serializers.py index 116ccb6..aa168d5 100644 --- a/hb_server/apps/hrm/serializers.py +++ b/hb_server/apps/hrm/serializers.py @@ -23,9 +23,11 @@ class FaceLoginSerializer(serializers.Serializer): class FaceLoginPathSerializer(serializers.Serializer): path = serializers.CharField() + tolerance = serializers.FloatField(required=False, default=0.45) class FaceClockCreateSerializer(serializers.Serializer): base64 = serializers.CharField() + tolerance = serializers.FloatField(required=False, default=0.45) class ClockRecordListSerializer(serializers.ModelSerializer): create_by_ = UserSimpleSerializer(source='create_by', read_only=True) diff --git a/hb_server/apps/hrm/services.py b/hb_server/apps/hrm/services.py index 2727616..3aa2950 100644 --- a/hb_server/apps/hrm/services.py +++ b/hb_server/apps/hrm/services.py @@ -10,11 +10,11 @@ from django.core.cache import cache class HRMService: @classmethod - def face_compare_from_path(cls, path): + def face_compare_from_path(cls, path, tolerance=0.45): filepath = settings.BASE_DIR +path try: unknown_picture = face_recognition.load_image_file(filepath) - unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0] + unknown_face_encoding = face_recognition.face_encodings(unknown_picture, num_jitters=2)[0] # os.remove(filepath) except: # os.remove(filepath) @@ -27,23 +27,30 @@ class HRMService: face_datas = cache.get('face_datas') face_users = cache.get('face_users') results = face_recognition.compare_faces(face_datas, - unknown_face_encoding, tolerance=0.42) - for index, value in enumerate(results): - if value: - # 识别成功 - user = User.objects.get(id=face_users[index]) - return user, '' - return None, '人脸未匹配,请调整位置' + unknown_face_encoding, tolerance=tolerance) + user_index = cls.get_user_index(results) + user_index_len = len(user_index) + if user_index_len == 1: + user = User.objects.get(id=face_users[user_index[0]]) + return user, '' + elif user_index_len == 0: + return None, '人脸未匹配,请调整位置' + else: + user_ids = [] + for i in user_index: + user_ids.append(face_users[i]) + user_name_str = ','.join(list(User.objects.filter(id__in=user_ids).values_list('name', flat=True))) + return None, '匹配多张人脸:' + user_name_str @classmethod - def face_compare_from_base64(cls, base64_data): + def face_compare_from_base64(cls, base64_data, tolerance=0.45): filename = str(uuid.uuid4()) filepath = settings.BASE_DIR +'/temp/' + filename +'.png' with open(filepath, 'wb') as f: f.write(base64_data) try: unknown_picture = face_recognition.load_image_file(filepath) - unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0] + unknown_face_encoding = face_recognition.face_encodings(unknown_picture, num_jitters=2)[0] os.remove(filepath) except: os.remove(filepath) @@ -56,13 +63,34 @@ class HRMService: face_datas = cache.get('face_datas') face_users = cache.get('face_users') results = face_recognition.compare_faces(face_datas, - unknown_face_encoding, tolerance=0.42) + unknown_face_encoding, tolerance=tolerance) + user_index = cls.get_user_index(results) + user_index_len = len(user_index) + if user_index_len == 1: + user = User.objects.get(id=face_users[user_index[0]]) + return user, '' + elif user_index_len == 0: + return None, '人脸未匹配,请调整位置' + else: + user_ids = [] + for i in user_index: + user_ids.append(face_users[i]) + user_name_str = ','.join(list(User.objects.filter(id__in=user_ids).values_list('name', flat=True))) + return None, '匹配多张人脸:' + user_name_str + + + @classmethod + def get_user_index(cls, results): + """ + 返回user_index列表 + """ + true_num = 0 + user_index = [] for index, value in enumerate(results): if value: - # 识别成功 - user = User.objects.get(id=face_users[index]) - return user, '' - return None, '人脸未匹配,请调整位置' + true_num = true_num + 1 + user_index.append(index) + return user_index @classmethod def get_facedata_from_img(cls, img_path): diff --git a/hb_server/apps/hrm/tasks.py b/hb_server/apps/hrm/tasks.py index b365f58..7cc65a3 100644 --- a/hb_server/apps/hrm/tasks.py +++ b/hb_server/apps/hrm/tasks.py @@ -18,7 +18,7 @@ def update_all_user_facedata_cache(): 更新人脸数据缓存 """ facedata_queyset = Employee.objects.filter(face_data__isnull=False, - user__is_active=True).values('user', 'face_data') + user__is_active=True, user__is_deleted = False).values('user', 'face_data') face_users = [] face_datas = [] for i in facedata_queyset: diff --git a/hb_server/apps/hrm/views.py b/hb_server/apps/hrm/views.py index 8b266a3..915333a 100644 --- a/hb_server/apps/hrm/views.py +++ b/hb_server/apps/hrm/views.py @@ -159,7 +159,7 @@ class FaceLogin(CreateAPIView): """ 人脸识别登录 """ - base64_data = base64.urlsafe_b64decode(tran64(request.data.get('base64').replace(' ', '+'))) + base64_data = base64.urlsafe_b64decode(tran64(request.data.get('base64').replace(' ', '+')), request.data.get('tolerance', 0.45)) user, msg = HRMService.face_compare_from_base64(base64_data) if user: refresh = RefreshToken.for_user(user) @@ -198,7 +198,7 @@ class FacePathLogin(CreateAPIView): """ 人脸识别登录-文件地址 """ - user, msg = HRMService.face_compare_from_path(request.data.get('path')) + user, msg = HRMService.face_compare_from_path(request.data.get('path'), request.data.get('tolerance', 0.45)) if user: refresh = RefreshToken.for_user(user) # 可设为在岗 diff --git a/hb_server/media/default/slx.png b/hb_server/media/default/slx.png new file mode 100644 index 0000000..5a5c994 Binary files /dev/null and b/hb_server/media/default/slx.png differ diff --git a/hb_server/media/default/wc.jpg b/hb_server/media/default/wc.jpg new file mode 100644 index 0000000..f5e07ad Binary files /dev/null and b/hb_server/media/default/wc.jpg differ