python使用opencv攝像頭識別特定人臉,並啓動語音問候

"""

==================== 訓練臉部數據  ==================

"""

學習要有一種空杯的心態,先跟着來---------------------------------->>>

一、準備臉部圖片:

我們將要檢測的臉部圖片命名爲"姓名_數字編號.jpg"的形式,注意編號不連續,創建一個facePics文件夾專門放圖片的。

完整代碼如下:

#  訓練臉部數據 ===============================================
print('*'*50)
print('\t'*5,'訓練臉部數據程序')
print('*'*50)

import os
import cv2 as cv
import numpy as np
from PIL import Image

# 檢查圖片數據是否存在

array_of_img = []
def read_directory(directory_name):
    for filename in os.listdir(directory_name):
        img = cv.imread(directory_name + "/" + filename)
        array_of_img.append(img)

# 圖片文件夾
directory = os.getcwd()+'\\facePics'
read_directory(directory)
count = len(array_of_img)
if count == 0:
    print('facePics文件夾下不存在用於訓練的圖片,將退出!')
    input('按任意鍵退出')
    quit()

print('開始訓練數據...')

# 人臉檢測器
face_detector=cv.CascadeClassifier('haarcascade_frontalface_default.xml')

# 獲取訓練圖片和對應的標籤id
def getImageAndLabels(path):
    # 人臉區域數組
    faceSamples=[]
    # 圖像id數組
    ids=[]
    # 合併圖片全路徑名稱存入列表
    imgPaths=[os.path.join(path,f) for f in os.listdir(path)]
    #print(imgPaths)  
    # 遍歷列表中的圖片
    for impath in imgPaths:
        # 打開圖片
        PIL_img=Image.open(impath).convert('L')   # 轉爲灰度圖
        # 將圖像轉換爲數組
        img_numpy=np.array(PIL_img,'uint8')
        # 將面部圖片數組傳入檢測器,獲取人臉數據
        faces=face_detector.detectMultiScale(img_numpy)
        # 獲取每張圖片的id
        splitStr = os.path.split(impath)  # 切分路徑
        #print(splitStr)                  # ('C:\\Users\\Administrator\\Desktop\\python學習筆記\\facePics', '小明_1.jpg')
        idStr = splitStr[1].split('.')[0]
        idStr = idStr.split('_')[1]       # 小明_1     
        id = int(idStr)
        
        for x,y,w,h in faces:
            # 提取人臉
            faceSamples.append(img_numpy[y:y+h,x:x+w])   # 二維數組切片:獲取y:y+h行,x:x+w列
            ids.append(id)
    return faceSamples,ids

if __name__=='__main__':
    # 圖片路徑
    path='facePics'  
    # 獲取圖像數組和id標籤數組
    faces, ids = getImageAndLabels(path)
    # 獲取訓練對象   
    recognizer = cv.face.LBPHFaceRecognizer_create()     # 注:如果報錯可能因爲未安裝contrib(用於訓練數據),嘗試pip install opencv-contrib-python
    # 訓練數據
    recognizer.train(faces,np.array(ids))    # train(面部數據,圖片id數組)
    # 保存文件
    recognizer.write('trainer.yml')
    print('臉部數據 trainer.yml 訓練成功')
    input('按任意鍵退出')
    quit()

如果你的機器環境都OK,且程序無誤,那麼運行上述代碼將會生成trainer.yml數據文件。

 

"""

=================== 攝像頭識別併發出問候音  ==================

"""

二、找一臺有攝像頭的機器,運行以下代碼,將開啓人臉識別模式

完整代碼如下:

# 檢測視頻人臉 ========================================================================

import os
from win32com.client import Dispatch
print(os.getcwd()) # 獲得當前目錄
print('================================= 人臉識別程序 ==============================')
_input=input('按任意鍵開始!')
# 檢查訓練數據是否存在
exist = os.path.exists(os.getcwd()+'\\trainer.yml');
if not exist:   # 文件不存在
    print('訓練數據 trainer.yml 不存在,系統將退出!')
    input('請按任意鍵退出')
    quit()

# 獲取所有圖片的id和對應名稱
names={}
#{1:'貝提',1:'魯姆',1:'傑米',1:'大衛',1:'米妮'}
def getNamesDic(imgPaths):    
    for impath in imgPaths:
        # 獲取每張圖片的id
        splitStr = os.path.split(impath)  # 切分路徑
        #print(splitStr)                  # ('C:\\Users\\Administrator\\Desktop\\python學習筆記\\facePics', '小明_1.jpg')
        fulnam = splitStr[1].split('.')[0] # 小明_1 
        idStr = fulnam.split('_')[1]       # 1    
        nam = fulnam.split('_')[0]          # 小明
        id = int(idStr)
        names[id] = nam

