基於 Python + OpenCV 進行人臉識別,視頻追蹤代碼全註釋

先來普及一下概念, 計算機對人臉是如何識別的呢? 或者說圖像是如何識別的。主要是獲取單張圖片的特徵值記錄了特徵值之後,若是下一張圖片來了之後兩張圖片特徵值進行對比,若是類似度很高那麼計算機就認定這兩個是一類圖(固然這是須要算法來實現的)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()
相關文章
相關標籤/搜索