基于Python+SQLite+django人脸识别签到系统设计与实现

目 录
1 概述 1
1.1课题背景及意义 1
1.2 国内外研究现状 1
1.3 本课题主要工作 2
2 系统开发环境 3
2.1 python简介 3
2.2 人脸识别简介 4
2.3 SQLite 5
2.4 Django介绍 6
2.5 TensorFlow 7
3 系统分析 8
3.1 可行性分析 8
3.1.1 技术可行性 8
3.1.2操作可行性 8
3.1.3 经济可行性 9
3.1.4 法律可行性 9
3.2需求分析 9
3.2.1 功能需求分析 9
3.2.2 性能需求分析 10
3.3开发环境分析 10
3.4界面需求 10
4 系统设计 12
4.1系统设计原则 12
4.2系统流程设计 12
4.2.1系统开发流程 12
4.2.2 添加信息流程 13
4.2.3 人脸识别流程 14
4.3 系统功能设计 15
4.4 数据库设计 15
4.4.1 数据库设计原则 15
4.4.2 数据库实体 16
4.4.3 数据库表设计 16
5系统实现 18
5.1 登录 18
5.2 注册 18
5.3 识别签到 20
6系统测试 25
6.1测试环境与条件 25
6.2功能测试 25
6.3可用性测试 26
6.4测试结果分析 26
结 论 27
致 谢 28
参考文献 29
3.2需求分析
所谓需求分析就是,需求人员通过与客户的沟通,所获取的信息,然后把这些信息通过需求说明书的方式展示给用户和开发人员。在软件功能发展的历史长河中,很长时间,特别是最开始的时候,需求分析的重要性并不被人们所认同,例如当时美国IBM公司为英国电信公司开发一套信息管理系统,在需求不明确的情况下开始开发,最初的工期为一年,由于需求获取不清晰导致工期推迟了半年多,造成巨大损失。我们很多软件公司也存在这种情况,边需求,边开发,甚至与客户没有沟通清楚的情况下,直接照搬同类型的项目进行更改,导致到系统验收的时候,重新更改,造成了人力、物力的极大浪费。而导致这一切后果的原因就是需求获取不及时、不清楚、不全面。
3.2.1 功能需求分析
登录:输入用户名和密码尽心登录。
注册:对学生的姓名、学号、班级、专业、脸部(正面、侧面)进行采集。
签到:通过拍照获取人脸进行签到。
签到查询:查询签到信息。
用户管理:管理用户和签到记录。
3.2.2 性能需求分析
简单性:由于使用本系统的大都是系统管理员,用户,有的人对计算机可能不是非常熟练,可能产生操作错误,造成损失,所以我们在实现该管理系统的功能的同时,尽量让系统操作普遍简单,让本系统真正的可以为管理者以及用户带来便利。
针对性:我们是通过对用户或企业需求调查才设计的该人脸是被系统,所以本系统是主要针对管理者以及用户,有极大的针对性。
实用性:本系统的功能都是与人脸识别信息管理有关,所以具有实用性,对管理者,用户均有所帮助。
一致性:页面采用了统一的色彩,操作几乎相同,规则也是差不多的,不同人员的操作都是简单易懂的,页面统一,操作单一,功能强大。
先进性:本系统采用python技术、相关类库等被广泛采用系统开发技术和数据库,因此本设计具有良好的先进性,具体表现在其具有良好的可扩展性,可开发性。
3.3开发环境分析
(1)开发硬件平台:
CPU:酷睿I5及以上
内存:4G以上
硬盘:80G以上
(2) 开发软件平台:
操作系统:Windows 7
开发语言:python
开发工具:Pycharm
数据库:SQLite

from django.shortcuts import render

import base64
from io import BytesIO
import threading
from django.http import JsonResponse
from PIL import Image
from . import face_task
from .models import User, Check
import pickle, numpy as np
from django.utils import timezone
from .forms import BootstrapAuthenticationForm
import datetime

work_time = 45  ## 每节课上课+休息时间

init_time = [float((datetime.datetime.strptime("8.30", "%H.%M") +
                    datetime.timedelta(minutes=work_time * x)).strftime("%H.%M"))
             for x in range(5)] + [
                float((datetime.datetime.strptime("14.00", "%H.%M") +
                       datetime.timedelta(minutes=work_time * x)).strftime("%H.%M"))
                for x in range(5)]  ### 每节课开始的时间
print("每节课开始时间", init_time)  ## 错过时间点签到 就算是迟到


def checkLogin(func):
    def check(request, *args, **kwargs):
        if request.user.is_anonymous:
            return render(request, "login.html", {
    
    "form": BootstrapAuthenticationForm()})
        else:
            return func(request, *args, **kwargs)

    return check


