人脸识别基本完成

This commit is contained in:
caoqianming 2021-10-18 14:18:11 +08:00
parent 96b40f101d
commit 7509ff0e15
9 changed files with 128 additions and 52 deletions

View File

@ -2,5 +2,6 @@
ENV = 'production' ENV = 'production'
# base api # base api
VUE_APP_BASE_API = 'http://47.95.0.242:2222/api' #VUE_APP_BASE_API = 'http://47.95.0.242:2222/api'
VUE_APP_BASE_API = 'http://127.0.0.1:8000/api'

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.6 on 2021-10-18 05:26
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('hrm', '0002_auto_20210924_1127'),
]
operations = [
migrations.AddField(
model_name='employee',
name='face_data',
field=models.JSONField(blank=True, null=True, verbose_name='人脸识别数据'),
),
]

View File

@ -28,9 +28,12 @@ class Employee(CommonAModel):
academic = models.CharField('学历', max_length=50, null=True, blank=True) academic = models.CharField('学历', max_length=50, null=True, blank=True)
jobstate = models.IntegerField('在职状态', choices=jobstate_choices, default=1) jobstate = models.IntegerField('在职状态', choices=jobstate_choices, default=1)
job = models.ForeignKey(Position, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='岗位') job = models.ForeignKey(Position, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='岗位')
face_data = models.JSONField('人脸识别数据', null=True, blank=True)
class Meta: class Meta:
verbose_name = '员工补充信息' verbose_name = '员工补充信息'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
def __str__(self): def __str__(self):
return self.name return self.name

View File

@ -1,6 +1,6 @@
from apps.system.models import User from apps.system.models import User
from rest_framework.serializers import ModelSerializer from rest_framework.serializers import ModelSerializer
from rest_framework import serializers
from .models import Employee from .models import Employee
from apps.system.serializers import UserListSerializer, UserSimpleSerializer from apps.system.serializers import UserListSerializer, UserSimpleSerializer
from django.db.models.query import Prefetch from django.db.models.query import Prefetch
@ -20,3 +20,6 @@ class EmployeeSerializer(ModelSerializer):
# queryset=User.objects.filter(employee_user__isnull=True)) # queryset=User.objects.filter(employee_user__isnull=True))
# ) # )
# return queryset # return queryset
class FaceLoginSerializer(serializers.Serializer):
base64 = serializers.CharField()

View File

@ -1,12 +1,13 @@
from django.db.models import base from django.db.models import base
from rest_framework import urlpatterns from rest_framework import urlpatterns
from apps.hrm.views import EmployeeViewSet from apps.hrm.views import EmployeeViewSet, FaceLogin
from django.urls import path, include from django.urls import path, include
from rest_framework.routers import DefaultRouter from rest_framework.routers import DefaultRouter
router = DefaultRouter() router = DefaultRouter()
router.register('employee', EmployeeViewSet, basename='employee') router.register('employee', EmployeeViewSet, basename='employee')
urlpatterns = [ urlpatterns = [
path('facelogin/', FaceLogin.as_view()),
path('', include(router.urls)), path('', include(router.urls)),
] ]

View File

@ -1,9 +1,34 @@
from django.shortcuts import render from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet, GenericViewSet from rest_framework.viewsets import ModelViewSet, GenericViewSet
from rest_framework.mixins import UpdateModelMixin, RetrieveModelMixin from rest_framework.mixins import UpdateModelMixin, RetrieveModelMixin
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
from apps.hrm.models import Employee from apps.hrm.models import Employee
from apps.hrm.serializers import EmployeeSerializer from apps.hrm.serializers import EmployeeSerializer, 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 import status
from rest_framework_simplejwt.tokens import RefreshToken
from apps.system.models import User
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):
""" """
@ -12,4 +37,71 @@ class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMix
perms_map = {'get': '*', 'put': 'employee_update'} perms_map = {'get': '*', 'put': 'employee_update'}
queryset = Employee.objects.all() queryset = Employee.objects.all()
serializer_class = EmployeeSerializer serializer_class = EmployeeSerializer
ordering = ['-pk'] ordering = ['-pk']
def perform_update(self, serializer):
instance = serializer.save(update_by = self.request.user)
try:
photo_path = settings.BASE_DIR + instance.photo
picture_of_me = face_recognition.load_image_file(photo_path)
my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
instance.face_data = my_face_encoding.tolist()
instance.save()
except:
logger.error('人脸识别出错')
import uuid
import base64
import os
def tran64(s):
missing_padding = len(s) % 4
if missing_padding != 0:
s = s+'='* (4 - missing_padding)
return s
class FaceLogin(CreateAPIView):
authentication_classes = []
permission_classes = []
serializer_class = FaceLoginSerializer
def create(self, request, *args, **kwargs):
"""
人脸识别登录
"""
# serializer = FaceLoginSerializer(data=request.data)
# serializer.is_valid(raise_exception=True)
filename = str(uuid.uuid4())
filepath = settings.BASE_DIR +'/temp/' + filename +'.png'
with open(filepath, 'wb') as f:
data = tran64(request.data.get('base64').replace(' ', '+'))
f.write(base64.urlsafe_b64decode(data))
# picture_of_me = face_recognition.load_image_file(settings.BASE_DIR +'/temp/me.png')
# my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
#results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding, tolerance=0.2)
try:
unknown_picture = face_recognition.load_image_file(filepath)
unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0]
os.remove(filepath)
except:
logger.error('解码失败')
# 匹配人脸库
user_faces = Employee.objects.filter(face_data__isnull=False, user__is_active=True).values('user', 'face_data')
user_l = []
face_l = []
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.2)
for index, value in enumerate(results):
if value:
# 识别成功
refresh = RefreshToken.for_user(User.objects.get(id=user_l[index]))
return Response({
'refresh': str(refresh),
'access': str(refresh.access_token),
})
return Response('未找到对应用户', status=status.HTTP_400_BAD_REQUEST)

