python实现人脸签到系统
作者:M_Lter 发布时间:2023-12-21 06:35:05
标签: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()
更多学习资料请关注专题《管理系统开发》。
来源:https://blog.csdn.net/lidengdengter/article/details/94853431
0
投稿
猜你喜欢
- python的文件和路径操作函数基本上位于os和os.path模块中。os.listdir(dirname):列出dirname下的目录和文
- 本文实例讲述了PHP实现获取第一个中文首字母并进行排序的方法。分享给大家供大家参考,具体如下:最近在做储值结算,需求里结算首页需要按门店的首
- 1. 多曲线1.1 使用pyplot方式import numpy as npimport matplotlib.pyplot as pltx
- SQL Server PRIMARY KEY(主键)约束简介主键是唯一标识表中每一行的一列或一组列。您可以使用主键约束为表创建主键。如果主键
- 设计师在抱怨开发人员不尊重Web标准,后台开发人员在抱怨为什么不可以增加一个空格。PM在抱怨为什么项目总是因为那些看似简单的问题而延期……如
- 后边要做一个微信小程序,并要能获取用户微信绑定的手机号码。而小程序开发文档上边提供的获取手机号码的接口(getPhoneNumber())返
- 产生原因:先说一下Git和SVN的区别吧,有助于更好的理解这个问题。SVN从服务器上update文件时,如果文件有冲突,SVN会自动帮你me
- Python tkinter中label控件动态改变值最近在用tkinter做大作业,因为是第一次接触tkinter,所以会遇到很多问题。比
- 1、查询语句的执行顺序select[distinct] from join(如left 
- Sybase于2008年11月4日在大中华区用户大会上宣布,联手神州数码金程(北京)科技有限公司对旗下领先的SQL Anywhere数据库进
- 机器视觉从Google的无人驾驶汽车到可以识别假钞的自动售卖机,机器视觉一直都是一个应用广泛且具有深远的影响和雄伟的愿景的领域。这里我们将重
- SQL Server 2005默认是不允许远程连接的,要想通过远程连接实现MSSQL,数据库备份,需要做如下设置:步骤/方法1.打开SQL
- Git 恢复到之前版本1. 应用场景进行了错误提交,需要将代码回退至某个版本;或者需要检出某个版本的代码,再切换回最新版本。2. 解决方法2
- 匿名管道管道是一个单向通道,有点类似共享内存缓存.管道有两端,包括输入端和输出端.对于一个进程的而言,它只能看到管道一端,即要么是输入端要么
- Jupyter 是数据分析领域非常有名的开发环境,使用 Jupyter 写数据分析相关的代码会大大节约开发时间。设想这样一个场景:别的部门的
- mpvue使用# 全局安装 vue-cli$ npm install --global vue-cli# 创建一个基于 mpvue-quic
- 本文实例讲述了php 多继承的几种常见实现方法。分享给大家供大家参考,具体如下:class Parent1 { function
- 有时需要根据项目的实际需求向spider传递参数以控制spider的行为,比如说,根据用户提交的url来控制spider爬取的网站。在这种情
- 1、安装类库pip install pyautogui2、代码:import pyautogui,time,randompyautogui.
- 如下所示:群里一朋友发了一个如上图的问题,解决方法如下data = {'a':[1,1,1,1,1,1,1,1,2,2,2,