天天看點

基于OpenCV級聯分類器的人臉檢測項目場景:正樣本準備:負樣本準備:分類器樣本制作:opencv配置:vec檔案擷取:開始訓練:結果驗證:總結

提示:文章寫完後,目錄可以自動生成,如何生成可參考右邊的幫助文檔

使用級聯分類器訓練人臉模型

項目場景:

作為一個大四狗,在畢業之前想做點有意思的東西,加上人工智能這兩年很火,也就從網上找資源,進行了一個學習的過程,使用的平台是QT5.12+OpenCV3.40。目的就是為了訓練一個可以進行人臉檢測的模型。

正樣本準備:

跟着賈志剛老師的課程學了一段時間以後,自己也就找項目去練手去了。不過在訓練的過程中還是借鑒了大佬的部落格https://blog.csdn.net/yangdashi888/article/details/80385041

裡面的描述還是很詳細的。采集的方法有了,但是資料方面也是很重要的,為此,我寫了一個QT的應用程式來進行資料采集的工作。` string writePath = “E:/Trainslation/img/”;

VideoCapture capture(1);

string name;

Mat Gray,outs;

int i = 939 ;

Rect rect(0,0,300,300);

capture.set(CAP_PROP_FRAME_WIDTH, 540.0);

//設定攝像頭采集圖像分辨率

capture.set(CAP_PROP_FRAME_HEIGHT, 680.0);

while(1){

Mat frame;

capture>>frame;

if(32==waitKey(20))

{

name = writePath + to_string(i)+".jpg";

outs = Mat(frame,rect);

cvtColor(outs,Gray,COLOR_BGR2GRAY);

imwrite(name,frame);

cout<<name<<endl;

i++;

}

if (97 == waitKey(10)) { //'a’退出

break;

}

rectangle(frame,rect,Scalar(125,125,125),3,LINE_8,0);

imshow(“hello”,frame);

//imshow(“GRAY”,Gray);

}

運作結果圖:

基于OpenCV級聯分類器的人臉檢測項目場景:正樣本準備:負樣本準備:分類器樣本制作:opencv配置:vec檔案擷取:開始訓練:結果驗證:總結

方框裡面的就是圖像采集區域,可以通過修改Rect參數來控制範圍,通過按下空格進行拍照,講目标圖檔存入指定的位置。

基于OpenCV級聯分類器的人臉檢測項目場景:正樣本準備:負樣本準備:分類器樣本制作:opencv配置:vec檔案擷取:開始訓練:結果驗證:總結

通過對實驗室的國小弟進行友好互動,得到了近500張人臉的樣本,因為對正樣本的要求是要灰階圖檔,是以在采集的時候做了灰階轉換處理。

cvtColor(outs,Gray,COLOR_BGR2GRAY);//灰階轉換

負樣本準備:

對于負樣本的要求很簡單的,隻需要不包含正樣本的照片就可以的了,當然負樣本數量跟正樣本數量的比例約為3:1。

從網上找了一些圖檔,還有就是使用上面的素材采樣程式,通過加大開窗,以及取消灰階轉換,得到了近1500張的負樣本素材。

基于OpenCV級聯分類器的人臉檢測項目場景:正樣本準備:負樣本準備:分類器樣本制作:opencv配置:vec檔案擷取:開始訓練:結果驗證:總結

分類器樣本制作:

制作方法很簡單,首先就是在采集到的圖像的路徑下面通過記事本建立一個.txt檔案。輸入以下内容:

dir /b/s/p/w *.jpg > positives.txt

這個正樣本使用相對路徑即可,打開記事本講路徑進行替換

face\0.jpg 1 0 0 100 100

保留為前面的face\即可,後面的.jpg替換為.jpg 1 0 0 100 100

注意後面的100 100 是圖檔的長度和寬度,這個根據需求自行改變

最後将生産的txt檔案字尾改為.bat格式。然後将這個檔案剪切到上一級路徑上。

同理,負樣本也是可以通過這種方法來進行制作,但是.jpg 後面的内容是可以省略的。

opencv配置:

在正式訓練之前我們需要将opencv路徑下的一些檔案進行拷貝。

E:\opencv3.4\opencv\build\x64\vc15\bin

上面的是我的opencv安裝位置,然後将其下的

基于OpenCV級聯分類器的人臉檢測項目場景:正樣本準備:負樣本準備:分類器樣本制作:opencv配置:vec檔案擷取:開始訓練:結果驗證:總結

這幾個檔案拷貝到需要訓練的位置,注意裡面的.dll檔案不能忘記哦。至此,我們的準備工作已經齊全了。

接下來要做的就是進行分類訓練了。

vec檔案擷取:

使用快捷鍵win+R輸入cmd:

然後進入目标位置,也就是自己訓練的位置。

基于OpenCV級聯分類器的人臉檢測項目場景:正樣本準備:負樣本準備:分類器樣本制作:opencv配置:vec檔案擷取:開始訓練:結果驗證:總結

然後使用opencv_createsamples.exe

基于OpenCV級聯分類器的人臉檢測項目場景:正樣本準備:負樣本準備:分類器樣本制作:opencv配置:vec檔案擷取:開始訓練:結果驗證:總結

這個是該應用程式的參數,隻需要按照自己的需求進行調整即可。

opencv_createsam

plesd.exe -info E:\image\face\positive\info.dat -vec E:\image\face\sample_310.ve

c -num 760 -bgcolor 0 -bgthresh 0 -w 24 -h 24

最終會得到一個vec檔案。

提示:這裡可以添加要學的内容

例如:

1、 搭建 Java 開發環境

2、 掌握 Java 基本文法

3、 掌握條件語句

4、 掌握循環語句

開始訓練:

opencv_traincascaded.exe -data E:\image\face -vec E:\image\face\sample_310.vec -bg bg.txt -numPos 500-numNeg 1500 -numStages 12 -featureType LBP -w 24 -h 24 -minHitRate 0.995 -maxFalseAlarmRate 0.5

基于OpenCV級聯分類器的人臉檢測項目場景:正樣本準備:負樣本準備:分類器樣本制作:opencv配置:vec檔案擷取:開始訓練:結果驗證:總結

這個是一些參數,可以根據自己的需要進行調整。

最終訓練結束會得到一個xml檔案,接下來我們就用用這個檔案去做驗證了。

ui->setupUi(this);
    VideoCapture capture(0);
//    capture.set(CAP_PROP_FRAME_WIDTH, 540.0);//設定攝像頭采集圖像分辨率
//    capture.set(CAP_PROP_FRAME_HEIGHT, 680.0);
    String fileName = "E://Trainslation//xml3//cascade.xml";
    //Mat img = imread("C:/Users/HS/Desktop/test.jpg");
    CascadeClassifier left_classifier;
    if (!left_classifier.load(fileName)) {
            printf("could not load face feature data...\n");
     }
     Mat Gary,outs;
     vector<Rect> left;
    //cvtColor(img,Gary,COLOR_BGR2GRAY);
    //equalizeHist(Gary,Gary);
//    left_classifier.detectMultiScale(Gary,left,1.1,3,0| cv::CASCADE_SCALE_IMAGE,Size(20,20));
//    for(size_t t= 0 ; t<left.size();t++)
//            {
//                rectangle(img,left[static_cast<int>(t)],Scalar(0,0,255),2,8,0);
//            }
//    imshow( "output",img);

    while(1)
    {
        Mat frame;
       capture>>frame;
       cvtColor(frame,Gary,COLOR_BGR2GRAY);
       equalizeHist(Gary,Gary);
       left_classifier.detectMultiScale(Gary,left,1.1,3,0,Size(40,40));
       waitKey(100);
       for(size_t t= 0 ; t<left.size();t++)
       {
           rectangle(frame,left[static_cast<int>(t)],Scalar(0,0,255),2,8,0);
       }
       imshow("The src imput img",frame);
        waitKey(40);
     }
           

結果驗證:

基于OpenCV級聯分類器的人臉檢測項目場景:正樣本準備:負樣本準備:分類器樣本制作:opencv配置:vec檔案擷取:開始訓練:結果驗證:總結

還是可以成果找到自己的,效果還是欠佳,多訓練幾次,加大訓練量效果會更好的。

總結

通過一段時間對于opencv的學習,感覺opencv的應用還是很不錯的,在于圖像處理方面擁有這極好的應用。想起來之前動手做攝像頭循迹小車的時候。當時用的是ov2640做的圖像處理,裡面要對每一幀圖像的每一個像素點做一個判斷,最終也就做出來一個黑白二值化的結果,如今應用opencv可以輕松做到這些個,自己學習的道路還是很長,也希望跟志同道合的朋友一起鑽研項目,一起成長。

繼續閱讀