Python+OpenCV人臉識別簽到考勤系統(tǒng)實現(xiàn)(附demo)
前言
本項目為IOT實驗室人員簽到考勤設(shè)計,系統(tǒng)實現(xiàn)功能:
1.人員人臉識別并完成簽到/簽退
2.考勤時間計算
3.保存考勤數(shù)據(jù)為CSV格式(Excel表格)
PS:本系統(tǒng)2D人臉識別,節(jié)約了繁瑣的人臉識別訓(xùn)練部分,簡潔快捷
該項目為測試版,正式版會加入更多的功能,持續(xù)更新中…
測試版項目地址我會放到結(jié)尾
項目效果圖
系統(tǒng)初始化登陸界面

主界面展示圖:

簽到功能展示


簽退功能展示

后臺簽到數(shù)據(jù)記錄

是否簽到/退判斷

項目需要的環(huán)境
核心環(huán)境:
- OpenCV-Python 4.5.5.64
- face_recognition 1.30
- face_recognition_model 0.3.0
- dlib 19.23.1
UI窗體界面:
- PyQt5 5.15.4
- pyqt5-plugins 5.15.4.2.2
- PyQt5-Qt5 5.15.2
- PyQt5-sip 12.10.1
- pyqt5-tools 5.15.4.3.2
編譯器
Pycham 2021.1.3

Python版本 3.9.12

Anaconda

輔助開發(fā)QT-designer


項目配置

