人脸识别基本完成
This commit is contained in:
parent
96b40f101d
commit
7509ff0e15
|
|
@ -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'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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='人脸识别数据'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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)),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -199,5 +199,3 @@ class UserCreateSerializer(serializers.ModelSerializer):
|
||||||
return phone
|
return phone
|
||||||
|
|
||||||
|
|
||||||
class FaceLoginSerializer(serializers.Serializer):
|
|
||||||
base64 = serializers.CharField()
|
|
||||||
|
|
@ -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())
|
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -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('这不是曹前明')
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue