python实现人脸签到系统


Posted in Python onApril 13, 2020

本文实例为大家分享了python实现人脸签到系统的具体代码,供大家参考,具体内容如下

简易版人脸签到/签退系统

管理员可进行录入人脸操作,以及导出各类签到情况表;

普通学生只可人脸识别进行签到签退操作。

python实现人脸签到系统

face_Recognizer.py

import cv2
import os
import numpy as np
from PIL import Image #pillow
import pyttsx3
import sys
import test.student_sql as connect #导入py
import test.recognizer_sql as baseConnect #导入py
import time
import json
 
def makeDir(engine):
 flag= 0
 if not os.path.exists("face_trainer"):
  print("创建预训练环境")
  engine.say('检测到第一次启动,未检测到环境,正在创建环境')
  engine.say('正在创建预训练环境')
  os.mkdir("face_trainer")
  engine.say('创建成功')
  engine.runAndWait()
  flag=1
 if not os.path.exists("Facedata"):
  print("创建训练环境")
  engine.say('正在创建训练环境')
  os.mkdir("Facedata")
  engine.say('创建成功')
  engine.runAndWait()
  flag=1
 return flag
 
def getFace(cap,path_id):
 # 调用笔记本内置摄像头,所以参数为0,如果有其他的摄像头可以调整参数为1,2
 #cap = cv2.VideoCapture(0)
 #xml文件为自己的文件路径
 face_detector = cv2.CascadeClassifier(r'F:\npyWorkspace\venv\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml')
 #face_id = input('\n enter user id:')
 print('\n Initializing face capture. Look at the camera and wait ...')
 count = 0
 while True:
  # 从摄像头读取图片
  sucess, img = cap.read()
  # 转为灰度图片
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  # 检测人脸
  faces = face_detector.detectMultiScale(gray, 1.3, 5)
  for (x, y, w, h) in faces:
   cv2.rectangle(img, (x, y), (x+w, y+w), (255, 0, 0))
   count += 1
   # 保存图像
   cv2.imwrite("Facedata/User." + str(path_id) + '.' + str(count) + '.jpg', gray[y: y + h, x: x + w])
   cv2.imshow('image', img)
  # 保持画面的持续。
  k = cv2.waitKey(1)
  if k == 27: # 通过esc键退出摄像
   break
  elif count >= 100: # 得到1000个样本后退出摄像
   break
 cv2.destroyAllWindows()
 
def getImagesAndLabels(path, detector):
 imagePaths = [os.path.join(path, f) for f in os.listdir(path)] # join函数的作用
 faceSamples = []
 ids = []
 for imagePath in imagePaths:
  PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale
  img_numpy = np.array(PIL_img, 'uint8')
  id = int(os.path.split(imagePath)[-1].split(".")[1])
  faces = detector.detectMultiScale(img_numpy)
  for (x, y, w, h) in faces:
   faceSamples.append(img_numpy[y:y + h, x: x + w])
   ids.append(id)
 return faceSamples, ids
 
 
def trainFace():
 # 人脸数据路径
 path = 'Facedata'
 recognizer = cv2.face.LBPHFaceRecognizer_create()
 detector = cv2.CascadeClassifier(r'F:\npyWorkspace\venv\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml')
 print('Training faces. It will take a few seconds. Wait ...')
 faces, ids = getImagesAndLabels(path, detector)
 recognizer.train(faces, np.array(ids))
 recognizer.write(r'face_trainer\trainer.yml')
 print("{0} faces trained. Exiting Program".format(len(np.unique(ids))))
 
def checkFace(cam,names,engine,sign_flag):
 sex = {"female":"女士","male":"先生"}
 recognizer = cv2.face.LBPHFaceRecognizer_create()
 recognizer.read('face_trainer/trainer.yml')
 cascadePath = r"F:\npyWorkspace\venv\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml"
 faceCascade = cv2.CascadeClassifier(cascadePath)
 font = cv2.FONT_HERSHEY_SIMPLEX
 idnum = 0
 names = ['yumengzhen', 'dujuanjuan','litingting','kangming','wangyizhe']
 #cam = cv2.VideoCapture(0)
 minW = 0.1 * cam.get(3)
 minH = 0.1 * cam.get(4)
 while True:
  ret, img = cam.read()
  gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  faces = faceCascade.detectMultiScale(
   gray,
   scaleFactor=1.2,
   minNeighbors=5,
   minSize=(int(minW), int(minH))
  )
  for (x, y, w, h) in faces:
   cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
   idnum, confidence = recognizer.predict(gray[y:y + h, x:x + w])
   if confidence < 100:
    Name =connect.readName(idnum) #connect 传入ID 学生信息表找到 返回 name
    Sex =connect.readSex(idnum) #connect ID 学生信息表找到 返回 Sex
    StudentID =connect.readStudentID(idnum) #connect ID 学生信息表找到 返回 studentID
    #idnum = names[idnum] #利用数据库 读取学生信息表 该id 对应的name
    confidence = "{0}%".format(round(100 - confidence))
    if sign_flag=='0': #签到
     say(engine, "欢迎   "+Name+ sex[Sex]+"   签到成功 ")
     baseConnect.insertd(idnum,Name,StudentID,Sex) #签到表中 插入签到信息
     print("欢迎  "+Name+ sex[Sex] + "签到成功 ")
    else :
     say(engine, "欢迎   "+Name+ sex[Sex]+"   签退成功 ")
     baseConnect.insertt(idnum,Name,StudentID,Sex) #签到表中 插入签退信息
     print("欢迎  "+Name+ sex[Sex] + "签退成功 ")
 
    cv2.imshow("img",img)
    os.system("pause")
    return
   else:
    idnum = "unknown"
    confidence = "{0}%".format(round(100 - confidence))
   cv2.putText(img, str(idnum), (x + 5, y - 5), font, 1, (0, 0, 255), 1)
   cv2.putText(img, str(confidence), (x + 5, y + h - 5), font, 1, (0, 0, 0), 1)
  cv2.imshow('camera', img)
  k = cv2.waitKey(10)
  if k == 27:
   break
 cam.release()
 cv2.destroyAllWindows()
 
 
def say(engine,str):
 engine.say(str)
 engine.runAndWait()
 
def admission(): #录入信息模块
 #names = {"yumengzhen":0,"dujuanjuan":1,"litingting":2}
 say(engine, "请输入您的学号   ")
 StudentID = input("请输入学号:")
 # 读取数据库信息表 取出Name 对应ID
 ID=connect.readIDbaseStudentID(StudentID) #connect 传入name 学生信息表找到 返回 ID
 if ID==-1:#没有找到该学生插入学生信息
  while True:
   say(engine,"没有找到该学生信息 输人 0 注册 1重新输入")
   op=input("\n 没有找到该学生信息 输人数字 0 注册学生信息 1重新输入")
   if op=='0':
    Name,studentID,Sex=input("输入学生信息: Name studentID Sex").split()
    connect.insert(Name,studentID,Sex) #插入学生信息信息
   else:
    StudentID = input("请输入学号:")
   ID=connect.readIDbaseStudentID(StudentID) #connect 传入name 学生信息表找到 返回 ID
   if ID!=-1 :
    break
 say(engine, "正在打开摄像头")
 cam = cv2.VideoCapture(0)
 say(engine, "注视摄像头,开始采集人脸数据")
 getFace(cam, ID) # 实际传入的是id
 cam.release()
 
 