代碼部分
核心代碼
MainWindow.py
UI文件加載:
class Ui_Dialog(QDialog):
def __init__(self):
super(Ui_Dialog, self).__init__()
loadUi("mainwindow.ui", self) #加載QTUI文件
self.runButton.clicked.connect(self.runSlot)
self._new_window = None
self.Videocapture_ = None
攝像頭調(diào)用:
def refreshAll(self):
print("當(dāng)前調(diào)用人倆檢測攝像頭編號(0為筆記本內(nèi)置攝像頭,1為USB外置攝像頭):")
self.Videocapture_ = "0"
OutWindow.py
獲取當(dāng)前系統(tǒng)時間
class Ui_OutputDialog(QDialog):
def __init__(self):
super(Ui_OutputDialog, self).__init__()
loadUi("./outputwindow.ui", self) #加載輸出窗體UI
#datetime 時間模塊
now = QDate.currentDate()
current_date = now.toString('ddd dd MMMM yyyy') #時間格式
current_time = datetime.datetime.now().strftime("%I:%M %p")
self.Date_Label.setText(current_date)
self.Time_Label.setText(current_time)
self.image = None
簽到時間計算
def ElapseList(self,name):
with open('Attendance.csv', "r") as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
line_count = 2
Time1 = datetime.datetime.now()
Time2 = datetime.datetime.now()
for row in csv_reader:
for field in row:
if field in row:
if field == 'Clock In':
if row[0] == name:
Time1 = (datetime.datetime.strptime(row[1], '%y/%m/%d %H:%M:%S'))
self.TimeList1.append(Time1)
if field == 'Clock Out':
if row[0] == name:
Time2 = (datetime.datetime.strptime(row[1], '%y/%m/%d %H:%M:%S'))
self.TimeList2.append(Time2)
人臉識別部分
# 人臉識別部分
faces_cur_frame = face_recognition.face_locations(frame)
encodes_cur_frame = face_recognition.face_encodings(frame, faces_cur_frame)
for encodeFace, faceLoc in zip(encodes_cur_frame, faces_cur_frame):
match = face_recognition.compare_faces(encode_list_known, encodeFace, tolerance=0.50)
face_dis = face_recognition.face_distance(encode_list_known, encodeFace)
name = "unknown" #未知人臉識別為unknown
best_match_index = np.argmin(face_dis)
if match[best_match_index]:
name = class_names[best_match_index].upper()
y1, x2, y2, x1 = faceLoc
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.rectangle(frame, (x1, y2 - 20), (x2, y2), (0, 255, 0), cv2.FILLED)
cv2.putText(frame, name, (x1 + 6, y2 - 6), cv2.FONT_HERSHEY_COMPLEX, 0.5, (255, 255, 255), 1)
mark_attendance(name)
return frame
簽到數(shù)據(jù)保存與判斷
# csv表格保存數(shù)據(jù)
def mark_attendance(name):
"""
:param name: 人臉識別部分
:return:
"""
if self.ClockInButton.isChecked():
self.ClockInButton.setEnabled(False)
with open('Attendance.csv', 'a') as f:
if (name != 'unknown'): #簽到判斷:是否為已經(jīng)識別人臉
buttonReply = QMessageBox.question(self, '歡迎 ' + name, '開始簽到' ,
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if buttonReply == QMessageBox.Yes:
date_time_string = datetime.datetime.now().strftime("%y/%m/%d %H:%M:%S")
f.writelines(f'\n{name},{date_time_string},Clock In')
self.ClockInButton.setChecked(False)
self.NameLabel.setText(name)
self.StatusLabel.setText('簽到')
self.HoursLabel.setText('開始簽到計時中')
self.MinLabel.setText('')
self.Time1 = datetime.datetime.now()
self.ClockInButton.setEnabled(True)
else:
print('簽到操作失敗')
self.ClockInButton.setEnabled(True)
elif self.ClockOutButton.isChecked():
self.ClockOutButton.setEnabled(False)
with open('Attendance.csv', 'a') as f:
if (name != 'unknown'):
buttonReply = QMessageBox.question(self, '嗨呀 ' + name, '確認簽退?',
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if buttonReply == QMessageBox.Yes:
date_time_string = datetime.datetime.now().strftime("%y/%m/%d %H:%M:%S")
f.writelines(f'\n{name},{date_time_string},Clock Out')
self.ClockOutButton.setChecked(False)
self.NameLabel.setText(name)
self.StatusLabel.setText('簽退')
self.Time2 = datetime.datetime.now()
self.ElapseList(name)
self.TimeList2.append(datetime.datetime.now())
CheckInTime = self.TimeList1[-1]
CheckOutTime = self.TimeList2[-1]
self.ElapseHours = (CheckOutTime - CheckInTime)
self.MinLabel.setText("{:.0f}".format(abs(self.ElapseHours.total_seconds() / 60)%60) + 'm')
self.HoursLabel.setText("{:.0f}".format(abs(self.ElapseHours.total_seconds() / 60**2)) + 'h')
self.ClockOutButton.setEnabled(True)
else:
print('簽退操作失敗')
self.ClockOutButton.setEnabled(True)
項目目錄結(jié)構(gòu)

后記
因為本系統(tǒng)沒有進行人臉訓(xùn)練建立模型,系統(tǒng)誤識別率較高,安全性較低
系統(tǒng)優(yōu)化較差,攝像頭捕捉幀數(shù)較低(8-9),后臺占有高,CPU利用率較高
數(shù)據(jù)保存CSV格式,安全性較低
正式版改進
1.加入TensorFlow深度學(xué)習(xí),提高系統(tǒng)人臉識別安全性與準確性
2.加入MySQL數(shù)據(jù)庫,對簽到數(shù)據(jù)進行更安全保護,不易被修改
3.美化優(yōu)化UI設(shè)計
項目下載
到此這篇關(guān)于Python+OpenCV人臉識別簽到考勤系統(tǒng)實現(xiàn)(新手入門)的文章就介紹到這了,更多相關(guān)Python OpenCV人臉識別簽到內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳談python read readline readlines的區(qū)別
下面小編就為大家?guī)硪黄斦刾ython read readline readlines的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-09-09
基于python + django + whoosh + jieba 分詞器實現(xiàn)站內(nèi)檢索功能
這篇文章主要介紹了基于python + django + whoosh + jieba 分詞器實現(xiàn)站內(nèi)檢索功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-08-08
Python selenium的安裝和下載谷歌瀏覽器鏡像驅(qū)動
Selenium是一個用于web自動化測試的框架,在使用Ajax請求數(shù)據(jù)的頁面中,會出現(xiàn) sign ,token等密鑰,借助使用Selenium框架來實現(xiàn)數(shù)據(jù)爬取很不錯,本文給大家介紹Python selenium的安裝和下載谷歌瀏覽器鏡像驅(qū)動,需要的朋友可以參考下2022-11-11

