如何使用python的opencv實現(xiàn)人臉識別
簡介:本項目主要使用python語言,主要的模塊庫有os,opencv-python,opencv-contrib-python。項目主要分為三個部分,人臉錄入,訓(xùn)練數(shù)據(jù),實現(xiàn)人臉的識別。本博客包含源代碼,以及各個功能模塊,需求分析的詳細(xì)解釋,當(dāng)然本項目只是簡單的實現(xiàn)人臉識別,可以在此基礎(chǔ)上擴展。
一:項目功能及流程分析
我們項目的主要功能,也就是最終的實現(xiàn)效果是當(dāng)我們打開攝像頭后,在攝像頭里會出現(xiàn)我的人臉頭像,且對我的人臉進行識別,在畫面中能夠框出我的人臉部分并顯示出畫面中人臉的姓名。
項目主要包含以下三個大的模塊:人臉錄入、訓(xùn)練數(shù)據(jù)、人臉識別。
主要用到的模塊:
- os:為操作系統(tǒng)的訪問提供相關(guān)功能的支持(處理文件和目錄)
- opencv-python:計算機視覺和機器學(xué)習(xí)軟件庫
- opencv-contrib-python:opencv 的擴展模塊
1、人臉錄入模塊。
主要目的:通過人臉錄入模塊去得到人臉的數(shù)據(jù),然后通過已知數(shù)據(jù)去訓(xùn)練模型,得到人臉的姓名標(biāo)簽和人臉的一一對應(yīng)關(guān)系,那么進行人臉的識別時,就能根據(jù)訓(xùn)練的數(shù)據(jù)去識別畫面中的人臉是誰了,能夠在畫面中顯示出它的名字。
主要功能:首先能打開攝像頭,找到框出人臉的部分,且我們要對人臉部分截取保存,因為我們是訓(xùn)練姓名和人臉一一對應(yīng),所有別忘了保存圖片的時候讓用戶輸入姓名,為了減小圖片大小,我們可以將截取的圖片轉(zhuǎn)化成灰度圖片,不需要彩色的。步驟如下:
- 打開攝像頭。
- 輸入人臉對應(yīng)的姓名。
- 檢測畫面中的人臉部分。
- 保存人臉圖片。(灰度圖片,不需要彩色)
2、數(shù)據(jù)訓(xùn)練模塊。
主要目的:通過保存的數(shù)據(jù),使用模塊自帶的訓(xùn)練器,訓(xùn)練得到姓名和人臉的一一對應(yīng)關(guān)系。
主要功能:讀取文件的 圖片和姓名,開始訓(xùn)練數(shù)據(jù),訓(xùn)練結(jié)束將數(shù)據(jù)保存。步驟如下:
- 讀取保存的全部灰度圖片和姓名。
- 訓(xùn)練數(shù)據(jù)。
- 保存數(shù)據(jù)。
3、人臉識別模塊。
主要目的:根據(jù)所訓(xùn)練的數(shù)據(jù),能夠在我們打開攝像頭的時候,標(biāo)記出畫面中的人臉部分,且在畫面中顯示人臉的姓名。
主要功能:能夠打開攝像頭,能夠框出畫面中的人臉部分,能夠識別畫面中的人臉并在畫面中顯示人臉的姓名。步驟如下:
- 打開攝像頭。
- 檢測人臉部分,框出人臉。
- 進行人臉識別,在畫面中顯示人臉姓名。
二:項目具體實現(xiàn)代碼及結(jié)果演示
1、建立項目文件
我們將本項目中用到一些路徑定義為宏,保存到python文件中,命名為hong,py。將人臉灰度照片保存到文件夾中,建立文件夾data。訓(xùn)練數(shù)據(jù)也需要保存到文本里面,新建文本文件命名為Training_data。新建三個python文件,分別用于三個模塊的具體實現(xiàn)。項目目錄如下:
宏文件源代碼供參考:
INPUT_FACE_WINDOWS_NAME = 'input_face' BGR_GREEN = (0, 255, 0) BGR_RED = (0, 0, 255) FACE_MIN_SIZE = (60, 60) # 保存圖片的路徑 IMG_SAVE_PATH = './data' # 級聯(lián)人臉特征檢測器 FACE_CLASSIFIER_PATH = 'D:/python_project/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml' TRAIN_DATA_SAVE_PATH = './Training_data' FACE_RECOGNITION_WINDOW_NAME = "Face recognition" FONT_SCALE = 0.75 # 字體比例 TEXT_THICKNESS = 1 # 線條粗細(xì) GRAPH_THICKNESS = 1
2、人臉錄入模塊代碼實現(xiàn)。
import cv2 as cv from hong import * import os def img_extract_faces(img): # 將人臉圖片轉(zhuǎn)為灰度 gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 轉(zhuǎn)成灰度圖像 face_classifier = cv.CascadeClassifier(FACE_CLASSIFIER_PATH) # 加載級聯(lián)檢測器,人臉特征分類器 return face_classifier.detectMultiScale(gray, minSize=FACE_MIN_SIZE), gray def get_image_name(name): # 獲取圖片的命名名字,格式:1.lihua.jpg # 1.lihua.jpg 格式。如果文件中沒有則加入,如果已有則替換 # 把讀出來的圖片名稱,用字典存,然后用name去字典里面找有沒有。 f = os.listdir(IMG_SAVE_PATH) # os.listdir(IMG_SAVE_PATH)返回目標(biāo)路徑里的文件列表 if len(f) == 0: # 文件列表f的長度為0則表示沒有圖片,編號為1 name_number = 1 else: # 說明原文件有人臉照片,如果出現(xiàn)相同人臉姓名替換成新的,沒有編號為最大值max.name.jpg加入進去。 name_map = {f.split('.')[1] : int(f.split('.')[0]) for f in os.listdir(IMG_SAVE_PATH)} name_number = name_map[name] if name in name_map else max(name_map.values())+1 # return IMG_SAVE_PATH + str(name_number) + "." + name + ".jpg" return str(name_number) + "." + name + ".jpg" def save_face(faces, img, name): # 保證只有一個人臉出現(xiàn)在畫面中 if len(faces) == 0: print('沒有檢測到人臉,請調(diào)整?。。?) if len(faces) > 1: print('檢測到多個人臉,請調(diào)整?。?!') x, y, w, h = faces[0] # 保存人臉部分,保存到文件夾,格式為 1.李華.jpg 格式。如果文件中沒有則加入,如果已有則替換 cv.imwrite('./data/' + get_image_name(name), img[y: y + h, x: x + w]) print('錄入成功,按 q 鍵退出') def main(): # 人臉錄入部分是為了得到人臉的數(shù)據(jù),然后后面對人臉進行訓(xùn)練。 # 人臉數(shù)據(jù)信息主要有三個部分。1、人臉圖片。 2、人臉名字。 3、編號(編號需要和名字需要統(tǒng)一。以為訓(xùn)練數(shù)據(jù)是拿序號和人臉進行比對) # 1、人臉圖片(打開攝像頭、只取人臉部分、給用戶實時展示人臉的畫面(把人臉框出來)、保存和退出) # 2、人臉名字。(用戶輸入) # 3、編號。(文件名稱記錄) # 打開攝像頭 cap = cv.VideoCapture(0) if not cap.isOpened(): print('連接攝像頭失敗') # 輸入人臉的名字 name = input("請輸入姓名:") if name == ' ': print('姓名不能為空,請重新輸入?。。?) print('姓名輸入完成:按 s 保存,按 q 退出。') # 循環(huán)讀取攝像頭的每一幀畫面,然后識別畫面中的人臉,識別后只保存人臉部分,作為訓(xùn)練數(shù)據(jù)。 while True: ret, frame = cap.read() if not ret: print('讀取失敗') break # 檢測人臉,且提取人臉部分。這部分直接使用一個函數(shù)封裝起來。 faces, gray = img_extract_faces(frame) # 框出人臉 for x, y, w, h in faces: cv.rectangle( img=frame, pt1=(x, y), pt2=(x+w, y+h), color=BGR_GREEN, thickness=1 ) cv.imshow(INPUT_FACE_WINDOWS_NAME, frame) # 保存和退出 k = cv.waitKey(1) if k == ord('s'): # 保存圖像,(只需保存灰度圖像) save_face(faces, gray, name) elif k == ord('q'): break # 釋放內(nèi)存 cap.release() cv.destroyAllWindows() if __name__ == '__main__': main()
運行imput_face.py錄入人臉:
點擊英文的s鍵,即可保存人臉到data文件中,如下圖所示:
3、訓(xùn)練數(shù)據(jù)模塊代碼實現(xiàn)。
import cv2 as cv import os from hong import * import numpy as np def main(): # 獲取圖片完整路徑 image_paths = [os.path.join(IMG_SAVE_PATH, f) for f in os.listdir(IMG_SAVE_PATH)] # 遍歷列表中的圖片 faces = [cv.imread(image_path, 0) for image_path in image_paths] # 獲取訓(xùn)練對象 img_ids = [int(f.split('.')[0])for f in os.listdir(IMG_SAVE_PATH)] recognizer = cv.face.LBPHFaceRecognizer_create() recognizer.train(faces, np.array(img_ids)) print(faces, np.array(img_ids)) # 保存文件 recognizer.write(TRAIN_DATA_SAVE_PATH) if __name__ == '__main__': main()
運行train.py文件訓(xùn)練data文件夾里面的數(shù)據(jù):
4、人臉識別模塊代碼實現(xiàn)。
""" 通過攝像頭識別人臉(LBPH識別器(訓(xùn)練的數(shù)據(jù),和當(dāng)前的人臉圖片))得到編號。編號和人臉的對應(yīng)關(guān)系,標(biāo)記人臉和名字并展示畫面 創(chuàng)建識別器,加載訓(xùn)練數(shù)據(jù) 讀取文件構(gòu)造編號和人臉的關(guān)系 打開攝像頭 循環(huán)取每幀畫面 人臉檢測且提取人臉部分 遍歷人臉進行識別 框出人臉部分且實時展示畫面(畫面上帶有 ) 關(guān)閉攝像頭和窗口 """ import os import cv2 as cv from cv2 import face from hong import * from train import * from imput_face import img_extract_faces def get_color_text(confidence, name): if confidence > 85: return BGR_RED, "unknown" return BGR_GREEN, name def main(): # 創(chuàng)建識別器 recognizer = cv.face.LBPHFaceRecognizer_create() recognizer.read(TRAIN_DATA_SAVE_PATH) # 讀取文件構(gòu)造編號和人臉的關(guān)系。以字典的形式保存編號和人臉名字的關(guān)系 name_map = {int(f.split('.')[0]): f.split('.')[1] for f in os.listdir(IMG_SAVE_PATH)} # 打開攝像頭 cap = cv.VideoCapture(0) if not cap.isOpened(): print('連接攝像頭失敗') print("按q退出") # 循環(huán)取每幀畫面 while True: ret, frame = cap.read() if not ret: print('讀取失敗') break # 人臉檢測,且提取人臉部分。 faces, gray = img_extract_faces(frame) # 遍歷人臉進行識別 for x, y, w, h in faces: img_id, confidence = recognizer.predict(gray[y: y+h, x: x+w]) # 返回圖片編號和置信度。置信度為兩張圖片的相似程度 # 框出人臉且實時展示畫面 color, text = get_color_text(confidence, name_map[img_id]) cv.putText( img=frame, text=text, org=(x, y), fontFace=cv.FONT_HERSHEY_SIMPLEX, fontScale=FONT_SCALE, color=color, thickness=TEXT_THICKNESS ) cv.circle( img=frame, center=(x+w//2, y+h//2), radius=w // 2, color=color, thickness=GRAPH_THICKNESS ) cv.imshow(FACE_RECOGNITION_WINDOW_NAME, frame) if cv.waitKey(1) == ord('q'): break # 關(guān)閉攝像頭,釋放空間 cap.release() cv.destroyAllWindows() if __name__ == '__main__': main()
運行face_recognition.py文件進行人臉識別:
項目介紹到這里,感謝閱讀?。?!
到此這篇關(guān)于使用python的opencv實現(xiàn)人臉識別的文章就介紹到這了,更多相關(guān)python opencv人臉識別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pytorch MSELoss計算平均的實現(xiàn)方法
這篇文章主要介紹了pytorch MSELoss計算平均的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-05-05Python+Pygame實現(xiàn)經(jīng)典魂斗羅游戲
《魂斗羅》(Contra)是由Konami于1987年推出的一系列卷軸射擊類單機游戲。本文將利用Python中的Pygame庫實現(xiàn)這一經(jīng)典游戲,感興趣的可以了解一下2022-05-05解決python文件字符串轉(zhuǎn)列表時遇到空行的問題
下面小編就為大家?guī)硪黄鉀Qpython文件字符串轉(zhuǎn)列表時遇到空行的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07Python無法安裝包的一種解決(Requirement already satisfied問題)
這篇文章主要介紹了Python無法安裝包的一種解決(Requirement already satisfied問題),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08python數(shù)據(jù)可視化Seaborn畫熱力圖
這篇文章主要介紹了數(shù)據(jù)可視化Seaborn畫熱力圖,熱力圖的想法其實很簡單,用顏色替換數(shù)字,下面我們來看看文章對操作過程的具體介紹吧,需要的小伙伴可以參考一下具體內(nèi)容,希望對你有所幫助2022-01-01