if __name__ == '__main__':
 names = {"yumengzhen":0,"dujuanjuan":1,"litingting": 2}
 password="123456" #密码
 engine = pyttsx3.init()
 rate = engine.getProperty('rate')
 engine.setProperty('rate', rate - 20)
 flag=makeDir(engine)
 #trainFace()
 while True:
  if flag==1 :
   flag = 0
   say(engine, "首次使用 没有人脸信息 ")
   say(engine, "是否要录入新的人脸信息  ")
   say(engine, "输入0 代表是 输入其他表示退出")
   value = input("0:是 or other:否")
   if value=='0':
    while True:
     admission()
     say(engine, "是否要继续录入新的人脸信息  ")
     say(engine, "输入0 代表是 输入其他表示退出")
     firstflag = input("0:是 其他:退出")
     if firstflag != '0':
      break
    say(engine, "采集完毕,开始训练")
    trainFace()
    say(engine, "训练完毕   ")
 
  #say(engine, "请选择登录方式 ")
  say(engine, "输入 0管理人员模式  1 进入签到/签退模式  2 退出学生签到系统 ")
  user=input("\n0:管理人员模式  1:进入签到/签退模式 2:退出学生签到系统\n")
 
  if user=='0':
   say(engine, "输入管理员密码 ")
   pd=input("\n输入管理员密码 :\n")
   count=1
   while True:
    if count==3:
     say(engine," 输入密码错误超过3次 强制退出输入  ")
     break
 
    if password == pd:
     say(engine, "管理员模式 ")
     #say(engine, "输入数字 0 导出签到表  1 导出个人签到表  2 导出时长表  3 导出信息表  4 录入人脸信息 5 退出")
     op = input("\n0:导出所有同学签到表 1:导出个人签到表 2:导出所有人员时长表 3:导出学生信息表 4 录入人脸信息 5 退出\n")
     if op == '0':
      baseConnect.sign()#导出签到表
      say(engine, "导出签到表成功 ")
      pass
     elif op == '1':
      say(engine,"输入导出学生的学号")
      StudentID=input("输入导出学生的学号")
      ID=connect.readIDbaseStudentID(StudentID)
      if ID==-1:
       say(engine, "没有该学生信息 ")
      else:
       baseConnect.peoson_sign(StudentID)#导出个人签到表
       Name =connect.readName(ID) #connect 传入ID 学生信息表找到 返回 name
       say(engine, "导出 "+Name+" 信息成功")
 
     elif op == '2':
      baseConnect.total_time()#导出时长表
      say(engine,"导出时长表成功  ")
     elif op == '3':
      #导出学生信息表
      connect.find_student_all()
      say(engine, "导出学生信息成功  ")
     elif op == '4':
      while True:
       admission()
       say(engine, "是否要继续录入新的人脸信息  ")
       say(engine, "输入0 代表是 输入其他表示退出")
       secondflag = input("0:是 其他:退出")
       if secondflag != '0':
        break
      say(engine, "采集完毕,开始训练")
      trainFace()
      say(engine, "训练完毕   ")
     elif op == '5':
      say(engine, "已退出 管理员模式 ")
      break
     else:
      say(engine, "输入形式错误 请重新输入  ")
    else:
     say(engine, "输入密码错误  请重新输入 ")
     pd = input("\n输入管理员密码 :\n")
     count += 1;
 
  elif user=='1':
   say(engine, "欢迎进入学生系统签到/签退模式  ")
   sign_flag=0;
   while True:
    say(engine, "输入数字 0 签到  1 签退")
    sign_flag = input("\n0: 签到  1 签退\n")
    if sign_flag=='1' or sign_flag=='0' :
     break
    else :
     say(engine," 请输入正确的输入形式")
   say(engine, "开始人脸识别")
   say(engine, "正在打开摄像头")
   cam = cv2.VideoCapture(0)
   checkFace(cam, names, engine,sign_flag)
 
  elif user=='2':
   say(engine, "信息已保存")
   say(engine, "再见")
   sys.exit(0)
  else:
   say(engine, "输入错误请重新输入  ")

student_sql.py  

学生

import pymssql as py
import pandas as pd
# 连接数据库,创建学生表,进行表查询,表录入
server = "DESKTOP-XXX"# 连接自己数据库的服务器地址
user = "sa"# 连接帐号
password = "123"# 连接密码
conn = py.connect(server, user, password, "student_message") #获取连接
cursor = conn.cursor() # 获取光标
 
