目錄
前言
安裝第三方庫
第一步:采集人臉圖像
(1)修改姓名學(xué)號(hào)
(2)運(yùn)行capture_face.py?
(3)采集人臉圖像?
(4)查看采集到的人臉圖像
第二步:訓(xùn)練模型
第三步:識(shí)別簽到
(1)建立簽到表
(2)運(yùn)行sign_in.py,進(jìn)行簽到
(3)查看簽到結(jié)果
第四步:設(shè)計(jì)GUI
完整項(xiàng)目的百度網(wǎng)盤鏈接:https://pan.baidu.com/s/1P1UzTyNdcHxfJyFxl-MV-Q?pwd=ni7A,提取碼:ni7A
前言
? ? ? ?當(dāng)今社會(huì),科學(xué)技術(shù)呈現(xiàn)著井噴式的發(fā)展情況,新理論的不斷提出及新技術(shù)的實(shí)時(shí)應(yīng)用,給人們的生活帶來了日新月異的變化。在這些新技術(shù)新應(yīng)用中,物聯(lián)網(wǎng)、人工智能、大數(shù)據(jù)等名詞被人們紛紛提起,產(chǎn)業(yè)領(lǐng)域的智能化產(chǎn)品層出不窮,其中人臉識(shí)別就是一個(gè)典型應(yīng)用。
? ? ? ?本項(xiàng)目構(gòu)建一個(gè)基于OpenCV + Python的人臉識(shí)別上課簽到系統(tǒng)。人臉識(shí)別是指將一個(gè)需要識(shí)別的人臉和人臉庫中的某個(gè)人臉對(duì)應(yīng)起來(類似于指紋識(shí)別),目的是完成識(shí)別功能。人臉檢測(cè)是在一張圖片中把人臉定位出來,完成的是搜尋的功能。
? ? ? ?OpenCV提供了三種人臉識(shí)別方法,分別是LBPH方法、EigenFishfaces方法、Fisherfaces方法。本項(xiàng)目采用LBPH方法,分四步實(shí)現(xiàn)。
?文章來源地址http://www.zghlxwxcb.cn/news/detail-440033.html
安裝第三方庫
首先安裝項(xiàng)目用到的第三方庫:opencv-python、opencv-contrib-python、pillow、tk、xlrd、xlwt、xlutils
安裝方式:在當(dāng)前python解釋器下,pycharm終端運(yùn)行:
pip install 庫名稱
?
第一步:采集人臉圖像
capture_face.py?
通過調(diào)用攝像頭進(jìn)行人臉圖像采集,建立人臉圖像庫
# 第一步:采集人臉圖像
# 1.導(dǎo)入第三方庫
import cv2
import os
import xlrd
# 2.初始化變量
font = cv2.FONT_HERSHEY_SIMPLEX # 定義字體,使用opencv中的FONT_HERSHEY_SIMPLEX字體
classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') # 導(dǎo)入人臉檢測(cè)級(jí)聯(lián)文件。CascadeClassifier是opencv中做人臉檢測(cè)時(shí)的一個(gè)級(jí)聯(lián)分類器,對(duì)輸入的圖片進(jìn)行分類,判斷圖像內(nèi)是否有無人臉
if not os.path.exists('dataset'): # 判斷項(xiàng)目目錄中是否存在dataset文件(dataset中存放采集到的人臉圖像)
os.mkdir('dataset') # 如果沒有就新建立dataset文件夾
count = 0 # 人臉圖像的初始數(shù)量
# 3.輸入學(xué)號(hào)
student_ID = 2021520542
# 4.采集圖像
capture = cv2.VideoCapture(0) # 打開電腦的內(nèi)置攝像頭
while capture.isOpened(): # 當(dāng)攝像頭打開的時(shí)候
kk = cv2.waitKey(1) # 等待鍵盤的輸入,1:表示延時(shí)1ms切換到下一幀圖像
_, frame = capture.read() # 讀取攝像頭內(nèi)容,返回兩個(gè)參數(shù)
gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) # 將讀取到的RGB圖像轉(zhuǎn)換為灰度圖像
faces = classifier.detectMultiScale(gray, 1.3, 5) # 讓classifier判斷人臉,detectMultiScale函數(shù)可以檢測(cè)出圖像中的人臉,其中g(shù)ray為要檢測(cè)的灰度圖像,1.3為每次圖像尺寸減小的比例,5為minNeighbors
if len(faces) != 0: # 如果找到人臉
# 框選人臉
for x, y, w, h in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 255, 0), 2) # 用矩形框框出人臉,xy為左上角的坐標(biāo),w為寬,h為高
cv2.putText(frame, 'please "s" to save a picture ', (200, 450), font, 0.8, (0, 255, 255), 2) # 在人臉圖像上添加文字,參數(shù)依次表示:圖像、要添加的文字、文字的位置、字體、字體大小、顏色、粗細(xì)
if kk == ord('s'): # ord(' ')將字符轉(zhuǎn)化為對(duì)應(yīng)的整數(shù)(ASCII碼)
cv2.imwrite('dataset/caixukun.'+str(student_ID)+'.'+str(count)+'.jpg', gray[y:y+h, x:x+w]) # 保存圖像
count += 1 # 成功框選人臉后,則樣本數(shù)增加
print('共采集了'+str(count)+'張圖片')
cv2.putText(frame, 'please "esc" to quit ', (10, 20), font, 0.8, (0, 255, 255), 2) # 在窗口上添加文字,參數(shù)依次表示:圖像、要添加的文字、文字的位置、字體、字體大小、顏色、粗細(xì)
cv2.imshow("picture from a cammre", frame) # 打開窗口的名稱
if kk == 27:
print('共采集了' + str(student_ID) + '同學(xué)' + str(count) + '張圖片')
break
# 5.退出程序
capture.release() # 釋放變量
cv2.destroyAllWindows() # 檢查有無打開窗口,有的話關(guān)掉
(1)修改姓名學(xué)號(hào)
(2)運(yùn)行capture_face.py?
(3)采集人臉圖像
按住 "s" 鍵保存人臉圖像,按 "esc" 鍵關(guān)閉攝像頭,結(jié)束人臉采集
?(4)查看采集到的人臉圖像
采集到的人臉圖像會(huì)自動(dòng)保存在dataset文件夾中
?
第二步:訓(xùn)練模型
使用OpenCV中LBPH(Local Binary Patterns Histograms,局部二進(jìn)制編碼)算法建立人臉數(shù)據(jù)模型,對(duì)人臉圖像庫中的人臉圖像提取特征信息(LBPH),并訓(xùn)練成模型,存儲(chǔ)起來形成特征庫。
# 第二步:訓(xùn)練模型
# 1. 導(dǎo)入第三方庫
import cv2
import os
from PIL import Image
import numpy as np
# 2. 加載特征提取模型
recognizer_create = cv2.face_LBPHFaceRecognizer.create()
# 3. 數(shù)據(jù)處理
def data_translate(path):
face_data = []
id_data = []
file_list = [os.path.join(path, f) for f in os.listdir(path)]
# print(file_list)
for file in file_list:
PIL_image = Image.open(file).convert("L")
np_image = np.array(PIL_image, 'uint8')
image_id = int(file.split('.')[1])
# print(image_id)
face_data.append(np_image)
id_data.append(image_id)
return face_data, id_data
# 4. 訓(xùn)練模型
Face, ID = data_translate('dataset')
recognizer_create.train(Face, np.array(ID))
print('訓(xùn)練完成')
# 5. 保存模型
recognizer_create.save('face_model.yml')
print('模型已保存')
運(yùn)行train.py,開始訓(xùn)練模型,訓(xùn)練完成后會(huì)生成face_model.yml 文件,face_model.yml 就是訓(xùn)練好的人臉模型
?
第三步:識(shí)別簽到
開啟攝像頭實(shí)時(shí)跟蹤人臉,獲取人臉特征信息,然后將獲取的人臉特征信息與第二步建立的特征庫進(jìn)行比對(duì),將識(shí)別的信息在畫面中呈現(xiàn),并記錄在Excel文檔中。
(1)建立簽到表
打開excel,新建文件,按如下的格式新建一個(gè)簽到表
?注意:
1. 建立簽到表的時(shí)候,一定要將單元格格式設(shè)置成文本,這就是為什么大家老是簽到不成功的原因
2. 保存簽到表時(shí),保存位置為當(dāng)前項(xiàng)目的目錄文件夾,文件命名為 “簽到表” 保存類型一定要選擇.xls格式
?(2)運(yùn)行sign_in.py,進(jìn)行簽到
# 第三步:識(shí)別簽到
# 1. 導(dǎo)入第三方庫
import xlrd, xlwt
from xlutils.copy import copy
from datetime import datetime
import cv2
import time
# 2. 在考勤表簽字
def sign_name(idx, name):
style0 = xlwt.easyxf('font:height 240,bOld on,color_index red', num_format_str='DD:MM HH:MM') # 樣式0
style1 = xlwt.easyxf('font:height 240,bOld on,color_index blue') # 樣式1
workbook = xlrd.open_workbook('簽到表.xls') # 讀取excel文件
newbook = copy(workbook) # 復(fù)制文件
newsheet = newbook.get_sheet(0) # 在源文件上追加
newsheet.write(idx, 4, datetime.now(), style0) # 第idx行,第4列,寫入簽到時(shí)間,樣式為style0(注:代碼中的行列是從0開始的)
newsheet.write(idx, 3, name, style1) # 第idx行,第3列,寫入簽到學(xué)生的名字,樣式為style1((注:代碼中的行列是從0開始的))
# 設(shè)置列寬
newsheet.col(0).width = 256 * 6 # 第0列的列寬為 256 * 6 (256為衡量單位,6表示6個(gè)字符寬度)
newsheet.col(1).width = 256 * 12 # 第1列的列寬為 256 * 12 (256為衡量單位,12表示12個(gè)字符寬度)
newsheet.col(2).width = 256 * 10 # 第2列的列寬為 256 * 10 (256為衡量單位,10表示10個(gè)字符寬度)
newsheet.col(3).width = 256 * 12 # 第3列的列寬為 256 * 12 (256為衡量單位,12表示12個(gè)字符寬度)
newsheet.col(4).width = 256 * 15 # 第4列的列寬為 256 * 15 (256為衡量單位,15表示15個(gè)字符寬度)
newbook.save('簽到表1.xls')
# 3. 導(dǎo)入模塊,初始化變量
classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
recognizer_create = cv2.face.LBPHFaceRecognizer.create()
recognizer_create.read('face_model.yml') # 讀取訓(xùn)練好的模型
flag = 0 # 標(biāo)記次數(shù)
start_time = time.time() # 系統(tǒng)時(shí)間提取
duration = 25 # 持續(xù)時(shí)間
ID = 'Unkonw'
font = cv2.FONT_HERSHEY_SIMPLEX # 定義字體,使用opencv中的FONT_HERSHEY_SIMPLEX字體
# 4. 導(dǎo)入應(yīng)到學(xué)生名單
workbook = xlrd.open_workbook('簽到表.xls') # 導(dǎo)入考勤記錄表
worksheet = workbook.sheet_by_index(0) # 打開工作表
stu_num = worksheet.col_values(1) # 提取工作表第1列,第1列為學(xué)生學(xué)號(hào)
stu_name = worksheet.col_values(2) # 提取工作表第2列,第2列為學(xué)生名字
# 5.識(shí)別簽到
capture = cv2.VideoCapture(0) # 打開攝像頭
while capture.isOpened(): # 當(dāng)打開攝像頭的時(shí)候
kk = cv2.waitKey(1) # 等待鍵盤的輸入
_, frame = capture.read() # 讀取攝像頭內(nèi)容
gray = cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY) # 將讀取到的RGB圖像轉(zhuǎn)換為灰度圖像
faces = classifier.detectMultiScale(gray, 1.3, 5) # 讓classifier判斷人臉,detectMultiScale函數(shù)可以檢測(cè)出圖像中的人臉
if len(faces) != 0: # 如果能找到人臉
# 框選人臉
for x, y, w, h in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2) # 用矩形框框出人臉,xy為左上角的坐標(biāo),w為寬,h為高
roi_face = gray[y:y + h, x:x + w]
label, conf = recognizer_create.predict(roi_face) # 預(yù)測(cè)出的學(xué)號(hào)和可信度
# print(label,conf)
if conf < 60:
index = [list for list, i in enumerate(stu_num) if i == str(label)] # 得到預(yù)測(cè)學(xué)號(hào)在excel表格中所在的行數(shù)(注:index的值是從0開始的,index=3表示在excel表格中的第4行)
# print(index)
if index != []:
name = stu_name[index[0]]
ID = stu_name[index[0]]
flag += 1
else:
ID = 'unknow'
cv2.putText(frame, str(ID), (x, y-10), font, 0.8, (0, 0, 255), 2) # 添加字幕
cv2.putText(frame, 'please "esc" to quit ', (10, 20), font, 0.8, (0, 255, 255), 2) # 在窗口上添加文字,參數(shù)依次表示:圖像、要添加的文字、文字的位置、字體、字體大小、顏色、粗細(xì)
cv2.imshow("picture from a cammre", frame) # 打開窗口的名稱
if flag > 5:
sign_name(index[0], name)
print('簽到成功')
break
if time.time()-start_time > duration: # 如果超時(shí),則簽到失敗
print('簽到失??!')
break
if kk == 27: # 如果退出
print('程序被終止,請(qǐng)重新簽到!')
break
# 6.退出程序
capture.release() # 釋放變量
cv2.destroyAllWindows() # 檢查有無打開窗口,有的話關(guān)掉
(3)查看簽到結(jié)果
簽到成功后項(xiàng)目目錄生成 “簽到表1.xls” 文件,雙擊打開即可查看簽到結(jié)果
?
第四步:設(shè)計(jì)GUI
?
運(yùn)行GUI.py,查看用戶界面
# 第四步:設(shè)計(jì)GUI
# 1. 導(dǎo)入第三方庫
import os
import tkinter as tk
# 2. 創(chuàng)建屏幕窗口
windows = tk.Tk() # 創(chuàng)建windows的窗口
windows.title('<計(jì)算機(jī)視覺>課程案例') # 窗口名稱
windows.geometry('310x500+1000+100') # 窗口大?。ㄗⅲ簒是小寫字母x,不能寫乘號(hào))
# 3. 定義功能函數(shù)
def function1():
os.system('python capture_face.py') # 執(zhí)行python capture_face.py命令
def function2():
os.system('python train.py') # 執(zhí)行python train.py命令
def function3():
os.system('python sign_in.py') # 執(zhí)行python sign_in.py命令
def function4():
os.startfile(os.getcwd()+'/簽到表1.xls') # 打開'簽到表1.xls'文件
def function5():
os.startfile(os.getcwd()+'/基于OpenCV的人臉識(shí)別說明文檔.docx') # 打開說明文檔
def function6():
windows.destroy()
# 4. 創(chuàng)建標(biāo)簽及按鈕
tk.Label(windows, text='人臉識(shí)別上課簽到系統(tǒng)', font=('黑體', 20, 'bold'), fg='white',
bg='maroon', height=2).grid(padx=7, pady=5)
tk.Button(windows,text='采 集 人 臉 圖 像', font=('黑體', 20, 'bold'), fg='white',
bg='#0D47A1', command=function1).grid(padx=7, pady=5, sticky=tk.W+tk.E)
tk.Button(windows,text='訓(xùn) 練 模 型', font=('黑體', 20, 'bold'), fg='white',
bg='#0D47A1', command=function2).grid(padx=7, pady=5, sticky=tk.W+tk.E)
tk.Button(windows,text='識(shí) 別 簽 到', font=('黑體', 20, 'bold'), fg='white',
bg='#0D47A1', command=function3).grid(padx=7, pady=5, sticky=tk.W+tk.E)
tk.Button(windows,text='查 看 簽 到 表', font=('黑體', 20, 'bold'), fg='white',
bg='#0D47A1', command=function4).grid(padx=7, pady=5, sticky=tk.W+tk.E)
tk.Button(windows,text='查看項(xiàng)目說明文檔', font=('黑體', 20, 'bold'), fg='white',
bg='#0D47A1', command=function5).grid(padx=7, pady=5, sticky=tk.W+tk.E)
tk.Button(windows,text=' 退 出 ', font=('黑體', 20, 'bold'), fg='white',
bg='#0D47A1', command=function6).grid(padx=7, pady=5, sticky=tk.W+tk.E)
tk.Button(windows,text='學(xué)號(hào):2021520542 姓名:蔡徐坤', font=('仿宋', 20, 'bold'), fg='black',
bg='white').grid(padx=20, pady=50, sticky=tk.W+tk.E)
# 5. 運(yùn)行
windows.mainloop()
文章來源:http://www.zghlxwxcb.cn/news/detail-440033.html
?
到了這里,關(guān)于基于 OpenCV + Python 的人臉識(shí)別上課簽到系統(tǒng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!