Python实现简单的人脸打卡系统

Python实现简单的人脸打卡系统

参考链接:https://blog.csdn.net/weixin_44451017/article/details/89086065?utm_medium=distribute.pc_relevant_download.none-task-blog-baidujs-1.nonecase&depth_1-utm_source=distribute.pc_relevant_download.none-task-blog-baidujs-1.nonecase

源码下载链接:https://pan.baidu.com/s/16uyAqdUbCNbBwR45q1Zoag

提取码: pb4c 

最近看到了一个比较有兴趣的东西,这个效果大概就是这个样子。

主要源码

# -*- coding: utf-8 -*-

import tkinter as tk
from tkinter import ttk
from tkinter.filedialog import *
import tkinter.messagebox
from PIL import Image, ImageTk
import img_api2
import cv2
import threading
import time

class Login(ttk.Frame):
    def __init__(self, win):
        ttk.Frame.__init__(self, win)
        frame0 = ttk.Frame(self)
        frame1 = ttk.Frame(self)
        win.title("人脸打卡考勤")
        win.minsize(800, 550)
        self.center_window()
        self.thread_run = None
        self.thread_run2 = None
        self.camera = None

        #开始的画面,可以自行选择图片
        self.pilImage = Image.open("img/start.png")
        self.tkImage = ImageTk.PhotoImage(image=self.pilImage)
        self.image_ctl = tk.Label(frame0, image=self.tkImage)
        self.image_ctl.pack()

        frame0.pack(side=TOP, fill=tk.Y, expand=1)
        frame1.pack(side=TOP, fill=tk.Y, expand=1)

        self.facer = ttk.Label(frame1, text='', font=('Times', '20'))
        self.facer.pack()

        #self.face_button1 = ttk.Button(frame1, text="选择文件", width=15, command=self.file1)
        #self.face_button1.pack(side=TOP)
        self.url_face_button = ttk.Button(frame1, text="使用相机识别", width=15, command=self.cv_face)
        self.url_face_button.pack(side=TOP)
        #self.file_pic_button = ttk.Button(frame1, text="本地文件识别", width=15, command=self.file_pic)
        #self.file_pic_button.pack(side=TOP)

        self.pack(fill=tk.BOTH, expand=tk.YES, padx="10", pady="10")

    #使弹出的窗体处于屏幕的中间位置
    def center_window(self):
        screenwidth = log.winfo_screenwidth()
        screenheight = log.winfo_screenheight()
        log.update()
        width = log.winfo_width()
        height = log.winfo_height()
        size = '+%d+%d' % ((screenwidth - width)/2, (screenheight - height)/2)
        log.geometry(size)

    def file1(self):
        self.pic_path = askopenfilename(title="选择识别图片", filetypes=[("jpg图片", "*.jpg"), ("png图片", "*.png")])

    def cv_face(self):
        if self.thread_run:
            if self.camera.isOpened():
                self.camera.release()
                print("关闭摄像头")
                self.camera = None
                self.thread_run = False
            return
        if self.camera is None:
            self.camera = cv2.VideoCapture(1)
            if not self.camera.isOpened():
                self.camera = None
                print("没有外置摄像头")
                self.camera = cv2.VideoCapture(0)
                if not self.camera.isOpened():
                    print("没有内置摄像头")
                    tkinter.messagebox.showinfo('警告', '摄像头打开失败!')
                    self.camera = None
                    return
                else:
                    print("打开内置摄像头")
            else:
                print("打开外置摄像头")
        self.thread = threading.Thread(target=self.video_thread)
        self.thread.setDaemon(True)
        self.thread.start()
        self.thread_run = True

    def video_thread(self):
        self.thread_run = True
        self.thread2 = threading.Thread(target=self.video_pic)
        self.thread2.setDaemon(True)
        self.thread2.start()
        self.thread_run2 = True
        while self.thread_run:
            _, img_bgr = self.camera.read()
            img = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
            im = Image.fromarray(img)
            w, h = im.size
            pil_image_resized = self.resize(w, h, im)
            self.imgtk = ImageTk.PhotoImage(image=pil_image_resized)
            self.image_ctl.configure(image=self.imgtk)
        print("run end")

    def video_pic(self):
        self.thread_run2 = True
        predict_time = time.time()
        while self.thread_run2:
            if time.time() - predict_time > 2:
                print("实时识别中")
                _, img_bgr = self.camera.read()
                cv2.imwrite("tmp/test.jpg", img_bgr)
                self.pic_path = "tmp/test.jpg"
                try:
                    self.file_pic()
                except:
                    pass
                predict_time = time.time()
                print("video_pic")
        pass

    def file_pic(self):
        self.pic_path2 = "img/mango.jpg"
        facestr, result = img_api2.facef(self.pic_path, self.pic_path2)
        self.facer.configure(text=str(facestr))
        self.pic()
        if result > 80:
            tkinter.messagebox.showinfo('提示', '打卡成功!')
            try:
                f=open("打卡记录.txt","r")
                fi=open("打卡记录.txt","a")
                txt=time.ctime()
                fi.write(txt+"   Mango  打卡成功 \n")
                f.close()
                fi.close()
            except:
                f=open("打卡记录.txt","w")
                txt=time.ctime()
                f.write(txt+"   Mango  打卡成功 \n")
                f.close()
                
            
            
            # close_window()
            # os.system("python3 ./main.py")
        else:
            tkinter.messagebox.showinfo('提示', '登录失败,请重试!')

    def pic(self):
        self.pilImage3 = Image.open(self.pic_path)
        w, h = self.pilImage3.size
        pil_image_resized = self.resize(w, h, self.pilImage3)
        self.tkImage3 = ImageTk.PhotoImage(image=pil_image_resized)
        self.image_ctl.configure(image=self.tkImage3)

    def resize(self, w, h, pil_image):
        w_box = 800
        h_box = 400
        f1 = 1.0*w_box/w
        f2 = 1.0*h_box/h
        factor = min([f1, f2])
        width = int(w*factor)
        height = int(h*factor)
        return pil_image.resize((width, height), Image.ANTIALIAS)