# 创建表
cursor.execute("""
IF OBJECT_ID('students', 'U') IS NOT NULL
 DROP TABLE students
CREATE TABLE students (
 ID INT NOT NULL,
 name VARCHAR(100),
 StudentID INT,
 Sex VARCHAR(100)
 )
""")
conn.commit()
#第一次运行时建立表,之后再运行无需再建
 
def insert(Name, studentID, Sex):
  count_students = 0
  try:
   conn = py.connect(server, user, password, "student_message") # 获取连接
   cursor =conn.cursor()
   cursor.execute(' select count(ID) from students')
   for row in cursor:
    count_students = row[0]
    print(row[0])
   cursor.executemany(
    "INSERT INTO students VALUES (%d, %s, %d,%s)",
    [(count_students+1, Name, studentID, Sex)])
  # 你必须调用 commit() 来保持你数据的提交如果你没有将自动提交设置为true
   conn.commit()
   conn.close()
  except py.InterfaceError:
   print("数据库连接出错")
  except py.ProgrammingError:
   print("数据错误,请检查输入的数据")
  except py.OperationalError:
   print("数据错误,请检查输入的数据")
 
 
# 导出学生信息表
def find_student_all():
 try:
  conn = py.connect(server, user, password, "student_message") # 获取连接
  cursor =conn.cursor()
  sql = "select * from students"
  df = pd.read_sql(sql, conn)
  df.to_excel('all.xlsx',index=False)
  print('ok')
  conn.commit()
  conn.close()
 except py.InterfaceError:
  print("数据库连接出错")
 except py.ProgrammingError:
  print("数据错误,请检查输入的数据")
 
#find_student_all()
 
def readName(idnum):
 Name = -1
 try:
  conn = py.connect(server, user, password, "student_message") # 获取连接
  cursor =conn.cursor()
  cursor.execute(' select Name from students where ID='+str(idnum))
  for row in cursor:
   if row[0]!=[]:
    Name = row[0]
  conn.commit()
  conn.close()
 except py.InterfaceError:
  print("数据库连接出错")
 except py.ProgrammingError:
  print("数据错误,请检查输入的数据")
 return Name
 
def readIDbaseStudentID(StudentID):
 ID = -1
 try:
  conn = py.connect(server, user, password, "student_message") # 获取连接
  cursor =conn.cursor()
  cursor.execute(' select ID from students where StudentID='+str(StudentID))
  for row in cursor:
   if row[0]!=[]:
    ID = row[0]
  conn.commit()
  conn.close()
 except py.InterfaceError:
  print("数据库连接出错")
 except py.ProgrammingError:
  print("数据错误,请检查输入的数据")
 return ID
 
def readSex(idnum):
 Sex = -1
 try:
  conn = py.connect(server, user, password, "student_message") # 获取连接
  cursor =conn.cursor()
  cursor.execute(' select Sex from students where ID='+str(idnum))
  for row in cursor:
    if row[0]!=[]:
     Sex = row[0]
  conn.commit()
  conn.close()
 except py.InterfaceError:
  print("数据库连接出错")
 except py.ProgrammingError:
  print("数据错误,请检查输入的数据")
 return Sex
 
 
def readID(name):
 # 多个id
 ID = -1
 try:
  conn = py.connect(server, user, password, "student_message") # 获取连接
  cursor =conn.cursor()
  cursor.execute(' select ID from students where name='+'\''+str(name)+'\'')
  for row in cursor:
   if row[0]!=[]:
    ID = row[0]
  conn.commit()
  conn.close()
 except py.InterfaceError:
  print("数据库连接出错")
 except py.ProgrammingError:
  print("数据错误,请检查输入的数据")
 return ID
 
 
