日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

python實現(xiàn)的人臉識別打卡系統(tǒng)

瀏覽:147日期:2022-06-20 11:26:36
目錄項目地址:簡介使用主要代碼項目地址:

https://github.com/king-xw/Face_Recogntion

簡介

本倉庫是使用python編寫的一個簡單的人臉識別考勤打卡系統(tǒng)

主要功能有錄入人臉信息、人臉識別打卡、設(shè)置上下班時間、導(dǎo)出打卡日志等

下面是各模塊截圖

首頁

python實現(xiàn)的人臉識別打卡系統(tǒng)

錄入人臉信息

python實現(xiàn)的人臉識別打卡系統(tǒng)

人臉識別打卡

python實現(xiàn)的人臉識別打卡系統(tǒng)

輸出日志

python實現(xiàn)的人臉識別打卡系統(tǒng)

使用

直接運行**==workAttendanceSystem==**.py即可

主要代碼

import datetimeimport timeimport win32apiimport win32conimport wximport wx.gridimport sqlite3from time import localtime, strftimeimport osfrom skimage import io as iioimport ioimport zlibimport dlib # 人臉識別的庫dlibimport numpy as np # 數(shù)據(jù)處理的庫numpyimport cv2 # 圖像處理的庫OpenCvimport _threadimport threadingimport win32com.clientimport tkinter as tkfrom tkinter import filedialogimport csvspk = win32com.client.Dispatch('SAPI.SpVoice')ID_NEW_REGISTER = 160ID_FINISH_REGISTER = 161ID_START_PUNCHCARD = 190ID_END_PUNCARD = 191ID_TODAY_LOGCAT = 283ID_CUSTOM_LOGCAT = 284ID_WORKING_HOURS = 301ID_OFFWORK_HOURS = 302ID_DELETE = 303ID_WORKER_UNAVIABLE = -1PATH_FACE = 'data/face_img_database/'# face recognition model, the object maps human faces into 128D vectorsfacerec = dlib.face_recognition_model_v1('model/dlib_face_recognition_resnet_model_v1.dat')# Dlib 預(yù)測器detector = dlib.get_frontal_face_detector()predictor = dlib.shape_predictor(’model/shape_predictor_68_face_landmarks.dat’)def speak_info(info): spk.Speak(info)def return_euclidean_distance(feature_1, feature_2): feature_1 = np.array(feature_1) feature_2 = np.array(feature_2) dist = np.sqrt(np.sum(np.square(feature_1 - feature_2))) print('歐式距離: ', dist) if dist > 0.4:return 'diff' else:return 'same'class WAS(wx.Frame): def __init__(self):wx.Frame.__init__(self, parent=None,, size=(920, 560))self.Folderpath = Noneself.initMenu()self.initInfoText()self.initGallery()self.initDatabase()self.initData() def initData(self):self.name = ''self.id = ID_WORKER_UNAVIABLEself.face_feature = ''self.pic_num = 0self.flag_registed = Falseself.loadDataBase(1) def initMenu(self):menuBar = wx.MenuBar() # 生成菜單欄menu_Font = wx.Font() # Font(faceName='consolas',pointsize=20)menu_Font.SetPointSize(14)menu_Font.SetWeight(wx.BOLD)registerMenu = wx.Menu() # 生成菜單self.new_register = wx.MenuItem(registerMenu, ID_NEW_REGISTER, '新建錄入')self.new_register.SetBitmap(wx.Bitmap('drawable/new_register.png'))self.new_register.SetTextColour('SLATE BLACK')self.new_register.SetFont(menu_Font)registerMenu.Append(self.new_register)self.finish_register = wx.MenuItem(registerMenu, ID_FINISH_REGISTER, '完成錄入')self.finish_register.SetBitmap(wx.Bitmap('drawable/finish_register.png'))self.finish_register.SetTextColour('SLATE BLACK')self.finish_register.SetFont(menu_Font)self.finish_register.Enable(False)registerMenu.Append(self.finish_register)puncardMenu = wx.Menu()self.start_punchcard = wx.MenuItem(puncardMenu, ID_START_PUNCHCARD, '開始簽到')self.start_punchcard.SetBitmap(wx.Bitmap('drawable/start_punchcard.png'))self.start_punchcard.SetTextColour('SLATE BLACK')self.start_punchcard.SetFont(menu_Font)puncardMenu.Append(self.start_punchcard)self.end_puncard = wx.MenuItem(puncardMenu, ID_END_PUNCARD, '結(jié)束簽到')self.end_puncard.SetBitmap(wx.Bitmap('drawable/end_puncard.png'))self.end_puncard.SetTextColour('SLATE BLACK')self.end_puncard.SetFont(menu_Font)self.end_puncard.Enable(False)puncardMenu.Append(self.end_puncard)logcatMenu = wx.Menu()self.today_logcat = wx.MenuItem(logcatMenu, ID_TODAY_LOGCAT, '輸出今日日志')self.today_logcat.SetBitmap(wx.Bitmap('drawable/open_logcat.png'))self.today_logcat.SetFont(menu_Font)self.today_logcat.SetTextColour('SLATE BLACK')logcatMenu.Append(self.today_logcat)self.custom_logcat = wx.MenuItem(logcatMenu, ID_CUSTOM_LOGCAT, '輸出自定義日志')self.custom_logcat.SetBitmap(wx.Bitmap('drawable/open_logcat.png'))self.custom_logcat.SetFont(menu_Font)self.custom_logcat.SetTextColour('SLATE BLACK')logcatMenu.Append(self.custom_logcat)setMenu = wx.Menu()self.working_hours = wx.MenuItem(setMenu, ID_WORKING_HOURS, '上班時間')self.working_hours.SetBitmap(wx.Bitmap('drawable/close_logcat.png'))self.working_hours.SetFont(menu_Font)self.working_hours.SetTextColour('SLATE BLACK')setMenu.Append(self.working_hours)self.offwork_hours = wx.MenuItem(setMenu, ID_OFFWORK_HOURS, '下班時間')self.offwork_hours.SetBitmap(wx.Bitmap('drawable/open_logcat.png'))self.offwork_hours.SetFont(menu_Font)self.offwork_hours.SetTextColour('SLATE BLACK')setMenu.Append(self.offwork_hours)self.delete = wx.MenuItem(setMenu, ID_DELETE, '刪除人員')self.delete.SetBitmap(wx.Bitmap('drawable/end_puncard.png'))self.delete.SetFont(menu_Font)self.delete.SetTextColour('SLATE BLACK')setMenu.Append(self.delete)menuBar.Append(registerMenu, '&人臉錄入')menuBar.Append(puncardMenu, '&刷臉簽到')menuBar.Append(logcatMenu, '&考勤日志')menuBar.Append(setMenu, '&設(shè)置')self.SetMenuBar(menuBar)self.Bind(wx.EVT_MENU, self.OnNewRegisterClicked, id=ID_NEW_REGISTER)self.Bind(wx.EVT_MENU, self.OnFinishRegisterClicked, id=ID_FINISH_REGISTER)self.Bind(wx.EVT_MENU, self.OnStartPunchCardClicked, id=ID_START_PUNCHCARD)self.Bind(wx.EVT_MENU, self.OnEndPunchCardClicked, id=ID_END_PUNCARD)self.Bind(wx.EVT_MENU, self.ExportTodayLog, id=ID_TODAY_LOGCAT)self.Bind(wx.EVT_MENU, self.ExportCustomLog, id=ID_CUSTOM_LOGCAT)self.Bind(wx.EVT_MENU, self.SetWorkingHours, id=ID_WORKING_HOURS)self.Bind(wx.EVT_MENU, self.SetOffWorkHours, id=ID_OFFWORK_HOURS)self.Bind(wx.EVT_MENU, self.deleteBtn, id=ID_DELETE) def SetWorkingHours(self, event):global workingglobal setWorkingSignsetWorkingSign = Falseself.loadDataBase(1)# self.working_hours.Enable(True)self.working_hours = wx.GetTextFromUser(message='請輸入上班時間', caption='溫馨提示', default_value='08:00:00',parent=None)working = self.working_hourssetWorkingSign = Truepass def SetOffWorkHours(self, event):global offworkingself.loadDataBase(1)# self.offwork_hours.Enable(True)self.offwork_hours = wx.GetTextFromUser(message='請輸入下班時間', caption='溫馨提示', default_value='18:00:00',parent=None)offworking = self.offwork_hourswin32api.MessageBox(0, '請確保同時設(shè)置上班時間和下班時間并且先設(shè)置上班時間', '提醒', win32con.MB_ICONWARNING)if setWorkingSign: self.loadDataBase(4)else: win32api.MessageBox(0, '您未設(shè)置上班時間', '提醒', win32con.MB_ICONWARNING)pass def ExportTodayLog(self, event):global Folderpath1Folderpath1 = ''self.save_route1(event)if not Folderpath1 == '': self.loadDataBase(3) day = time.strftime('%Y-%m-%d') path = Folderpath1 + '/' + day + '.csv' f = open(path, ’w’, newline=’’, encoding=’utf-8’) csv_writer = csv.writer(f) csv_writer.writerow(['編號', '姓名', '打卡時間', '是否遲到']) size = len(logcat_id) index = 0 while size - 1 >= index:localtime1 = str(logcat_datetime[index]).replace(’[’, ’’).replace(’]’, ’’)csv_writer.writerow([logcat_id[index], logcat_name[index], localtime1, logcat_late[index]])index += 1; f.close()pass def ExportCustomLog(self, event):global dialogglobal t1global t2global Folderpath2Folderpath2 = ''dialog = wx.Dialog(self)Label1 = wx.StaticText(dialog, -1, '輸入員工id', pos=(30, 10))t1 = wx.TextCtrl(dialog, -1, ’’, pos=(130, 10), size=(130, -1))Label2 = wx.StaticText(dialog, -1, '輸出日期(天)', pos=(30, 50))sampleList = [u’1’, u’3’, u’7’, u’30’]t2 = wx.ComboBox(dialog, -1, value='1', pos=(130, 50), size=(130, -1), choices=sampleList, style=wx.CB_READONLY)button = wx.Button(dialog, -1, '選擇文件保存路徑', pos=(120, 90))button.Bind(wx.EVT_BUTTON, self.save_route2, button)btn_confirm = wx.Button(dialog, 1, '確認(rèn)', pos=(30, 150))btn_close = wx.Button(dialog, 2, '取消', pos=(250, 150))btn_close.Bind(wx.EVT_BUTTON, self.OnClose, btn_close)btn_confirm.Bind(wx.EVT_BUTTON, self.DoCustomLog, btn_confirm)dialog.ShowModal()pass # 關(guān)閉主窗口前確認(rèn)一下是否真的關(guān)閉 def OnClose(self, event):dlg = wx.MessageDialog(None, u’確定要關(guān)閉本窗口嗎?’, u’操作提示’, wx.YES_NO)if dlg.ShowModal() == wx.ID_YES: dialog.Destroy() def OnClose1(self, event):dlg = wx.MessageDialog(None, u’確定要關(guān)閉本窗口嗎?’, u’操作提示’, wx.YES_NO)if dlg.ShowModal() == wx.ID_YES: dialog1.Destroy() def OnYes(self, event):dlg = wx.MessageDialog(None, u’確定要刪除該編號的員工?’, u’操作提示’, wx.YES_NO)if dlg.ShowModal() == wx.ID_YES: return True def deleteBtn(self, event):global dialog1global t4dialog1 = wx.Dialog(self)Label1 = wx.StaticText(dialog1, -1, '輸入員工id: ', pos=(40, 34))t4 = wx.TextCtrl(dialog1, -1, ’’, pos=(130, 30), size=(130, -1))btn_confirm = wx.Button(dialog1, 1, '確認(rèn)', pos=(30, 150))btn_close = wx.Button(dialog1, 2, '取消', pos=(250, 150))btn_close.Bind(wx.EVT_BUTTON, self.OnClose1, btn_close)btn_confirm.Bind(wx.EVT_BUTTON, self.deleteById, btn_confirm)dialog1.ShowModal() def DoCustomLog(self, event):if not Folderpath2 == '': number = t1.GetValue() days = t2.GetValue() flag = self.findById(number, days) print('查詢的天數(shù)是:', days) if flag:row = len(find_id)path = Folderpath2 + ’/’ + find_name[0] + ’.csv’f = open(path, ’w’, newline=’’, encoding=’utf-8’)csv_writer = csv.writer(f)csv_writer.writerow(['編號', '姓名', '打卡時間', '是否遲到'])for index in range(row): s1 = str(find_datetime[index]).replace(’[’, ’’).replace(’]’, ’’) csv_writer.writerow([str(find_id[index]), str(find_name[index]), s1, str(find_late[index])])f.close()success = wx.MessageDialog(None, ’日志保存成功,請注意查看’, ’info’, wx.OK)success.ShowModal() else:warn = wx.MessageDialog(None, ’輸入id不正確,請重新輸入’, ’info’, wx.OK)warn.ShowModal() dialog.Destroy()else: win32api.MessageBox(0, '請輸入文件導(dǎo)出位置', '提醒', win32con.MB_ICONWARNING)pass def deleteById(self, event):global delete_namedelete_name = []id = t4.GetValue()print('刪除員工的id為:', id)conn = sqlite3.connect('inspurer.db') # 建立數(shù)據(jù)庫連接cur = conn.cursor() # 得到游標(biāo)對象sql = ’select name from worker_info where id=’ + idsql1 = ’delete from worker_info where id=’ + idsql2 = ’delete from logcat where id=’ + idlength = len(cur.execute(sql).fetchall())if length <= 0: win32api.MessageBox(0, '沒有查詢到該員工,請重新輸入ID', '提醒', win32con.MB_ICONWARNING) return Falseelse: origin = cur.execute(sql).fetchall() for row in origin:delete_name.append(row[0])name = delete_name[0]print('名字是', name) if self.OnYes(event):cur.execute(sql1)cur.execute(sql2)conn.commit()dir = PATH_FACE + namefor file in os.listdir(dir): os.remove(dir + '/' + file) print('已刪除已錄入人臉的圖片', dir + '/' + file)os.rmdir(PATH_FACE + name)print('已刪除已錄入人臉的姓名文件夾', dir)dialog1.Destroy()self.initData()return True def findById(self, id, day):global find_id, find_name, find_datetime, find_latefind_id = []find_name = []find_datetime = []find_late = []DayAgo = (datetime.datetime.now() - datetime.timedelta(days=int(day)))# 轉(zhuǎn)換為其他字符串格式:day_before = DayAgo.strftime('%Y-%m-%d')today = datetime.date.today()first = today.replace(day=1)last_month = first - datetime.timedelta(days=1)print(last_month.strftime('%Y-%m'))print(last_month)conn = sqlite3.connect('inspurer.db') # 建立數(shù)據(jù)庫連接cur = conn.cursor() # 得到游標(biāo)對象sql = ’select id ,name,datetime,late from logcat where id=’ + idif day == ’30’: str = '’' sql1 = ’select id ,name,datetime,late from logcat where id=’ + id + ’ ’ + ’and datetime like ’ + str + ’%’ + last_month.strftime('%Y-%m') + ’%’ + strelse: sql1 = ’select id ,name,datetime,late from logcat where id=’ + id + ’ ’ + ’and datetime>=’ + day_beforelength = len(cur.execute(sql).fetchall())if length <= 0: return Falseelse: cur.execute(sql1) origin = cur.fetchall() for row in origin:find_id.append(row[0])find_name.append(row[1])find_datetime.append(row[2])find_late.append(row[3]) return Truepass def save_route1(self, event):global Folderpath1root = tk.Tk()root.withdraw()Folderpath1 = filedialog.askdirectory() # 獲得選擇好的文件夾pass def save_route2(self, event):global Folderpath2root = tk.Tk()root.withdraw()Folderpath2 = filedialog.askdirectory() # 獲得選擇好的文件夾pass def register_cap(self, event):# 創(chuàng)建 cv2 攝像頭對象self.cap = cv2.VideoCapture(0)# cap.set(propId, value)# 設(shè)置視頻參數(shù),propId設(shè)置的視頻參數(shù),value設(shè)置的參數(shù)值# self.cap.set(3, 600)# self.cap.set(4,600)# cap是否初始化成功while self.cap.isOpened(): # cap.read() # 返回兩個值: # 一個布爾值true/false,用來判斷讀取視頻是否成功/是否到視頻末尾 # 圖像對象,圖像的三維矩陣 flag, im_rd = self.cap.read() # 每幀數(shù)據(jù)延時1ms,延時為0讀取的是靜態(tài)幀 kk = cv2.waitKey(1) # 人臉數(shù) dets dets = detector(im_rd, 1) # 檢測到人臉 if len(dets) != 0:biggest_face = dets[0]# 取占比最大的臉maxArea = 0for det in dets: w = det.right() - det.left() h = det.top() - det.bottom() if w * h > maxArea:biggest_face = detmaxArea = w * h# 繪制矩形框cv2.rectangle(im_rd, tuple([biggest_face.left(), biggest_face.top()]), tuple([biggest_face.right(), biggest_face.bottom()]), (255, 0, 0), 2)img_height, img_width = im_rd.shape[:2]image1 = cv2.cvtColor(im_rd, cv2.COLOR_BGR2RGB)pic = wx.Bitmap.FromBuffer(img_width, img_height, image1)# 顯示圖片在panel上self.bmp.SetBitmap(pic)# 獲取當(dāng)前捕獲到的圖像的所有人臉的特征,存儲到 features_cap_arrshape = predictor(im_rd, biggest_face)features_cap = facerec.compute_face_descriptor(im_rd, shape)# 對于某張人臉,遍歷所有存儲的人臉特征for i, knew_face_feature in enumerate(self.knew_face_feature): # 將某張人臉與存儲的所有人臉數(shù)據(jù)進(jìn)行比對 compare = return_euclidean_distance(features_cap, knew_face_feature) if compare == 'same': # 找到了相似臉self.infoText.AppendText(self.getDateAndTime() + '工號:' + str(self.knew_id[i]) + ' 姓名:' + self.knew_name[i] + ' 的人臉數(shù)據(jù)已存在rn')self.flag_registed = Trueself.OnFinishRegister()_thread.exit()face_height = biggest_face.bottom() - biggest_face.top()face_width = biggest_face.right() - biggest_face.left()im_blank = np.zeros((face_height, face_width, 3), np.uint8)try: for ii in range(face_height):for jj in range(face_width): im_blank[ii][jj] = im_rd[biggest_face.top() + ii][biggest_face.left() + jj] if len(self.name) > 0:cv2.imencode(’.jpg’, im_blank)[1].tofile( PATH_FACE + self.name + '/img_face_' + str(self.pic_num) + '.jpg') # 正確方法self.pic_num += 1print('寫入本地:', str(PATH_FACE + self.name) + '/img_face_' + str(self.pic_num) + '.jpg')self.infoText.AppendText( self.getDateAndTime() + '圖片:' + str(PATH_FACE + self.name) + '/img_face_' + str(self.pic_num) + '.jpg保存成功rn')except: print('保存照片異常,請對準(zhǔn)攝像頭')if self.new_register.IsEnabled(): _thread.exit()if self.pic_num == 30: self.OnFinishRegister() _thread.exit() def OnNewRegisterClicked(self, event):self.new_register.Enable(False)self.finish_register.Enable(True)self.loadDataBase(1)while self.id == ID_WORKER_UNAVIABLE: self.id = wx.GetNumberFromUser(message='請輸入您的工號(-1不可用)', prompt='工號', caption='溫馨提示', value=ID_WORKER_UNAVIABLE, parent=self.bmp, max=100000000, min=ID_WORKER_UNAVIABLE) for knew_id in self.knew_id:if knew_id == self.id: self.id = ID_WORKER_UNAVIABLE wx.MessageBox(message='工號已存在,請重新輸入', caption='警告')while self.name == ’’: self.name = wx.GetTextFromUser(message='請輸入您的的姓名,用于創(chuàng)建姓名文件夾', caption='溫馨提示', default_value='', parent=self.bmp) # 監(jiān)測是否重名 for exsit_name in (os.listdir(PATH_FACE)):if self.name == exsit_name: wx.MessageBox(message='姓名文件夾已存在,請重新輸入', caption='警告') self.name = ’’ breakos.makedirs(PATH_FACE + self.name)_thread.start_new_thread(self.register_cap, (event,))pass def OnFinishRegister(self):self.new_register.Enable(True)self.finish_register.Enable(False)self.cap.release()self.bmp.SetBitmap(wx.Bitmap(self.pic_index))if self.flag_registed == True: dir = PATH_FACE + self.name for file in os.listdir(dir):os.remove(dir + '/' + file)print('已刪除已錄入人臉的圖片', dir + '/' + file) os.rmdir(PATH_FACE + self.name) print('已刪除已錄入人臉的姓名文件夾', dir) self.initData() returnif self.pic_num > 0: pics = os.listdir(PATH_FACE + self.name) feature_list = [] feature_average = [] for i in range(len(pics)):pic_path = PATH_FACE + self.name + '/' + pics[i]print('正在讀的人臉圖像:', pic_path)img = iio.imread(pic_path)img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)dets = detector(img_gray, 1)if len(dets) != 0: shape = predictor(img_gray, dets[0]) face_descriptor = facerec.compute_face_descriptor(img_gray, shape) feature_list.append(face_descriptor)else: face_descriptor = 0 print('未在照片中識別到人臉') if len(feature_list) > 0:for j in range(128): # 防止越界 feature_average.append(0) for i in range(len(feature_list)):feature_average[j] += feature_list[i][j] feature_average[j] = (feature_average[j]) / len(feature_list)self.insertARow([self.id, self.name, feature_average], 1)self.infoText.AppendText(self.getDateAndTime() + '工號:' + str(self.id) + ' 姓名:' + self.name + ' 的人臉數(shù)據(jù)已成功存入rn') passelse: os.rmdir(PATH_FACE + self.name) print('已刪除空文件夾', PATH_FACE + self.name)self.initData() def OnFinishRegisterClicked(self, event):self.OnFinishRegister()pass def punchcard_cap(self, event):# 調(diào)用設(shè)置上班時間的函數(shù),根據(jù)當(dāng)前時間和上班時間判斷是否遲到self.cap = cv2.VideoCapture(0)# cap.set(propId, value)# 設(shè)置視頻參數(shù),propId設(shè)置的視頻參數(shù),value設(shè)置的參數(shù)值# self.cap.set(3, 600)# self.cap.set(4,600)# cap是否初始化成功self.loadDataBase(5)print('長度是')print(len(working_times))if len(working_times) == 0: win32api.MessageBox(0, '您未設(shè)置上班時間,請先設(shè)置上班時間后再設(shè)置下班時間', '提醒', win32con.MB_ICONWARNING) self.start_punchcard.Enable(True) self.end_puncard.Enable(False)else: working = working_times[0] print('-----------') print(working) offworking = offworking_times[0] print('-----------') print(offworking) while self.cap.isOpened():# cap.read()# 返回兩個值:# 一個布爾值true/false,用來判斷讀取視頻是否成功/是否到視頻末尾# 圖像對象,圖像的三維矩陣flag, im_rd = self.cap.read()# 每幀數(shù)據(jù)延時1ms,延時為0讀取的是靜態(tài)幀kk = cv2.waitKey(1)# 人臉數(shù) detsdets = detector(im_rd, 1)# 檢測到人臉if len(dets) != 0: biggest_face = dets[0] # 取占比最大的臉 maxArea = 0 for det in dets:w = det.right() - det.left()h = det.top() - det.bottom()if w * h > maxArea: biggest_face = det maxArea = w * h # 繪制矩形框 cv2.rectangle(im_rd, tuple([biggest_face.left(), biggest_face.top()]), tuple([biggest_face.right(), biggest_face.bottom()]), (255, 0, 255), 2) img_height, img_width = im_rd.shape[:2] image1 = cv2.cvtColor(im_rd, cv2.COLOR_BGR2RGB) pic = wx.Bitmap.FromBuffer(img_width, img_height, image1) # 顯示圖片在panel上 self.bmp.SetBitmap(pic) # 獲取當(dāng)前捕獲到的圖像的所有人臉的特征,存儲到 features_cap_arr shape = predictor(im_rd, biggest_face) features_cap = facerec.compute_face_descriptor(im_rd, shape) # 對于某張人臉,遍歷所有存儲的人臉特征 for i, knew_face_feature in enumerate(self.knew_face_feature):# 將某張人臉與存儲的所有人臉數(shù)據(jù)進(jìn)行比對compare = return_euclidean_distance(features_cap, knew_face_feature)if compare == 'same': # 找到了相似臉 print('same') flag = 0 nowdt = self.getDateAndTime() for j, logcat_name in enumerate(self.logcat_name):if logcat_name == self.knew_name[i] and nowdt[0:nowdt.index(' ')] == self.logcat_datetime[ j][0:self.logcat_datetime[ j].index(' ')]: self.infoText.AppendText(nowdt + '工號:' + str(self.knew_id[i]) + ' 姓名:' + self.knew_name[i] + ' 簽到失敗,重復(fù)簽到rn') speak_info(self.knew_name[i] + ' 簽到失敗,重復(fù)簽到 ') flag = 1 break if flag == 1:break if nowdt[nowdt.index(' ') + 1:-1] <= working:self.infoText.AppendText(nowdt + '工號:' + str(self.knew_id[i]) + ' 姓名:' + self.knew_name[i] + ' 成功簽到,且未遲到rn')speak_info(self.knew_name[i] + ' 成功簽到 ')self.insertARow([self.knew_id[i], self.knew_name[i], nowdt, '否'], 2) elif offworking >= nowdt[nowdt.index(' ') + 1:-1] >= working:self.infoText.AppendText(nowdt + '工號:' + str(self.knew_id[i]) + ' 姓名:' + self.knew_name[i] + ' 成功簽到,但遲到了rn')speak_info(self.knew_name[i] + ' 成功簽到,但遲到了 ')self.insertARow([self.knew_id[i], self.knew_name[i], nowdt, '是'], 2) elif nowdt[nowdt.index(' ') + 1:-1] > offworking:self.infoText.AppendText(nowdt + '工號:' + str(self.knew_id[i]) + ' 姓名:' + self.knew_name[i] + ' 簽到失敗,超過簽到時間rn')speak_info(self.knew_name[i] + ' 簽到失敗,超過下班時間 ') self.loadDataBase(2) break if self.start_punchcard.IsEnabled():self.bmp.SetBitmap(wx.Bitmap(self.pic_index))_thread.exit() def OnStartPunchCardClicked(self, event):self.start_punchcard.Enable(False)self.end_puncard.Enable(True)self.loadDataBase(2)threading.Thread(target=self.punchcard_cap, args=(event,)).start()pass def OnEndPunchCardClicked(self, event):self.start_punchcard.Enable(True)self.end_puncard.Enable(False)pass def initInfoText(self):# 少了這兩句infoText背景顏色設(shè)置失敗,莫名奇怪resultText = wx.StaticText(parent=self, pos=(10, 20), size=(90, 60))resultText.SetBackgroundColour(wx.GREEN)# resultText.SetBackgroundColour((12,12,12))self.info = 'rn' + self.getDateAndTime() + '程序初始化成功rn'# 第二個參數(shù)水平混動條self.infoText = wx.TextCtrl(parent=self, size=(320, 500), style=(wx.TE_MULTILINE | wx.HSCROLL | wx.TE_READONLY))# 前景色,也就是字體顏色self.infoText.SetForegroundColour(’Black’)self.infoText.SetLabel(self.info)font = wx.Font()font.SetPointSize(12)font.SetWeight(wx.BOLD)font.SetUnderlined(True)self.infoText.SetFont(font)self.infoText.SetBackgroundColour(’WHITE’)pass def initGallery(self):self.pic_index = wx.Image('drawable/index.png', wx.BITMAP_TYPE_ANY).Scale(600, 500)self.bmp = wx.StaticBitmap(parent=self, pos=(320, 0), bitmap=wx.Bitmap(self.pic_index))pass def getDateAndTime(self):dateandtime = strftime('%Y-%m-%d %H:%M:%S', localtime())return '[' + dateandtime + ']' # 數(shù)據(jù)庫部分 # 初始化數(shù)據(jù)庫 def initDatabase(self):conn = sqlite3.connect('inspurer.db') # 建立數(shù)據(jù)庫連接cur = conn.cursor() # 得到游標(biāo)對象cur.execute(’’’create table if not exists worker_info(name text not null,id int not null primary key,face_feature array not null)’’’)cur.execute(’’’create table if not exists logcat (datetime text not null, id int not null, name text not null, late text not null)’’’)cur.execute(’’’create table if not exists time (id intconstraint table_name_pkprimary key, working_time time not null, offwork_time time not null)’’’)cur.close()conn.commit()conn.close() def adapt_array(self, arr):out = io.BytesIO()np.save(out, arr)out.seek(0)dataa = out.read()# 壓縮數(shù)據(jù)流return sqlite3.Binary(zlib.compress(dataa, zlib.Z_BEST_COMPRESSION)) def convert_array(self, text):out = io.BytesIO(text)out.seek(0)dataa = out.read()# 解壓縮數(shù)據(jù)流out = io.BytesIO(zlib.decompress(dataa))return np.load(out) def insertARow(self, Row, type):conn = sqlite3.connect('inspurer.db') # 建立數(shù)據(jù)庫連接cur = conn.cursor() # 得到游標(biāo)對象if type == 1: cur.execute('insert into worker_info (id,name,face_feature) values(?,?,?)',(Row[0], Row[1], self.adapt_array(Row[2]))) print('寫人臉數(shù)據(jù)成功')if type == 2: cur.execute('insert into logcat (id,name,datetime,late) values(?,?,?,?)',(Row[0], Row[1], Row[2], Row[3])) print('寫日志成功') passcur.close()conn.commit()conn.close()pass def loadDataBase(self, type):nowday = self.getDateAndTime()day = nowday[0:nowday.index(' ')]print(day)global logcat_id, logcat_name, logcat_datetime, logcat_late, working_times, offworking_timesconn = sqlite3.connect('inspurer.db') # 建立數(shù)據(jù)庫連接cur = conn.cursor() # 得到游標(biāo)對象if type == 1: self.knew_id = [] self.knew_name = [] self.knew_face_feature = [] cur.execute(’select id,name,face_feature from worker_info’) origin = cur.fetchall() for row in origin:print(row[0])self.knew_id.append(row[0])print(row[1])self.knew_name.append(row[1])print(self.convert_array(row[2]))self.knew_face_feature.append(self.convert_array(row[2]))if type == 2: self.logcat_id = [] self.logcat_name = [] self.logcat_datetime = [] self.logcat_late = [] cur.execute(’select id,name,datetime,late from logcat’) origin = cur.fetchall() for row in origin:print(row[0])self.logcat_id.append(row[0])print(row[1])self.logcat_name.append(row[1])print(row[2])self.logcat_datetime.append(row[2])print(row[3])self.logcat_late.append(row[3])if type == 3: logcat_id = [] logcat_name = [] logcat_datetime = [] logcat_late = [] s = '’' sql = ’select w.id,w.name,l.datetime,l.late from worker_info w left join logcat l on w.id=l.id and l.datetime like’ + ’ ’ + s + day + ’%’ + s + ’ ’ + ’order by datetime desc’ print(sql) cur.execute(sql) origin = cur.fetchall() for row in origin:print(row[0])logcat_id.append(row[0])print(row[1])logcat_name.append(row[1])print(row[2])logcat_datetime.append(row[2])print(row[3])logcat_late.append(row[3])if type == 4: sql = ’select working_time from time’ cur.execute(sql) countResult = (cur.fetchall()) print(countResult) str = '’' if not countResult:sql = ’insert into time (id,working_time,offworking_time) values (1,’ + str + working + str + ’,’ + str + offworking + str + ’)’cur.execute(sql)print(sql)conn.commit()print('插入時間成功') else:str='’'sql = ’update time set working_time=’ + str + working + str + ’,offworking_time=’ + str + offworking + str + ’ where id=1’cur.execute(sql)conn.commit()print(sql)print('更新時間成功')if type==5: sql = ’select working_time,offworking_time from time’ cur.execute(sql) print(sql) origin = cur.fetchall() print(origin) working_times = [] offworking_times = [] for row in origin:print('這是數(shù)據(jù)庫取出的上班時間')print(row[0])working_times.append(row[0])print('這是數(shù)據(jù)庫取出的下班時間')print(row[1])offworking_times.append(row[1])cur.close()conn.commit()conn.close()passapp = wx.App()frame = WAS()frame.Show()app.MainLoop()

