前言:
人臉識(shí)別技術(shù)已經(jīng)在許多領(lǐng)域得到了廣泛應(yīng)用,例如安防、金融、醫(yī)療等等。人臉識(shí)別可以幫助我們識(shí)別和驗(yàn)證一個(gè)人的身份,這是一項(xiàng)非常重要的任務(wù)。本篇博客將介紹如何使用Python和OpenCV庫(kù)進(jìn)行人臉識(shí)別。我們將學(xué)習(xí)如何使用OpenCV中的人臉檢測(cè)器檢測(cè)圖像中的人臉,如何與一個(gè)人的圖像進(jìn)行比較以檢測(cè)是否屬于該人,以及如何在GUI中顯示識(shí)別結(jié)果。你可以嵌入到你的程序、機(jī)器上?,F(xiàn)在,讓我們開(kāi)始學(xué)習(xí)人臉識(shí)別技術(shù)吧!
如果你已有python環(huán)境和opencv庫(kù)可直接跳轉(zhuǎn)到代碼解讀哦
目錄
前言:
環(huán)境搭建:
安裝Python
安裝pip
安裝OpenCV
配置環(huán)境變量
代碼解讀
程序的大體流程如下:
加載 Haar Cascade 分類器用于人臉檢測(cè)。
打開(kāi)攝像頭并捕獲實(shí)時(shí)圖像。
循環(huán)處理捕獲的圖像:
關(guān)閉攝像頭并銷毀窗口。
代碼解析
與person文件夾中的圖像進(jìn)行比較以檢測(cè)人臉
?cv2AddChineseText方法
?完整代碼
環(huán)境搭建:
安裝Python
首先,你需要下載和安裝Python??梢栽赑ython官方網(wǎng)站上下載最新版本的Python安裝程序:https://www.python.org/downloads/windows/請(qǐng)務(wù)必下載并安裝3.x版本的Python,因?yàn)镺penCV不支持Python 2.x。
安裝pip
pip是Python的包管理器,可以輕松地安裝、升級(jí)和刪除Python軟件包??梢允褂靡韵旅顧z查是否已經(jīng)安裝了pip:
pip --version
?如果pip沒(méi)有安裝,可以在終端中輸入以下命令進(jìn)行安裝:
python -m ensurepip --default-pip
安裝OpenCV
可以使用pip來(lái)安裝OpenCV:
pip install opencv-python
配置環(huán)境變量
為了讓Python能夠找到OpenCV,需要將OpenCV的路徑添加到系統(tǒng)的環(huán)境變量中。
首先,找到OpenCV安裝的路徑,一般在Python的安裝目錄下的Lib\site-packages目錄中。例如,在我的電腦上,OpenCV安裝在以下目錄下:
C:\Users\username\AppData\Local\Programs\Python\Python39\Lib\site-packages\cv2
然后,將這個(gè)路徑添加到系統(tǒng)的環(huán)境變量中。在Windows 10中,可以按以下步驟進(jìn)行操作:
- 在Windows搜索欄中輸入“環(huán)境變量”,并點(diǎn)擊“編輯系統(tǒng)環(huán)境變量”;
- 在“高級(jí)”選項(xiàng)卡下,點(diǎn)擊“環(huán)境變量”按鈕;
- 在“系統(tǒng)變量”下方找到“Path”變量,點(diǎn)擊“編輯”按鈕;
- 在“編輯環(huán)境變量”對(duì)話框中,點(diǎn)擊“新建”按鈕,并將OpenCV的路徑添加進(jìn)去。
- 測(cè)試OpenCV
- 最后,可以測(cè)試一下OpenCV是否已經(jīng)正確安裝??梢栽诮K端中輸入以下代碼:
import cv2
print(cv2.__version__)
如果OpenCV已經(jīng)成功安裝,應(yīng)該會(huì)顯示OpenCV的版本號(hào)。
希望這個(gè)簡(jiǎn)要的教程可以幫助你在Windows上成功安裝和配置OpenCV和Python。
代碼解讀
這是一個(gè)基于 OpenCV 庫(kù)和 tkinter 庫(kù)開(kāi)發(fā)的人臉識(shí)別程序。它可以從攝像頭實(shí)時(shí)獲取視頻,并在視頻中檢測(cè)人臉并顯示其姓名。
程序的大體流程如下:
-
加載 Haar Cascade 分類器用于人臉檢測(cè)。
-
打開(kāi)攝像頭并捕獲實(shí)時(shí)圖像。
-
循環(huán)處理捕獲的圖像:
- 將圖像轉(zhuǎn)換為灰度圖像。
- 使用 Haar Cascade 分類器檢測(cè)人臉。
- 如果檢測(cè)到人臉,則查找是否存在與
person
文件夾中的某個(gè)人匹配的圖像。 - 如果找到匹配的人臉,則在圖像中框出人臉并顯示姓名。
- 如果未找到匹配的人臉,則在圖像中框出人臉但不顯示姓名。
- 將圖像轉(zhuǎn)換為 PIL Image 格式以在 GUI 中顯示。
- 更新標(biāo)簽以顯示圖像。
- 處理 GUI 事件以避免程序掛起。
-
關(guān)閉攝像頭并銷毀窗口。
代碼中的函數(shù) cv2AddChineseText
用于在圖像上添加中文文本。函數(shù) cv2AddChineseText
接受四個(gè)參數(shù):
-
img
:要添加文本的圖像。 -
text
:要添加的文本。 -
position
:文本的位置。 -
textColor
:文本顏色,默認(rèn)為綠色。 -
textSize
:文本大小,默認(rèn)為 30。
代碼中的 person_images
列表用于存儲(chǔ) person
文件夾中的人臉圖像。person_names
列表用于存儲(chǔ)每個(gè)人臉圖像對(duì)應(yīng)的姓名。在處理捕獲的圖像時(shí),程序?qū)z查每個(gè)人臉圖像是否匹配,并在圖像中顯示姓名。
代碼解析
該程序主要通過(guò)計(jì)算機(jī)視覺(jué)技術(shù)實(shí)現(xiàn)人臉識(shí)別。首先,程序使用OpenCV庫(kù)中的Haar Cascade分類器來(lái)檢測(cè)輸入圖像中的人臉。然后,它會(huì)將人臉與事先保存在“person”文件夾中的圖像進(jìn)行比較,以確定是否存在匹配的人臉。如果存在匹配的人臉,則程序會(huì)在圖像中框出人臉并顯示相應(yīng)的姓名。如果不存在匹配的人臉,則程序僅在圖像中框出人臉。
下面是程序的主要部分的解釋:
# 加載Haar Cascade分類器
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# 打開(kāi)攝像頭并捕獲實(shí)時(shí)圖像
cap = cv2.VideoCapture(0)
# 讀取person文件夾中的圖像和姓名
person_images = []
person_names = []
for filename in os.listdir('person'):
if filename.endswith('.jpg'):
# 使用utf-8編碼打開(kāi)文件
with open(os.path.join('person', filename), 'rb') as f:
person_images.append(cv2.imdecode(np.frombuffer(f.read(), np.uint8), cv2.IMREAD_COLOR))
person_names.append(os.path.splitext(filename)[0])
while True:
ret, frame = cap.read()
if not ret:
break
# 轉(zhuǎn)換圖像格式以進(jìn)行人臉檢測(cè)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 使用Haar Cascade分類器檢測(cè)人臉
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
# 在圖像中框出檢測(cè)到的人臉
for (x, y, w, h) in faces:
# 檢查人臉是否屬于person文件夾中的某個(gè)人
found_person = False
for i in range(len(person_images)):
person_image = person_images[i]
person_name = person_names[i]
# 將person圖像轉(zhuǎn)換為灰度圖像以進(jìn)行比較
person_gray = cv2.cvtColor(person_image, cv2.COLOR_BGR2GRAY)
# 檢查是否存在與person圖像相匹配的人臉
match = cv2.matchTemplate(gray[y:y + h, x:x + w], person_gray, cv2.TM_CCOEFF_NORMED)
if match.max() > 0.8:
# 如果找到匹配的人臉,則將其標(biāo)記為“found_person”,并繪制人臉框
found_person = True
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 在人臉框上方寫出人名
cv2.putText(frame, person_name, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
break
if not found_person:
# 如果沒(méi)有找到匹配的人臉,則將其標(biāo)記為“unknown”,并繪制人臉框
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.putText(frame, 'unknown', (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)
與person文件夾中的圖像進(jìn)行比較以檢測(cè)人臉
我們已經(jīng)成功地檢測(cè)出了人臉,并將其框出來(lái)?,F(xiàn)在我們將探討如何與person文件夾中的圖像進(jìn)行比較以檢測(cè)人臉。
首先,我們需要讀取person文件夾中的圖像和姓名。我們可以使用os模塊中的listdir函數(shù)列出person文件夾中的所有文件名,然后使用cv2.imread函數(shù)讀取每個(gè)圖像。
import os
person_folder = 'person'
person_images = []
person_names = []
# 獲取person文件夾中的所有文件名
for filename in os.listdir(person_folder):
? ? # 如果文件名以'.jpg'或'.png'結(jié)尾,則讀取該圖像并將其添加到person_images列表中
? ? if filename.endswith('.jpg') or filename.endswith('.png'):
? ? ? ? image = cv2.imread(os.path.join(person_folder, filename))
? ? ? ? person_images.append(image)
? ? ? ? # 使用文件名中的數(shù)字作為該人員的姓名
? ? ? ? person_names.append(filename.split('.')[0])
接下來(lái),我們需要將每個(gè)person圖像轉(zhuǎn)換為灰度圖像以進(jìn)行比較。我們可以使用cv2.cvtColor函數(shù)將BGR圖像轉(zhuǎn)換為灰度圖像。
for i in range(len(person_images)):
person_image = person_images[i]
# 將person圖像轉(zhuǎn)換為灰度圖像以進(jìn)行比較
person_gray = cv2.cvtColor(person_image, cv2.COLOR_BGR2GRAY)
現(xiàn)在,我們可以使用matchTemplate函數(shù)將當(dāng)前人臉與person圖像進(jìn)行比較,以確定當(dāng)前人臉是否屬于person文件夾中的某個(gè)人。matchTemplate函數(shù)可以將當(dāng)前人臉的灰度圖像與person圖像的灰度圖像進(jìn)行比較,并返回一個(gè)相似度矩陣。我們可以使用max方法獲取相似度矩陣中的最大值,并將其與一個(gè)預(yù)設(shè)的閾值(例如0.8)進(jìn)行比較,以確定當(dāng)前人臉是否與person圖像匹配。?
for (x, y, w, h) in faces:
# 檢查人臉是否屬于person文件夾中的某個(gè)人
found_person = False
for i in range(len(person_images)):
person_image = person_images[i]
person_name = person_names[i]
# 將person圖像轉(zhuǎn)換為灰度圖像以進(jìn)行比較
person_gray = cv2.cvtColor(person_image, cv2.COLOR_BGR2GRAY)
# 檢查是否存在與person圖像相匹配的人臉
match = cv2.matchTemplate(gray[y:y + h, x:x + w], person_gray, cv2.TM_CCOEFF_NORMED)
if match.max() > 0.8:
found_person = True
# 將人物名稱繪制在檢測(cè)到的人臉上
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame, person_name, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
break
# 如果找不到相應(yīng)的人物,則將“Unknown”繪制在檢測(cè)到的人臉上
if not found_person:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.putText(frame, 'Unknown', (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
# 將幀顯示在窗口中
cv2.imshow('Face Recognition', frame)
# 等待退出鍵
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 釋放資源
cap.release()
cv2.destroyAllWindows()
這段代碼將每個(gè)檢測(cè)到的人臉與存儲(chǔ)在“person”文件夾中的圖像進(jìn)行比較。如果存在與任何一個(gè)圖像匹配的人臉,則在該人臉上方框和標(biāo)注該人的名稱。否則,將該人臉框在紅色方框內(nèi),并標(biāo)注“Unknown”。(完整代碼中沒(méi)有加入這行,如果需要可以加上)
最后,它將幀顯示在GUI窗口中,并等待退出鍵按下后釋放資源并關(guān)閉窗口。
?cv2AddChineseText方法
在原生的cv2.putText()方法里并不支持中文只能顯示英文,在網(wǎng)上查閱了很多方法都不奏效于是我決定重構(gòu)這個(gè)方法:
def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):
if (isinstance(img, np.ndarray)): # 判斷是否OpenCV圖片類型
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 創(chuàng)建一個(gè)可以在給定圖像上繪圖的對(duì)象
draw = ImageDraw.Draw(img)
# 字體的格式
fontStyle = ImageFont.truetype(
"simsun.ttc", textSize, encoding="utf-8")
# 繪制文本
draw.text(position, text, textColor, font=fontStyle)
# 轉(zhuǎn)換回OpenCV格式
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
?完整代碼
import cv2
import os
import tkinter as tk
from PIL import Image, ImageTk,ImageDraw
import numpy as np
from PIL import ImageFont
def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):
if (isinstance(img, np.ndarray)): # 判斷是否OpenCV圖片類型
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 創(chuàng)建一個(gè)可以在給定圖像上繪圖的對(duì)象
draw = ImageDraw.Draw(img)
# 字體的格式
fontStyle = ImageFont.truetype(
"simsun.ttc", textSize, encoding="utf-8")
# 繪制文本
draw.text(position, text, textColor, font=fontStyle)
# 轉(zhuǎn)換回OpenCV格式
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
# 加載自定義字體
font = ImageFont.truetype(r"C:\Users\ge\Desktop\test1\Cuesor\msyh.ttc", size=30)
# 加載Haar Cascade分類器
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# 創(chuàng)建GUI窗口
root = tk.Tk()
root.geometry('640x480')
root.title('人臉識(shí)別')
# 創(chuàng)建標(biāo)簽用于顯示圖像
image_label = tk.Label(root)
image_label.pack()
# 打開(kāi)攝像頭并捕獲實(shí)時(shí)圖像
cap = cv2.VideoCapture(0)
# 創(chuàng)建 PhotoImage 對(duì)象
photo = None
# 讀取person文件夾中的圖像和姓名
person_images = []
person_names = []
for filename in os.listdir('person'):
if filename.endswith('.jpg'):
# 使用utf-8編碼打開(kāi)文件
with open(os.path.join('person', filename), 'rb') as f:
person_images.append(cv2.imdecode(np.frombuffer(f.read(), np.uint8), cv2.IMREAD_COLOR))
person_names.append(os.path.splitext(filename)[0])
# 循環(huán)處理攝像頭捕獲的圖像
while True:
ret, frame = cap.read()
if not ret:
break
# 轉(zhuǎn)換圖像格式以進(jìn)行人臉檢測(cè)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 使用Haar Cascade分類器檢測(cè)人臉
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
# 在圖像中框出檢測(cè)到的人臉
for (x, y, w, h) in faces:
# 檢查人臉是否屬于person文件夾中的某個(gè)人
found_person = False
for i in range(len(person_images)):
person_image = person_images[i]
person_name = person_names[i]
# 將person圖像轉(zhuǎn)換為灰度圖像以進(jìn)行比較
person_gray = cv2.cvtColor(person_image, cv2.COLOR_BGR2GRAY)
# 檢查是否存在與person圖像相匹配的人臉
match = cv2.matchTemplate(gray[y:y + h, x:x + w], person_gray, cv2.TM_CCOEFF_NORMED)
if match.max() > 0.8:
print(person_name)
found_person = True
# 在圖像中框出人臉并顯示姓名
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 255), 2)
# 在圖像中框出人臉并顯示姓名
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 255), 2)
frame = cv2AddChineseText(frame, person_name, (x + (w/2)-10, y - 30), (0, 255, 255), 30)
break
# 如果沒(méi)有找到匹配的人臉,則在圖像中框出人臉但不顯示姓名
if not found_person:
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 將圖像轉(zhuǎn)換為PIL Image格式以在GUI中顯示
image = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
photo = ImageTk.PhotoImage(image)
# 更新標(biāo)簽以顯示圖像
image_label.configure(image=photo)
image_label.image = photo
# 處理GUI事件以避免程序掛起
root.update()
#關(guān)閉攝像頭并銷毀窗口
cap.release()
cv2.destroyAllWindows()
人臉識(shí)別技術(shù)在現(xiàn)代生活中有著廣泛的應(yīng)用,例如人臉解鎖手機(jī)、人臉識(shí)別支付、安防領(lǐng)域等。但是,人臉識(shí)別技術(shù)還存在一些局限性和改進(jìn)的空間。
首先,人臉識(shí)別技術(shù)的準(zhǔn)確性受到許多因素的影響,例如光照、姿勢(shì)、表情、遮擋等。為了提高人臉識(shí)別的準(zhǔn)確性,可以采用更先進(jìn)的算法,例如基于深度學(xué)習(xí)的人臉識(shí)別算法。此外,還可以通過(guò)采用更好的硬件設(shè)備來(lái)提高圖像采集的質(zhì)量。
其次,當(dāng)前的人臉識(shí)別技術(shù)主要針對(duì)單個(gè)人臉進(jìn)行識(shí)別,對(duì)于多個(gè)人臉的情況處理較為困難。為了解決這個(gè)問(wèn)題,可以探索如何將多個(gè)人臉的特征進(jìn)行有效地提取和匹配。
最后,人臉識(shí)別技術(shù)還涉及到隱私保護(hù)等倫理問(wèn)題。在應(yīng)用人臉識(shí)別技術(shù)時(shí),需要注意隱私保護(hù)的問(wèn)題,避免對(duì)個(gè)人隱私造成侵害。
總的來(lái)說(shuō),人臉識(shí)別技術(shù)在未來(lái)還有很大的發(fā)展空間,隨著科技的不斷進(jìn)步,相信人臉識(shí)別技術(shù)的應(yīng)用將更加廣泛,也將更加普及化和便利化。
人臉識(shí)別技術(shù)正在廣泛應(yīng)用于各個(gè)領(lǐng)域,例如安全監(jiān)控、人臉支付、人臉解鎖等等。本文介紹的人臉識(shí)別應(yīng)用程序只是冰山一角,隨著技術(shù)的不斷發(fā)展,我們可以期待更加高效、準(zhǔn)確的人臉識(shí)別應(yīng)用程序的出現(xiàn)。如果您對(duì)人臉識(shí)別技術(shù)感興趣,不妨關(guān)注相關(guān)的技術(shù)發(fā)展和應(yīng)用案例,為您的職業(yè)生涯增添一份技術(shù)的底氣。感謝閱讀本文,如果您覺(jué)得有用,請(qǐng)點(diǎn)贊、收藏和關(guān)注,謝謝啦??!
過(guò)幾天我會(huì)在此基礎(chǔ)上加上錄入人臉信息的功能,感興趣的小伙伴不要錯(cuò)過(guò)哦。
再次感謝不離不棄的粉絲,之后仍會(huì)不定期更新哦~~文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-412928.html
?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-412928.html
到了這里,關(guān)于python基于opencv和tkinter實(shí)現(xiàn)人臉識(shí)別【內(nèi)附完整代碼】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!