# Create your views here.
def index(request):
    if request.method == "GET":

        return render(request, "index.html")
    else:
        img_content = request.POST.get("img").replace("data:image/jpeg;base64,", "").replace("data:image/png;base64,",
                                                                                             "")
        faceencodings = face_task.get_face_encoding(BytesIO(base64.b64decode(img_content)))
        users = []
        for encoding in faceencodings:
            face_names = face_task.base_match_faces(encoding, face_task.known_face_encodings,
                                                    face_task.known_face_names)
            users.append(face_names)

        if len(users) == 0:
            return JsonResponse({
    
    "code": 200, "data": []})

        method = request.POST.get("method", "work")
        now_time = float(datetime.datetime.now().strftime("%H.%M"))
        work_status = ""
        if method == "work":
            for i, x in enumerate(init_time):
                if now_time > x:
                    if i < len(init_time) - 1 and now_time < init_time[i + 1]:
                        work_status = f"第{i + 1}节课迟到"
                        break
                    else:
                        continue
                if now_time <= x:
                    work_status = f"第{i + 1}节课出勤"
                    break
            else:
                if work_status == "":
                    work_status = f"第{len(init_time)}节课迟到"

        else:
            for i, x in enumerate(init_time):
                if now_time > x:
                    if i < len(init_time) - 1 and now_time < init_time[i + 1]:
                        work_status = f"第{i + 1}节课签退正常"
                        break
                    else:
                        continue
                if now_time <= x:
                    work_status = f"第{i + 1}节课早退"
                    break
            else:
                if work_status == "":
                    work_status = f"第{len(init_time)}节课签退正常"
        status = []
        for username in users:
            try:
                user = User.objects.get(username=username)
            except:
                continue

            try:
                check = Check.objects.get(user=user, status__icontains=work_status.split("课")[0],
                                          time__gte=timezone.now().date(), method=method)
            except Check.DoesNotExist:
                Check.objects.create(user=user, status=work_status, method=method)
                status.append(f"{username} {work_status}")

        return JsonResponse({
    
    "code": 200, "data": status})


def register(request):
    if request.method == "GET":

        return render(request, "register.html")
    else:
        img1 = request.POST.get("face1").replace("data:image/jpeg;base64,",
                                                 "").replace("data:image/png;base64,", "")

        img2 = request.POST.get("face2").replace("data:image/jpeg;base64,",
                                                 "").replace("data:image/png;base64,", "")

        img3 = request.POST.get("face3").replace("data:image/jpeg;base64,",
                                                 "").replace("data:image/png;base64,", "")
        encodings = face_task.get_face_encoding([BytesIO(base64.b64decode(img1)),
                                                 BytesIO(base64.b64decode(img2)),
                                                 BytesIO(base64.b64decode(img3)), ])
        print(encodings)
        if len(encodings) != 3:
            return JsonResponse({
    
    "code": 500, "msg": "您其中有一张图片没有检测到人脸哦!", })

        password = request.POST.get("password", "")
        clss = request.POST.get("clss", "")
        pro = request.POST.get("pro", "")
        snum = request.POST.get("snum", "")
        college = request.POST.get("college", "")
        username = request.POST.get("username")

        if "" in [password, clss, pro, snum, college, username]:
            return JsonResponse({
    
    "code": 500, "msg": "请填入正确的信息!", })

        user = User.objects.create_user(username=username,
                                        password=password,
                                        clss=clss,
                                        pro=pro,
                                        snum=snum,
                                        college=college,
                                        feature1=str(list(encodings[0])),
                                        feature2=str(list(encodings[1])),
                                        feature3=str(list(encodings[2]))
                                        )
        face_task.known_face_names, face_task.known_face_encodings = face_task.load_all_users()
        return JsonResponse({
    
    "code": 200, "msg": "用户注册成功!", "data": {
    
    "user": user.username}})


#
def face_online(request):
    img3 = BytesIO(
        base64.b64decode(request.POST.get("img").replace("data:image/jpeg;base64,",
                                                         "").replace("data:image/png;base64,", "")))
    face = face_task.face_detector(np.array(Image.open(img3).convert("RGB")), 1)

    return JsonResponse({
    
    "code": 200, "data": len(face)})


from django.db.models import Q

from django.db.models import Sum, Count, Value, Avg



def search(request):
    if request.method == "GET":
        return render(request, "search.html")
    else:
        lst = []
        username = request.POST.get("username", "")

        college = request.POST.get("college", "")
        snum = request.POST.get("snum", "")
        pro = request.POST.get("pro", "")
        clss = request.POST.get("clss", "")
        date  =  request.POST.get("date", " - ")

        date1, date2 = date.split(" - ") if " - " in date else "",""
        if username != "":
            lst.append(Q(user__username=username))


        if college != "":
            lst.append(Q(user__college=college))
        if snum != "":
            lst.append(Q(user__snum=snum))
        if pro != "":
            lst.append(Q(user__pro=pro))

        if clss != "":
            lst.append(Q(user__clss=clss))
        if len(lst) > 0:
            checks = Check.objects.filter(lst[0])
            for x in lst[1:]:
                checks = checks.filter(x)
        else:
            checks = Check.objects.all()

        if date1 != "":
            date1 = datetime.datetime.strptime(date1, "%Y-%m-%d")
            date2 = datetime.datetime.strptime(date2, "%Y-%m-%d")
            checks = checks.filter(time__gte=date1, time__lte=date2)


        data = [{
    
    "username": x.user.username,
                 "time": x.time,
                 "status": x.status,
                 "pro":x.user.pro,
                 "snum":x.user.snum,
                 "college":x.user.college,
                 "clss":x.user.clss,

                 } for x in checks]

        over_time = checks.filter(status__icontains="迟到").count()
        early_time = checks.filter(status__icontains="早退").count()
        on_time = checks.filter(status__icontains="出勤").count()
        on_time_out = checks.filter(status__icontains="正常").count()
        user_data = {
    
    
            "name": '出勤统计',
            "type": 'pie',
            "radius": [30, 100],

            "data": [

            ]
        }
        if over_time:
            user_data["data"].append({
    
    "value": over_time, "name": '迟到'})
        if early_time:
            user_data["data"].append({
    
    "value": early_time, "name": '早退'})
        if on_time:
            user_data["data"].append({
    
    "value": on_time, "name": '出勤'}, )
        if on_time_out:
            user_data["data"].append({
    
    "value": on_time_out, "name": '签退正常'}, )




        return JsonResponse({
    
    "code": 200, "data": {
    
    "user_data": user_data, "detail": data}})

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sheziqiong/article/details/131167677
今日推荐