def close_window():
    print("log destroy")
    log.destroy()


if __name__ == '__main__':
    log = tk.Tk()

    login = Login(log)
    # close,退出输出destroy
    log.protocol('WM_DELETE_WINDOW', close_window)
    # 进入消息循环
    log.mainloop()

img_api2.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import requests
import os
import base64
import json

ACCESS_TOKEN = ''
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# ID,KEY的配置信息
INFO_CONFIG = {
    'ID': '15788358',
    'API_KEY': 'ohtGa5yYoQEZ8Try8lnL99UK',
    'SECRET_KEY': 'qaDjyuXkf5MZ28g5C8pwFngDZenhswC3'
}

# URL配置
URL_LIST_URL = {
    # ACCESS_TOKEN_URL用于获取ACCESS_TOKEN, POST请求,
    #  grant_type必须参数,固定为client_credentials,client_id必须参数,应用的API Key,client_secre 必须参数,应用的Secret Key.
    'ACCESS_TOKEN_URL': 'https://aip.baidubce.com/oauth/2.0/token?' + 'grant_type=client_credentials&client_id={API_KEYS}&client_secret={SECRET_KEYS}&'.format(
        API_KEYS=INFO_CONFIG['API_KEY'], SECRET_KEYS=INFO_CONFIG['SECRET_KEY']),
    # 人脸识别
    'FACE_PLATE': 'https://aip.baidubce.com/rest/2.0/face/v3/match',

}


class AccessTokenSuper(object):
    pass


class AccessToken(AccessTokenSuper):
    def getToken(self):
        accessToken = requests.post(url=URL_LIST_URL['ACCESS_TOKEN_URL'])
        accessTokenJson = accessToken.json()
        if dict(accessTokenJson).get('error') == 'invalid_client':
            return '获取accesstoken错误,请检查API_KEY,SECRET_KEY是否正确!'
        return accessTokenJson


ACCESS_TOKEN = AccessToken().getToken()['access_token']

LICENSE_PLATE_URL = URL_LIST_URL['FACE_PLATE'] + '?access_token={}'.format(ACCESS_TOKEN)


class faceSuper(object):
    pass


class face(faceSuper):

    def __init__(self, image=None, image2=None):
        self.HEADER = {
            'Content-Type': 'application/json; charset=UTF-8',
        }
        if image is not None:
            imagepath = os.path.exists(image)
            if imagepath == True:
                images = image
                with open(images, 'rb') as images:
                    img1 = base64.b64encode(images.read())
            else:
                print("img1 not exits")
                return
        if image2 is not None:
            imagepath2 = os.path.exists(image2)
            if imagepath2 == True:
                images2 = image2
                with open(images2, 'rb') as images2:
                    img2 = base64.b64encode(images2.read())
            else:
                print("img2 not exits")
                return
        self.img = img1
        self.imgs = img2
        self.IMAGE_CONFIG1 = {"image": str(img1, 'utf-8'), "image_type": "BASE64"}
        self.IMAGE_CONFIG2 = {"image": str(img2, 'utf-8'), "image_type": "BASE64"}
        self.IMAGE_CONFIG = json.dumps([self.IMAGE_CONFIG1, self.IMAGE_CONFIG2])

    def postface(self):
        if (self.img==None and self.imgs==None):
            return 'image参数不能为空!'
        face = requests.post(url=LICENSE_PLATE_URL, headers=self.HEADER, data=self.IMAGE_CONFIG)
        return face.json()


def facef(FA1, FA2):
    testAccessToken = AccessToken()
    testface = face(image=FA1, image2=FA2)
    result_json = testface.postface()
    result = result_json['result']['score']
    print('人脸相似度:', result)
    if result > 80:
        print("是同一个人")
    else:
        print("不是同一个人")
    return '人脸相似度:' + str(result), result

猜你喜欢

转载自blog.csdn.net/yql_617540298/article/details/108479057
今日推荐