以上就是python實現(xiàn)的人臉識別打卡系統(tǒng)的詳細(xì)內(nèi)容,更多關(guān)于python 人臉識別打卡的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Python 編程
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲国产综合在线看不卡| 狠狠色狠狠色综合日日tαg| 中文字幕日本一区| 亚洲精品美女91| 中文字幕中文字幕精品| 日韩av中文字幕一区二区 | а√在线中文在线新版| 红杏一区二区三区| 日韩视频不卡| 日本不卡高清| 麻豆91小视频| 91精品久久久久久久久久不卡| 欧美女激情福利| 亚洲精品系列| 麻豆91精品91久久久的内涵| 日韩和的一区二在线| 国产亚洲一级| 亚洲制服一区| 国产精品天堂蜜av在线播放| 国产福利电影在线播放| 欧美日韩精品一本二本三本| 蜜桃av一区二区在线观看| 青青草国产精品亚洲专区无| 国产一区二区精品久| 国内精品99| 欧美伊人久久| 日韩一区二区三区免费播放| 午夜在线精品| 国产精品对白| 久久在线视频免费观看| 亚洲精品伊人| 日本一二区不卡| 蜜臀av在线播放一区二区三区| 日韩高清中文字幕一区| 日韩电影免费网址| 亚洲久久视频| 伊人久久国产| 亚洲精品免费观看| 日韩成人亚洲| 欧美另类中文字幕| 欧美aa国产视频| 国产伦理一区| 91成人精品视频| 欧美极品中文字幕| 精品1区2区3区4区| 精品国产18久久久久久二百| 石原莉奈在线亚洲二区| 亚洲国产成人二区| 久久亚洲风情| 国产va在线视频| 日韩精品视频在线看| 99久久久久| 久久精品一本| 一区二区三区四区精品视频| 中文av在线全新| 国产日韩欧美中文在线| 尤物在线精品| 婷婷激情一区| 国产精品日韩精品中文字幕| 午夜久久99| 神马午夜在线视频| 国产精品18| 亚洲+小说+欧美+激情+另类| 中文字幕色婷婷在线视频| 久久精品 人人爱| 美国三级日本三级久久99| 亚洲va在线| 国产成人1区| 欧美日韩一区二区三区在线电影| aⅴ色国产欧美| 久久中文字幕av| 欧美www视频在线观看| 欧美另类中文字幕 | 99视频一区| 亚洲天堂久久| 日韩视频网站在线观看| 欧美激情视频一区二区三区免费| 亚欧成人精品| 亚洲精品少妇| 亚洲欧美日本视频在线观看| 午夜av成人| 在线天堂中文资源最新版| 久久香蕉精品香蕉| 国产精品久久久久av蜜臀| 日本a级不卡| 日韩av资源网| 国产亚洲人成a在线v网站| 综合视频一区| 亚久久调教视频| 91麻豆精品激情在线观看最新| 亚洲精品第一| 三级久久三级久久久| 日本伊人午夜精品| 日韩和欧美的一区| 欧美精品中文字幕亚洲专区| 久久精品99久久久| 国产精品mv在线观看| 国产精品久久国产愉拍| 国产精品一站二站| 国产九一精品| 美女av一区| 国产成人久久精品一区二区三区| 精品国产麻豆| 日韩国产一区二区| 亚洲伊人av| 99精品视频在线| 五月激情久久| 国产一区久久| 视频一区视频二区在线观看| 视频一区中文字幕精品| 国产日韩免费| 成人av三级| 欧美日韩免费观看一区=区三区 | 樱桃视频成人在线观看| 亚洲啊v在线| 五月精品视频| 中文字幕视频精品一区二区三区| 日韩激情视频网站| 欧美aaaaaa午夜精品| 日韩88av| 亚洲精品午夜av福利久久蜜桃| 久久国产高清| 日韩高清成人在线| 久久精品二区亚洲w码 | 91九色精品| 亚洲1区在线观看| 麻豆国产精品| 亚洲福利国产| 午夜精品影视国产一区在线麻豆| 欧美日韩调教| 日本免费一区二区三区四区| 最新国产拍偷乱拍精品| 亚久久调教视频| 成人在线免费观看网站| 伊人成人在线视频| 国产精品视频一区二区三区四蜜臂| 激情视频网站在线播放色| 国产视频欧美| 嫩呦国产一区二区三区av| 蜜臀久久99精品久久一区二区| 日本在线视频一区二区| 国产美女高潮在线| 视频一区中文字幕精品| 国产在线观看www| 免费视频久久| 精品一区二区三区的国产在线观看 | 你懂的亚洲视频| 激情综合自拍| 国产日韩中文在线中文字幕 | 国产在线观看www| 日韩av午夜在线观看| 99久久99久久精品国产片果冰| 日韩影片在线观看| 色老板在线视频一区二区| 日本伊人久久| 免费久久久久久久久| 久久av免费| 蜜臀av性久久久久蜜臀aⅴ四虎| 国产精品一区免费在线| 欧美女激情福利| 国产精品久久久久蜜臀| 日韩精品一区二区三区中文在线| 天堂中文在线播放| 日韩国产一二三区| 午夜精品影院| 新版的欧美在线视频| 欧美日韩1区2区3区| 美女少妇全过程你懂的久久| 久久精品国产网站| 日本在线视频一区二区| 欧美日韩免费观看一区=区三区| 久久久久免费| 久久精品99国产国产精| 黄色亚洲在线| 久久久久美女| 裤袜国产欧美精品一区| 国产激情欧美| 欧美一级二级视频| 免费国产亚洲视频| 欧美 日韩 国产一区二区在线视频| 精品日产乱码久久久久久仙踪林| 五月激激激综合网色播| 久久都是精品| 欧美日韩高清| 国产精品字幕| | 三上悠亚国产精品一区二区三区| 国产伦精品一区二区三区视频| 免费在线观看精品| 免费观看久久av| 91精品推荐| 欧美日韩尤物久久| 亚洲性色av| 日韩欧美二区| 久久久久久网| 蜜桃视频在线网站| 色天使综合视频| 久久精品成人| 久久视频一区| 欧洲激情综合|