人脸识别数据用缓存处理

This commit is contained in:
caoqianming 2022-01-21 16:13:32 +08:00
parent db87609ad6
commit e53024c9bc
5 changed files with 69 additions and 41 deletions

View File

@ -3,7 +3,9 @@ import uuid
import face_recognition import face_recognition
import os import os
from apps.hrm.models import Employee from apps.hrm.models import Employee
from apps.hrm.tasks import update_all_user_facedata_cache
from apps.system.models import User from apps.system.models import User
from django.core.cache import cache
class HRMService: class HRMService:
@ -22,18 +24,25 @@ class HRMService:
return None, '头像解码失败' return None, '头像解码失败'
# 匹配人脸库 # 匹配人脸库
user_faces = Employee.objects.filter(face_data__isnull=False, face_datas = cache.get('face_datas')
user__is_active=True).values('user', 'face_data') face_users = cache.get('face_users')
user_l = [] if face_datas is None:
face_l = [] update_all_user_facedata_cache()
for i in user_faces:
user_l.append(i['user'])
face_l.append(i['face_data'])
results = face_recognition.compare_faces(face_l, unknown_face_encoding, tolerance=0.5) results = face_recognition.compare_faces(face_datas, unknown_face_encoding, tolerance=0.5)
for index, value in enumerate(results): for index, value in enumerate(results):
if value: if value:
# 识别成功 # 识别成功
user = User.objects.get(id=user_l[index]) user = User.objects.get(id=face_users[index])
return user, '' return user, ''
return None, '识别失败' return None, '识别失败'
def get_facedata_from_img(cls, img_rpath):
try:
photo_path = settings.BASE_DIR + img_rpath
picture_of_me = face_recognition.load_image_file(photo_path)
my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
face_data_list = my_face_encoding.tolist()
return face_data_list
except:
return None

View File

@ -2,6 +2,10 @@ from django.db.models.signals import post_save
from apps.system.models import User from apps.system.models import User
from django.dispatch import receiver from django.dispatch import receiver
from apps.hrm.models import Employee from apps.hrm.models import Employee
from django.conf import settings
import face_recognition
import logging
logger = logging.getLogger('log')
@receiver(post_save, sender=User) @receiver(post_save, sender=User)
def createEmployee(sender, instance, created, **kwargs): def createEmployee(sender, instance, created, **kwargs):

View File

@ -1,8 +1,31 @@
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
from celery import shared_task from celery import shared_task
from apps.hrm.models import Employee
from apps.system.models import User
from django.core.cache import cache
@shared_task @shared_task
def x(): def update_all_user_not_atwork():
print('ok') """
将所有员工设为非在岗状态
"""
User.objects.all().update(is_atwork=False)
@shared_task
def update_all_user_facedata_cache():
"""
更新人脸数据缓存
"""
facedata_queyset = Employee.objects.filter(face_data__isnull=False,
user__is_active=True).values('user', 'face_data')
face_users = []
face_datas = []
for i in facedata_queyset:
face_users.append(i['user'])
face_datas.append(i['face_data'])
cache.set('face_users', face_users, timeout=None)
cache.set('face_datas', face_datas, timeout=None)

View File