imgPaths = []
def read_directory(directory_name):
    for filename in os.listdir(directory_name):
        picname = directory_name + "/" + filename
        imgPaths.append(picname)
# 圖片文件夾
directory = os.getcwd()+'\\facePics'
read_directory(directory)
getNamesDic(imgPaths)

# 使用文字轉語音功能,發出問候音:xx,你好!
def welcome(id): 
    msg='你好,'+str(id)
    speaker=Dispatch('SAPI.SpVoice')
    speaker.Speak(msg)
    del speaker

# cv2.VideoCapture(0)代表調取攝像頭資源,其中0代表電腦攝像頭,1代表外接攝像頭(usb攝像頭)
# cap.read()按幀讀取視頻,ret,frame是獲cap.read()方法的兩個返回值。其中ret是布爾值,
# 如果讀取幀是正確的則返回True,如果文件讀取到結尾,它的返回值就爲False,如果沒有攝像頭則返回False。frame就是每一幀的圖像,是個三維矩陣。
print('正在打開攝像頭...')
cap = cv.VideoCapture(0)   # 調用自己的攝像頭
ret,frame = cap.read()
if not ret:
    cap = cv.VideoCapture(1)
    ret,frame = cap.read()
    if not ret:
        print('未發現電腦攝像頭,或未能打開攝像頭,將進行本地視頻人臉識別')   # False
        cap = cv.VideoCapture('video.mkv')
        ret,frame = cap.read()
        if not ret:
            quit()
                 
def face_detect_demo(img):
    #print(type(img))   # <class 'numpy.ndarray'>
    # 將圖片灰度
    gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
  
    # 加載訓練數據集文件
    recognizer = cv.face.LBPHFaceRecognizer_create()
    recognizer.read('trainer.yml')
    # 加載特徵數據
    # 'D:\\opencv_3.4.7\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_default.xml'
    #
    face_detector = cv.CascadeClassifier('haarcascade_frontalface_default.xml')
    faces = face_detector.detectMultiScale(gray)
   
    for x,y,w,h in faces:
        cv.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2)        
        # 識別是哪一個
        id,confidence=recognizer.predict(gray[y:y+h,x:x+w])
        # 播放歡迎語音...
        if confidence<50:
            print('標籤id:',id,' 置信評分:',confidence,end='\t')
            print('你好,',names[id])
            # 在人臉下畫一個有名字的標籤;cv2.putText 不支持中文所以這裏換一種方法
            cv.putText(img, str(id), (x,y), cv.FONT_HERSHEY_SIMPLEX, 1.0, (255, 255, 255), 1)   # 圖像,文字內容, 座標 ,字體,大小,顏色,字體厚度
            ##font=ImageFont.truetype('msyh.ttc',20)     # 微軟雅黑20號字體,此處未指定路徑會從Windows字體目錄查找
            ##img_pil = Image.fromarray(img)
            ##draw = ImageDraw.Draw(img_pil)
            ##d#raw.text( (x,y), names[id], font=font, fill=(255, 255, 255))
            ##frame = np.array(img_pil)
            welcome(names[id])     
    cv.imshow('result',img)

print('加載人臉特徵數據...')
while True:
    flag,frame=cap.read()
    #print('flag: ',flag,'frame.shape: ',frame.shape)   # flag:  True frame.shape:  (720, 1280, 3)
    if not flag:
        break
    # 將視頻幀的大小調整爲1/2以加快人臉識別處理
    #frame = cv.resize(frame, (0, 0), fx=0.5, fy=0.5)
    face_detect_demo(frame)
    if ord('q') == cv.waitKey(10):
        break

cv.destroyAllWindows()    # 釋放內存
cap.release()    # 清理空間

如果攝像頭識別到相似度高的人臉,將啓動問候音:“xx,你好!”
特別注意:安裝的opencv的版本和python的版本都需要考慮到,不然會很麻煩!我們需要將臉部數據特徵xml文件,和訓練出來的數據yml文件放好位置;

最後鏈接附上源碼和相關資源

注:(由於CSDN有上傳文件大小限制,我打包好的exe可執行程序就不上傳了,需要加微信:2463954659)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章