1. 程式人生 > >分類器的訓練進行目標識別,以車輛識別為例

分類器的訓練進行目標識別,以車輛識別為例

一、從網路上下載或者自己找到的圖片中裁剪挑選出合適的圖片。圖片的大小和格式都要相同,準備好兩個資料夾,分別命名為posdata(正樣本)和negdata(負樣本),所有樣本的尺寸必須一致,如果不一致的或者尺寸較大的,可以先將所有樣本統一縮放到100*40。posdata中的圖片為車輛樣本。給分類器展示的是正確的樣本。

negdata中的圖片為一些背景樣本,裡面不包含車輛,是用來告訴分類器哪些是錯誤的樣本。雖然負樣本就是樣本中不存在正樣本的內容,但最好是根據不同的專案選擇不同的負樣本,比如一個專案是做機場的人臉檢測,那麼就最好從現場拍攝一些圖片資料回來,從中採集負樣本。 

二、在negdata和posdata資料夾準備好之後,使用命令提示符(win + r),輸入cmd,把位置切換到posdata資料夾的位置。

然後在裡面輸入“ dir /b/s/p/w *.jpg > pos.txt ”,將會在posdata資料夾中產生一個pos.txt的文件。開啟pos.txt,選擇編輯-替換,在查詢中搜索jpg,替換為jpg 1 0 0 100 40,之後儲存,將pos.txt複製到上一級目錄中。

 之後對negdata資料夾進行相同的操作,在cmd中輸入的語句為“ dir /b/s/p/w *.jpg > neg.txt ”。

三、找到自己下載的OpenCV資料夾,開啟opencv,開啟build,開啟x64,開啟vc14,開啟bin資料夾。

選擇opencv_createsamples.exe和opencv_traincascade.exe兩項,將其複製到需要的資料夾中,與negdata、posdata並列。 

四、開啟cmd,在該檔案目錄下輸入“ opencv_createsamples.exe -vec pos.vec -info pos.txt -num 32 -w 100 -h 40 ” 。

        pos.txt 表明這是正樣本;

        num 32 代表正樣本照片數量;

       w 100  h40表示圖片解析度(寬和高)

之後在該資料夾中會出現pos.vec

之後重複該步驟,cmd輸入的語句換為“ opencv_createsamples.exe -vec neg.vec -info neg.txt -num 100 -w 100 -h 40 ”,產生neg.vec。

五、在主資料夾下建立一個txt文件,命名為“traincascade”,在該txt中輸入“ 

opencv_traincascade.exe -data xml -vec pos.vec -bg neg.txt -numPos 32 -numNeg 100 -numStages 20 -w 100 -h 40 -mode ALL

pause

numPos 32 代表正樣本照片數量   numNeg100 表示負樣本照片數量     numStage 20表示檢測次數   pause為暫停

對“traincascade.txt”進行重新命名,將字尾名改為bat。

 之後雙擊“traincascade.bat”。會產生如下效果

 訓練分類器時佔用CPU空間多,電腦執行將會變卡,處理時間較長。處理完成之後將會在資料夾下生成一個cascade.xml。

六、 之後可以執行VS,新建一個VC++專案。輸入一下程式碼之後進行測試。

程式碼為:

#include<opencv2\opencv.hpp> #include<iostream>

using namespace cv; using namespace std;

String filename = "F:/車輛樣本2/cascade.xml";  //之前cascade.xml放置的位置 CascadeClassifier car_classifier;

int main(int argc, char**argv) {     if (!car_classifier.load(filename))     {         printf("could not laod car feature data..\n");         return -1;     }

    Mat src = imread("D:/圖片/15.jpg"); //需要檢測的圖片     if (src.empty())     {         printf("could not laod image...\n");         return -1;     }     imshow("inupt image", src);     Mat gray;     cvtColor(src, gray, COLOR_BGR2GRAY);     equalizeHist(gray, gray);

    vector<Rect>cars;     car_classifier.detectMultiScale(gray, cars, 1.1, 3, 0, Size(50, 50));     for (size_t t = 0; t < cars.size(); t++)     {         rectangle(src, cars[static_cast<int>(t)], Scalar(0, 0, 255), 2, 8, 0);     }

    imshow("detect cars", src);     waitKey(0);     return 0;

}

 之後點選執行,因為設定的正負樣本過少的原因,效果不是很明顯。出現效果如下: