人脸识别基本完成

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'
# 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)
jobstate = models.IntegerField('在职状态', choices=jobstate_choices, default=1)
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:
verbose_name = '员工补充信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.name

View File

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

View File

@ -1,12 +1,13 @@
from django.db.models import base
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 rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('employee', EmployeeViewSet, basename='employee')
urlpatterns = [
path('facelogin/', FaceLogin.as_view()),
path('', include(router.urls)),
]

View File

@ -1,9 +1,34 @@
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet, GenericViewSet
from rest_framework.mixins import UpdateModelMixin, RetrieveModelMixin
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
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.
class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMixin, RetrieveModelMixin, GenericViewSet):
"""
@ -13,3 +38,70 @@ class EmployeeViewSet(CreateUpdateModelAMixin, OptimizationMixin, UpdateModelMix
queryset = Employee.objects.all()
serializer_class = EmployeeSerializer
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
class FaceLoginSerializer(serializers.Serializer):
base64 = serializers.CharField()

View File

@ -1,5 +1,5 @@
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
@ -15,6 +15,5 @@ router.register('ptask', PTaskViewSet, basename="ptask")
urlpatterns = [
path('', include(router.urls)),
path('task/', TaskList.as_view()),
path('test/', TestView.as_view()),
path('facelogin/', FaceLogin.as_view())
path('test/', TestView.as_view())
]

View File

@ -21,6 +21,7 @@ from rest_framework.views import APIView
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework.exceptions import ValidationError, ParseError
from apps.hrm.models import Employee
from utils.queryset import get_child_queryset2
from .filters import UserFilter
@ -29,7 +30,7 @@ from .models import (Dict, DictType, File, Organization, Permission, Position,
Role, User)
from .permission import RbacPermission, get_permission_list
from .permission_data import RbacFilterSet
from .serializers import (DictSerializer, DictTypeSerializer, FaceLoginSerializer, FileSerializer,
from .serializers import (DictSerializer, DictTypeSerializer, FileSerializer,
OrganizationSerializer, PermissionSerializer,
PositionSerializer, RoleSerializer, PTaskSerializer,PTaskCreateUpdateSerializer,
UserCreateSerializer, UserListSerializer,
@ -352,43 +353,3 @@ class FileViewSet(CreateModelMixin, DestroyModelMixin, RetrieveModelMixin, ListM
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('这不是曹前明')