Python-OpenCV人臉識別之數據集生成

上一篇文章中,咱們學習瞭如何安裝配置OpenCV和Python,而後寫了些代碼玩玩人臉檢測。如今咱們要進行下一步了,即搞一我的臉識別程序,就是不僅是檢測還須要識別到人是誰。python

來,搞人臉識別

要搞一我的臉識別程序,首先咱們須要先用提早裁剪好的標註好的人臉照片訓練一個識別器。好比說,咱們的識別器須要識別兩我的,一我的的id是1,而另外一個的id是2,因而在數據集裏面,1號人的全部照片會有id 1號,2號人同理。而後咱們就會使用這些數據集照片去訓練識別器,再從一個視頻中識別出1號人。shell

咱們把要作的事分紅三部分:數組

  1. 建立數據集
  2. 訓練
  3. 識別

在本文中,咱們會嘗試寫一個程序來生成數據集。ide

生成數據集

咱們來寫一個數據集生成腳本。學習

首先打開咱們的Python環境,無論是Pycharm等IDE,仍是簡單的記事本都行。須要提早準備的是在目錄中放好haarcascade_frontalface_default.xml,上一篇也有用到過這個XML文件,就是OpenCV自帶的。ui

接下來使用cv2獲取攝像頭數據以及XML文件:spa

import cv2
cam = cv2.VideoCapture(0)
detector=cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

咱們的數據集須要先從攝像頭採集一些人臉例子照片,固然,只能是同一我的的。而後程序會給這些例子照片添加id,並將照片保存在一個文件夾中,這個文件夾咱們就將它命名爲dataSet吧。code

來,咱們在py腳本的同目錄下建立一個dataSet的文件夾。爲了避免會將不一樣的人臉照片弄混,咱們須要定一個命名規則,用於給照片命名。視頻

例如,命名規則爲User.[ID].[SampleNumber].jpg。若是是2號人的第十張照片,咱們能夠將它命名爲User.2.10.jpgxml

爲何要定義這樣的格式呢?由於這樣,在加載照片訓練的時候,咱們就能夠只經過照片的文件名,就能簡單地判斷是幾號用戶的人臉照片。

接下來,咱們嘗試用比較簡單的方法,經過shell輸入,來獲取人的id,而且初始化計算器變量來存儲人們的例子數。

Id = raw_input('enter your id: ')
sampleNum = 0

而後咱們加入一個主循環,咱們會從視頻流中輸入20個例子,而後把例子都保存在已經建立好的dataSet文件夾。

這是以前寫過的代碼版本,用於人臉檢測:

while True:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

    cv2.imshow('frame', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

如今咱們將它改形成數據集生成程序:

while True:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

        # 增長例子數
        sampleNum = sampleNum + 1
        # 把照片保存到數據集文件夾
        cv2.imwrite("dataSet/user." + str(Id) + '.' + str(sampleNum) + ".jpg", gray[y:y + h, x:x + w])

        cv2.imshow('frame', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

咱們添加了兩行代碼,用以計算例子數,以及將人臉照片按照咱們的命名規則保存爲jpg格式。

其中有一個值得注意的地方,就是gray[y : y + h, x : x + w]。此處咱們是把一張灰度圖片當作一個二維數組(或二維矢量),而後使用python中[]截取OpenCV檢測出來的人臉區域。

不過這樣的代碼會在一秒內快速地生成許多照片,好比說20張。咱們不想要那麼快,咱們須要的是更好的素材,好比說從不一樣角度拍攝出來的照片,這樣的話,要求慢一點。

爲了慢一點,咱們須要提升一下兩次拍攝之間的延遲。同時,咱們素材不須要太多,20張就好。

while True:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

        # 增長例子數 
        sampleNum = sampleNum + 1
        # 把照片保存到數據集文件夾
        cv2.imwrite("dataSet/User." + str(Id) + '.' + str(sampleNum) + ".jpg", gray[y:y + h, x:x + w])  #

        cv2.imshow('frame', img)
    # 延遲100毫秒 
    if cv2.waitKey(100) & 0xFF == ord('q'):
        break
    # 超過20張就能夠停了
    elif sampleNum > 20:
        break

好,繼續,如今的代碼就會在兩個拍攝間延遲100毫秒,100毫秒足夠讓咱們去移動咱們人臉的角度了(時間不夠長就再加)。並且,在拍攝20張後就中止了。

最後記得釋放資源:

cap.release()
cv2.destroyAllWindows()

放出完整代碼:

import cv2

detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture(0)
sampleNum = 0
Id = raw_input('enter your id: ')

while True:
    ret, img = cap.read()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector.detectMultiScale(gray, 1.3, 5)
    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

        # incrementing sample number
        sampleNum = sampleNum + 1
        # saving the captured face in the dataset folder
        cv2.imwrite("dataSet/User." + str(Id) + '.' + str(sampleNum) + ".jpg", gray[y:y + h, x:x + w])  #

        cv2.imshow('frame', img)
    # wait for 100 miliseconds
    if cv2.waitKey(100) & 0xFF == ord('q'):
        break
    # break if the sample number is morethan 20
    elif sampleNum > 20:
        break

cap.release()
cv2.destroyAllWindows()

生成結果

如圖,已經生成了一堆訓練素材了。

先這樣吧

原文,如有錯誤之處請指出,更多地關注煎魚

相關文章
相關標籤/搜索