先來普及一下概念, 計算機對人臉是如何識別的呢? 或者說圖像是如何識別的。主要是獲取單張圖片的特徵值記錄了特徵值之後,若是下一張圖片來了之後兩張圖片特徵值進行對比,若是類似度很高那麼計算機就認定這兩個是一類圖(固然這是須要算法來實現的)git
我寫的這個是怎麼實現的呢,一組訓練集訓練要識別的人的圖像來進行特徵提取保存到模型中,在經過攝像頭返回的圖像進行處理並最後展示出來github
直接上代碼: ---- 抱歉因爲不知道插入代碼後怎麼寫文字我就全寫這了。代碼不算完善,可是識別沒問題 使用時修改 train_path 和 fd 的人臉描述.xml文件路徑就ok了算法
訓練文件結構描述 : train_path文件結構 train_path -> LL(老李) -> 全部人臉圖片數組
face.xml 文件下載地址 : http://note.youdao.com/noteshare?id=a74c5cffa145ff5341560d6c269702cb&sub=6A602009232C468CBE83114E840D679Eapp
# 抱歉因爲本人不會用 github 因此你們用有道雲下載吧(捂臉笑)ide
1 # -*- coding: utf-8 -*- 2 from __future__ import unicode_literals 3 # 操做文件 4 import os 5 # 科學計算 6 import numpy as np 7 # 圖像識別 8 import cv2 as cv 9 # 數據預處理, 該項目中只使用了標籤編碼 10 import sklearn.preprocessing as sp 11 12 13 def load_imgs(directory): 14 '''加載 directory 該文件夾下全部以 .jpg 結尾的圖片''' 15 # 識別 系統環境 自動分配當前系統的路徑分隔符並替換 16 directory = os.path.normpath(directory) 17 # 判斷當前路徑是否爲存在 18 if not os.path.isdir(directory): 19 # 手動拋出異常 biu biu biu 20 raise IOError("The directory '" + directory + "' doesn't exist!") 21 # 建立圖片集合 用於存儲文件夾名和該文件夾下全部的圖片 22 faces = {} 23 # os.walk(directory) 獲取當前文件夾下全部的文件夾以及文件 24 # curdir: 當前文件夾路徑 25 # subdirs: 當前文件夾下全部文件夾 (列表) 26 # files: 當前文件夾下全部文件 (列表) 27 for curdir, subdirs, files in os.walk(directory): 28 # 首先便利全部的文件 篩選.jpg結尾文件並循環 29 for jpeg in (file for file in files if file.endswith('.jpg')): 30 # 拼接圖片路徑 31 path = os.path.join(curdir, jpeg) 32 # 獲取該圖片分類名稱 33 label = path.split(os.path.sep)[-2] 34 # 判斷當前key值是否存在圖片集合中, 若是爲空則建立該鍵並賦值空列表 35 # 不然給圖片集合中的 key 添加圖片路徑 36 if label not in faces: 37 faces[label] = [] 38 faces[label].append(path) 39 # 返回圖片集合 40 return faces 41 42 43 def LBPHModel(fd, codec, train_path): 44 ''' 45 ------------------- 46 參數說明: fd, codec, [model_path] 47 fd: Haar-like(人臉特徵模型對象) 48 codec: LabelEncoder(標籤編碼器對象) 49 model_path: 服用模型路徑(功能未實現, 沒找到讀取的函數...) 50 ------------------- 51 返回: 訓練後的模型對象 52 ''' 53 # 加載當前文件加下全部.jpg結尾的圖片 54 train_faces = load_imgs(train_path) # 'traom_imgs' 55 # 將全部標籤放入編碼器進行訓練 56 codec.fit(list(train_faces.keys())) 57 # 建立空的訓練集數組x y 58 train_x, train_y = [], [] 59 # 循環全部訓練組 60 for label, filenames in train_faces.items(): 61 # 循環當前樣本組中的圖片 62 for filename in filenames: 63 # 讀取圖片 64 image = cv.imread(filename) 65 # 將圖片轉成灰度圖 66 gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) 67 # 獲取人臉特徵位置 68 faces = fd.detectMultiScale( 69 gray, 1.1, 2, minSize=(100, 100)) 70 # 循環臉部特徵數組 71 for l, t, w, h in faces: 72 # 將圖片中的臉部特徵裁剪下來 73 train_x.append(gray[t:t + h, l:l + w]) 74 # 標籤編碼結果存儲 75 train_y.append(codec.transform([label])[0]) 76 train_y = np.array(train_y) 77 # 建立LBPH人臉檢測器 78 model = cv.face.LBPHFaceRecognizer_create() 79 # 對訓練集進行訓練 80 model.train(train_x, train_y) 81 return model 82 83 84 if __name__ == "__main__": 85 # 訓練集圖片存儲路徑 86 train_path = 'train_imgs' 87 # 讀取人臉描述文件, 構建人臉檢測器 88 fd = cv.CascadeClassifier('face.xml') 89 # 建立標籤編碼器 90 codec = sp.LabelEncoder() 91 # 獲取model 92 model = LBPHModel(fd, codec, train_path) 93 # 打開視頻捕捉設備 94 vc = cv.VideoCapture(0) 95 while True: 96 # 讀取視頻幀 97 frame = vc.read()[1] 98 # 反轉圖片 99 frame = cv.flip(frame, 1) 100 # print(frame) 101 # 人臉位置檢測, 返回數組 102 faces = fd.detectMultiScale(frame, 1.3, 5) 103 # 循環人臉位置數組 104 for l, t, w, h in faces: 105 # 給人臉描邊 106 cv.rectangle(frame, (l, t), (l + w, t + h), 107 (255, 0, 0), 4) 108 # 複製原圖片文本 109 gray = frame.copy() 110 # 將圖片變化成灰度圖 111 gray = cv.cvtColor(gray, cv.COLOR_BGR2GRAY) 112 # 對面部特徵進行識別 113 pred_test_y = model.predict(gray[t:t + h, l:l + w])[0] 114 # 將預測後的結果進行標籤解碼 115 face_name = codec.inverse_transform([pred_test_y])[0] 116 # 給圖片添加文本 圖片矩陣, 添加文本名稱, 設置文本顯示位置, 117 # 字體樣式, 字體大小, 字體顏色, 字體粗細 118 cv.putText(frame, face_name, (l + 5, t - 15), 119 cv.FONT_HERSHEY_SIMPLEX, 1, 120 (255, 255, 255), 3) 121 # 打印名稱 122 # print(face_name) 123 124 # 顯示圖片 125 cv.imshow('VideoCapture', frame) 126 # 等待按下ESC鍵退出, 每次等待33毫秒 127 if cv.waitKey(33) == 27: 128 break 129 # 關閉視頻捕捉設備 130 vc.release() 131 # 關閉視頻窗口 132 cv.destroyAllWindows()