def readStudentID(idnum):
 StudentID = -1
 try:
  conn = py.connect(server, user, password, "student_message") # 获取连接
  cursor =conn.cursor()
  cursor.execute(' select StudentID from students where ID='+str(idnum))
  for row in cursor:
   if row[0]!=[]:
    StudentID = row[0]
  conn.commit()
  conn.close()
 except py.InterfaceError:
  print("数据库连接出错")
 except py.ProgrammingError:
  print("数据错误,请检查输入的数据")
 return StudentID
 
 
# 关闭连接
# conn.close()
#
# # 注:在任何时候,在一个连接下,一次正在执行的数据库操作只会出现一个cursor对象

recognizer_sql.py

import pymssql as py
import time
import pandas as pd
 
server = "DESKTOP-XXXX"# 连接服务器地址
user = "sa" # 连接帐号
password = "123" # 连接密码
conn = py.connect(server, user, password, "student_message") #获取连接
cursor = conn.cursor() # 获取光标
 
def insertd(idnum,Name,StudentID,Sex): # 签到
 conn = py.connect(server, user, password, "student_message") # 获取连接
 timenow = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
 cursor = conn.cursor()
 cursor.execute("INSERT INTO qiandao VALUES (%d, %s,%d,%s, %s, %s, %s,%d )", (idnum,Name,StudentID,Sex,timenow, '0', '0', 0))
 conn.commit()
 # 必须调用 commit() 来保持数据的提交
def insertt(idnum,Name,StudentID,Sex): # 签退
 conn = py.connect(server, user, password, "student_message") # 获取连接
 cursor = conn.cursor()
 cursor.execute("SELECT starttime FROM qiandao WHERE ID=%s and flag=%d",(idnum,0))
 starttimeget = cursor.fetchone()
 sat = str(tuple(starttimeget))
 timenow = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
 timeArray = time.strptime(sat, "('%Y-%m-%d %H:%M:%S',)")
 timeStamp = int(time.mktime(timeArray))
 timecout = time.time() - timeStamp
 m, s = divmod(timecout, 60)
 h, m = divmod(m, 60)
 timepass = str(h) + '小时 ' + str(m) + '分钟 ' + str(s) + '秒'
 print(timepass)
 cursor.executemany("INSERT INTO qiandao VALUES (%d, %s,%d,%s, %s, %s, %s,%d )",
  [(idnum,Name,StudentID,Sex,'0', timenow, timepass, 1)])
 conn.commit()
 
def peoson_sign(StudentID):# 导出学生信息表_按照学号
 conn = py.connect(server, user, password, "student_message") # 获取连接
 cursor = conn.cursor()
 sql = "select * from qiandao where StudentID=" + str(StudentID)
 df = pd.read_sql(sql, conn)
 df.to_excel(r'E:\01STUDY\20190701\work\openVersion\excel\studentID_sign.xlsx',index=False)
 print('ok')
 conn.commit()
 
#peoson_sign(2016002105)
 
def sign():# 导出签到表
 conn = py.connect(server, user, password, "student_message") # 获取连接
 cursor = conn.cursor()
 sql = "select * from qiandao"
 df = pd.read_sql(sql, conn)
 df.to_excel(r'E:\01STUDY\20190701\work\openVersion\excel\sign_all.xlsx', index=False)
 print('ok')
 conn.commit()
#sign()
 
def total_time():# 导出时长表#sign()
 conn = py.connect(server, user, password, "student_message") # 获取连接
 cursor = conn.cursor()
 sql = "select * from qiandao where convert(nvarchar(max),count) != convert(nvarchar(max),0)"
 df = pd.read_sql(sql, conn)
 df.to_excel(r'E:\01STUDY\20190701\work\openVersion\excel\total_time.xlsx', index=False)
 print('ok')
 conn.commit()
 
#
# if __name__=='__main':
#  sign()
#  #peoson_sign(2016002105)
 
conn.close()

