天天看點

【opencv實踐】人臉識别比對——資料收集和預處理

參考自@星沉閣冰不語出品,轉載請注明作者和出處。

原連結:http://blog.csdn.net/xingchenbingbuyu/article/details/51386949

本人女學渣一枚研一,所有過程參考上面的大神,記錄一下我的曆程。

畢業論文将做【基于opencv的課堂點名和監控系統】,之前一直在做人臉檢測,如果各路大神有什麼好點子請在下方留言。下面開始。

人臉檢測可以利用opencv自帶的分類器,但是人臉識别就需要自己收集資料,自己訓練分類器了。opencv給出的有人臉識别的教程:Face Recognition with OpenCV。網上也可以找到中文版本的。

一、背景資料集

本次用的資料集市opencv給出的教程裡面的第一個資料集:The AT&T Facedatabase。又稱ORL人臉資料庫,40個人,每人10張照片。照片在不同時間、不同光照、不同表情(睜眼閉眼、笑或者不笑)、不同人臉細節(戴眼鏡或者不戴眼鏡)下采集。所有的圖像都在一個黑暗均勻的背景下采集的,正面豎直人臉(有些有有輕微旋轉)。

下載下傳下來之後是這樣的:

【opencv實踐】人臉識别比對——資料收集和預處理
【opencv實踐】人臉識别比對——資料收集和預處理

可以看到每個人一個檔案夾,每個檔案夾下是這個人的十張照片,但是不是我們熟悉的BMP或者是PNG或者是JPEG格式的,而是PGM格式的。windows7自帶的照片檢視器和畫圖軟體都不能打開這種格式的圖檔!!是以我們将用強大的imread()函數讀取,是以記得opencv文檔裡有這樣的描述:

【opencv實踐】人臉識别比對——資料收集和預處理
#include<opencv2\opencv.hpp>

using namespace cv;
int main()
{
    Mat img = imread("C:\\Users\\Apple\\Desktop\\ORL\\s40\\1.pgm");
    imshow("1", img);
    waitKey();
    return ;
}
           
【opencv實踐】人臉識别比對——資料收集和預處理
【opencv實踐】人臉識别比對——資料收集和預處理
【opencv實踐】人臉識别比對——資料收集和預處理

二、自己的人臉資料集

1.拍照程式

想要識别自己,單有别人的資料集還是不行的,還需要自己人臉的照片才行。這就需要我們收集自己的照片,然後和上面的那個資料集一起來訓練模型。在拿着手機自拍的過程中我想到,問什麼不寫一個程式用電腦的攝像頭自拍呢,随便還能研究下怎麼用opencv實作拍照的功能。經過一番實驗(其實還是費了好長時間),終于寫了一個拍照程式。

程式的功能就是打開電腦攝像頭,當P鍵按下的時候,儲存目前幀的圖像。簡單到沒朋友。

#include<opencv2\opencv.hpp>

using namespace cv;

int main()
{
    VideoCapture cap();
    Mat frame;
    int i = ;

    while ()
    {
        char key = waitKey();
        cap >> frame;
        imshow("frame", frame);
        string filename = format("C:\\Users\\Apple\\Desktop\\hhh\\aaa%d.jpg", i);

        switch (key)
        {
        case'p':
            i++;
            imwrite(filename, frame);
            imshow("photo", frame);
            waitKey();
            destroyWindow("photo");
            break;
        default:
            break;
        }
    }
}
           

然後我們就可以運作程式,不停地按下p鍵對自己一通狂拍了。

2.預處理

在得到自己的人臉照片之後,還需要對這些照片進行一些預處理才能拿去訓練模型。所謂預處理,其實就是檢測并分割出人臉,并改變人臉的大小與下載下傳的資料集中圖檔大小一緻。

檢測出人臉之後改變大小使之與ORL人臉資料庫人臉大小一緻。通過加斷點在Locals裡面或者是ImageWatch可以看到ORL人臉資料庫人臉的大小是92 x 112。(這個也是根據部落客部落格學習的)

【opencv實踐】人臉識别比對——資料收集和預處理

那麼如何批量處理上面拍的照片呢?我給實驗室每位同學都來了20連拍,這個工作量還是很大的。答主給的程式不太全,編了一下午才調好了代碼。可以分割人臉并且變大小灰階與ORL資料庫人臉大小一緻,然後儲存下來,儲存的檔案夾一定要注意先提前建好。

代碼如下:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>

using namespace cv;

int main()
{
    char file_img[];
    Mat t_img[];
    vector<Rect> faces;
    CascadeClassifier face_cascade;
    face_cascade.load("haarcascade_frontalface_alt.xml");

    //Size dst_size;
    //讀取訓練樣本
    for (int i = ; i < ; i++)
    {
        Mat img_gray;
        int d = i + ;
        sprintf(file_img, "C:\\Users\\Apple\\Desktop\\頭2\\%d.jpg", d);
        Mat img = imread(file_img, );
        cvtColor(img, img_gray, COLOR_BGR2GRAY);
        equalizeHist(img_gray, img_gray);

        //-- Detect faces;
        //檢測人臉
        face_cascade.detectMultiScale(img_gray, faces, , , CV_HAAR_DO_CANNY_PRUNING, Size(, ),Size(,));
        if (faces.size() == )
        {

            continue;

        }
        Mat faceROI = img(faces[]);
        Mat MyFace;
        resize(faceROI, MyFace, Size(, ));
        cvtColor(MyFace, MyFace, COLOR_BGR2GRAY);
        string  str = format("C:\\Users\\Apple\\Desktop\\頭3\\%d.jpg", d);
        imwrite(str, MyFace);
        imshow("ii", MyFace);
        waitKey();
    }
}
           

至此,我們就得到和ORL人臉資料庫人臉大小一緻的自己的人臉資料集。然後我們把自己的作為第41個人,在我們下載下傳的人臉檔案夾下建立一個s41的子檔案夾,把自己的人臉資料放進去。就成了這樣下面這樣,最後一個檔案夾裡面是我自己的頭像照片,我還多做了實驗室同學的資料集,一共五個人。

【opencv實踐】人臉識别比對——資料收集和預處理

注意:我這裡儲存的圖像格式是.jpg的,而不是跟原資料集一樣是.pgm的。經測試仍然可以訓練出可以正确識别我自己人臉的模型來。但是如果大小不一緻會報錯。

跟着大神做了一天,十分疲憊。。

未完待續……