@ -8,10 +8,9 @@ from apps.hrm.services import HRMService
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
from apps.hrm.models import ClockRecord, Employee from apps.hrm.models import ClockRecord, Employee
from apps.hrm.serializers import ClockRecordListSerializer, EmployeeSerializer, FaceClockCreateSerializer, FaceLoginSerializer from apps.hrm.serializers import ClockRecordListSerializer, EmployeeSerializer, FaceClockCreateSerializer, FaceLoginSerializer
import face_recognition
from django.conf import settings
from django.core.cache import cache
import logging
from rest_framework.generics import CreateAPIView from rest_framework.generics import CreateAPIView
from rest_framework import status from rest_framework import status
from rest_framework_simplejwt.tokens import RefreshToken from rest_framework_simplejwt.tokens import RefreshToken
@ -19,20 +18,8 @@ from rest_framework import exceptions
from apps.system.models import User from apps.system.models import User
from apps.system.serializers import UserSimpleSerializer from apps.system.serializers import UserSimpleSerializer
from rest_framework.permissions import AllowAny from rest_framework.permissions import AllowAny
logger = logging.getLogger('log')
def load_face_data(username:int, path:str):
"""
将某用户face_encoding加载进缓存
"""
face_datas = cache.get_or_set('face_datas', {}, timeout=None)
photo_path = settings.BASE_DIR + path
picture_of_me = face_recognition.load_image_file(photo_path)
my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
face_datas[username] = my_face_encoding
cache.set('face_datas', face_datas, timeout=None)
return my_face_encoding
# Create your views here. # Create your views here.
class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMixin, RetrieveModelMixin, GenericViewSet): class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMixin, RetrieveModelMixin, GenericViewSet):
@ -44,16 +31,21 @@ class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMix
serializer_class = EmployeeSerializer serializer_class = EmployeeSerializer
ordering = ['-pk'] ordering = ['-pk']
def perform_update(self, serializer): def update(self, request, *args, **kwargs):
instance = serializer.save(update_by = self.request.user) partial = kwargs.pop('partial', False)
try: instance = self.get_object()
photo_path = settings.BASE_DIR + instance.photo data = request.data
picture_of_me = face_recognition.load_image_file(photo_path) serializer = self.get_serializer(instance, data=data, partial=partial)
my_face_encoding = face_recognition.face_encodings(picture_of_me)[0] serializer.is_valid(raise_exception=True)
instance.face_data = my_face_encoding.tolist() photo = data.get('photo', None)
instance.save() if instance.photo != photo:
except: f_l = HRMService.get_facedata_from_img(photo)
logger.error('人脸识别出错') if f_l:
serializer.save(update_by=request.user, face_data = f_l)
return Response()
return Response('头像识别失败', status=status.HTTP_400_BAD_REQUEST)
serializer.save(update_by=request.user)
return Response()
class ClockRecordViewSet(CreateModelMixin, ListModelMixin, GenericViewSet): class ClockRecordViewSet(CreateModelMixin, ListModelMixin, GenericViewSet):

View File

@ -194,7 +194,7 @@ AUTHENTICATION_BACKENDS = (
# CACHES = { # CACHES = {
# "default": { # "default": {
# "BACKEND": "django_redis.cache.RedisCache", # "BACKEND": "django_redis.cache.RedisCache",
# "LOCATION": "redis://redis:6379/1", # "LOCATION": "redis://127.0.0.1:6379/0",
# "OPTIONS": { # "OPTIONS": {
# "CLIENT_CLASS": "django_redis.client.DefaultClient", # "CLIENT_CLASS": "django_redis.client.DefaultClient",
# "PICKLE_VERSION": -1 # "PICKLE_VERSION": -1
@ -203,7 +203,7 @@ AUTHENTICATION_BACKENDS = (
# } # }
# celery配置,celery正常运行必须安装redis # celery配置,celery正常运行必须安装redis
CELERY_BROKER_URL = "redis://redis:6379/0" # 任务存储 CELERY_BROKER_URL = "redis://127.0.0.1:6379/1" # 任务存储
CELERYD_MAX_TASKS_PER_CHILD = 100 # 每个worker最多执行300个任务就会被销毁可防止内存泄露 CELERYD_MAX_TASKS_PER_CHILD = 100 # 每个worker最多执行300个任务就会被销毁可防止内存泄露
CELERY_TIMEZONE = 'Asia/Shanghai' # 设置时区 CELERY_TIMEZONE = 'Asia/Shanghai' # 设置时区
CELERY_ENABLE_UTC = True # 启动时区设置 CELERY_ENABLE_UTC = True # 启动时区设置