更多学习资料请关注专题《管理系统开发》。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python list使用示例 list中找连续的数字
Jan 27 Python
Python实现的几个常用排序算法实例
Jun 16 Python
Python文件和目录操作详解
Feb 08 Python
详解Python中类的定义与使用
Apr 11 Python
Python 稀疏矩阵-sparse 存储和转换
May 27 Python
使用numba对Python运算加速的方法
Oct 15 Python
利用python开发app实战的方法
Jul 09 Python
pycharm配置git(图文教程)
Aug 16 Python
python双端队列原理、实现与使用方法分析
Nov 27 Python
python3用urllib抓取贴吧邮箱和QQ实例
Mar 10 Python
Pycharm自动添加文件头注释和函数注释参数的方法
Oct 23 Python
python爬虫selenium模块详解
Mar 30 Python
python实现IOU计算案例
Apr 12 #Python
python 已知平行四边形三个点,求第四个点的案例
Apr 12 #Python
python 已知三条边求三角形的角度案例
Apr 12 #Python
python实现输入三角形边长自动作图求面积案例
Apr 12 #Python
Python3如何判断三角形的类型
Apr 12 #Python
Python判断三段线能否构成三角形的代码
Apr 12 #Python
Python 实现打印单词的菱形字符图案
Apr 12 #Python
You might like
php在线生成ico文件的代码
2007/10/09 PHP
php数组函数序列之array_combine() - 数组合并函数使用说明
2011/10/29 PHP
PHP SFTP实现上传下载功能
2017/07/26 PHP
javascript unicode与GBK2312(中文)编码转换方法
2013/11/14 Javascript
JavaScript简单表格编辑功能实现方法
2015/04/16 Javascript
jQuery ajax提交Form表单实例(附demo源码)
2016/04/06 Javascript
JS 根据子网掩码,网关计算出所有IP地址范围示例
2020/04/23 Javascript
JavaScript实现同一个页面打开多张图片
2016/12/29 Javascript
使用Webpack提高Vue.js应用的方式汇总(四种)
2017/07/10 Javascript
JQuery事件冒泡和默认行为代码实例
2020/05/13 jQuery
浅谈vue-props的default写不写有什么区别
2020/08/09 Javascript
React实现轮播效果
2020/08/25 Javascript
[14:24]Optic Gaming vs PSG LGD BO3
2018/06/07 DOTA
使用python编写脚本获取手机当前应用apk的信息
2014/07/21 Python
Python性能提升之延迟初始化
2016/12/04 Python
使用Python的Scrapy框架十分钟爬取美女图
2016/12/26 Python
一个基于flask的web应用诞生(1)
2017/04/11 Python
python 脚本生成随机 字母 + 数字密码功能
2018/05/26 Python
Python 利用pydub库操作音频文件的方法
2019/01/09 Python
在Python中过滤Windows文件名中的非法字符方法
2019/06/10 Python
selenium+Chrome滑动验证码破解二(某某网站)
2019/12/17 Python
Selenium常见异常解析及解决方案示范
2020/04/10 Python
如何解决cmd运行python提示不是内部命令
2020/07/01 Python
专门出售各种儿童读物的网站:Put Me In The Story
2016/08/07 全球购物
俄罗斯香水和化妆品购物网站:Л’Этуаль
2018/05/10 全球购物
PHP解析URL是哪个函数?怎么用?
2013/05/09 面试题
会计员岗位职责
2014/03/15 职场文书
父母对孩子的寄语
2014/04/09 职场文书
劳模事迹材料范文
2014/12/24 职场文书
2015年师德师风承诺书
2015/01/22 职场文书
护林员个人总结
2015/03/04 职场文书
2016年幼儿园万圣节活动总结
2016/04/05 职场文书
CSS3 菱形拼图实现只旋转div 背景图片不旋转功能
2021/03/30 HTML / CSS
vue中利用mqtt服务端实现即时通讯的步骤记录
2021/07/01 Vue.js
24年收藏2000多部退役军用电台
2022/02/18 无线电
python Tkinter模块使用方法详解
2022/04/07 Python