View File

@ -199,5 +199,3 @@ class UserCreateSerializer(serializers.ModelSerializer):
return phone return phone
class FaceLoginSerializer(serializers.Serializer):
base64 = serializers.CharField()

View File

@ -1,5 +1,5 @@
from django.urls import path, include from django.urls import path, include
from .views import FaceLogin, TaskList, UserViewSet, OrganizationViewSet, PermissionViewSet, RoleViewSet, PositionViewSet, TestView, DictTypeViewSet, DictViewSet, PTaskViewSet from .views import TaskList, UserViewSet, OrganizationViewSet, PermissionViewSet, RoleViewSet, PositionViewSet, TestView, DictTypeViewSet, DictViewSet, PTaskViewSet
from rest_framework import routers from rest_framework import routers
@ -15,6 +15,5 @@ router.register('ptask', PTaskViewSet, basename="ptask")
urlpatterns = [ urlpatterns = [
path('', include(router.urls)), path('', include(router.urls)),
path('task/', TaskList.as_view()), path('task/', TaskList.as_view()),
path('test/', TestView.as_view()), path('test/', TestView.as_view())
path('facelogin/', FaceLogin.as_view())
] ]

View File

@ -21,6 +21,7 @@ from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet, ModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet
from rest_framework_simplejwt.tokens import RefreshToken from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework.exceptions import ValidationError, ParseError from rest_framework.exceptions import ValidationError, ParseError
from apps.hrm.models import Employee
from utils.queryset import get_child_queryset2 from utils.queryset import get_child_queryset2
from .filters import UserFilter from .filters import UserFilter
@ -29,7 +30,7 @@ from .models import (Dict, DictType, File, Organization, Permission, Position,
Role, User) Role, User)
from .permission import RbacPermission, get_permission_list from .permission import RbacPermission, get_permission_list
from .permission_data import RbacFilterSet from .permission_data import RbacFilterSet
from .serializers import (DictSerializer, DictTypeSerializer, FaceLoginSerializer, FileSerializer, from .serializers import (DictSerializer, DictTypeSerializer, FileSerializer,
OrganizationSerializer, PermissionSerializer, OrganizationSerializer, PermissionSerializer,
PositionSerializer, RoleSerializer, PTaskSerializer,PTaskCreateUpdateSerializer, PositionSerializer, RoleSerializer, PTaskSerializer,PTaskCreateUpdateSerializer,
UserCreateSerializer, UserListSerializer, UserCreateSerializer, UserListSerializer,
@ -352,43 +353,3 @@ class FileViewSet(CreateModelMixin, DestroyModelMixin, RetrieveModelMixin, ListM
instance.save() instance.save()
#import face_recognition
import uuid
import base64
import os
def tran64(s):
missing_padding = len(s) % 4
if missing_padding != 0:
s = s+'='* (4 - missing_padding)
return s
class FaceLogin(CreateAPIView):
authentication_classes = []
permission_classes = []
serializer_class = FaceLoginSerializer
def create(self, request, *args, **kwargs):
"""
人脸识别登录
"""
# serializer = FaceLoginSerializer(data=request.data)
# serializer.is_valid(raise_exception=True)
filename = str(uuid.uuid4())
filepath = settings.BASE_DIR +'/temp/' + filename +'.png'
with open(filepath, 'wb') as f:
data = tran64(request.data.get('base64').replace(' ', '+'))
f.write(base64.urlsafe_b64decode(data))
# picture_of_me = face_recognition.load_image_file(settings.BASE_DIR +'/temp/me.png')
# my_face_encoding = face_recognition.face_encodings(picture_of_me)[0]
# unknown_picture = face_recognition.load_image_file(filepath)
# unknown_face_encoding = face_recognition.face_encodings(unknown_picture)[0]
#results = face_recognition.compare_faces([my_face_encoding], unknown_face_encoding, tolerance=0.2)
os.remove(filepath)
# if results[0] == True:
# return Response('这是曹前明')
# else:
# return Response('这不是曹前明')