opencv-訓練識別狗的分類器過程詳解

一、樣本準備

包括正樣本和負樣本,由於是手工準備的數據都是在百度截取的圖片,所以樣本不多。正樣本:100個,負樣本208個。
正樣本:都是狗的圖片,儘量選背景色單一的,由於我是百度出來的圖片沒那麼多講究。
負樣本:可以是其他的除了狗的圖片,我選了各種各樣動物的圖片。

二、訓練數據準備

(1)準備正樣本vec文件所需的info.dat文件,如下所示:

img/1-0001.png  1       0       0       114     114
img/1-0002.png  1       0       0       386     386
img/1-0003.png  1       0       0       321     321
img/1-0004.png  1       0       0       224     224
img/1-0005.png  1       0       0       212     212
img/1-0006.png  1       0       0       197     197

第一列是圖片路徑;
第二列是圖片中能檢測出的樣本表數量,由於訓練的目標是小狗,所以圖片中只有一隻狗。當然如果有兩隻就寫2;
第三第四列是圖像的座標,(0,0)就行;
第五第六列是圖像寬和高,需要注意是一樣的,寬高比需要一樣的。

(2)準備最終訓練的負樣本數據bg.txt,如下:

img/1-f001.png
img/1-f002.png
img/1-f003.png
img/1-f004.png
img/1-f005.png

這裏就不需要這麼講究了,路徑即可,圖像比例隨意因爲後面訓練的時候會切割的。

三、得到vec文件

使用opencv_createsamplesd.exe程序,安裝完opencv後在目錄:D:\ProgramFiles\opencv\build\install\x64\vc15\bin 可以根據自己的安裝情況來找。
執行:.\opencv_createsamplesd -info D:\source\cascadetrain\positive\info .dat -vec D:\source\cascadetrain\mysamples_344.vec -num 100 -bgcolor 0 -bgthresh 0 -w 24 -h 24即可得到vec文件。

PS D:\ProgramFiles\opencv\build\install\x64\vc15\bin> .\opencv_createsamplesd -info D:\source\cascadetrain\positive\info
.dat -vec D:\source\cascadetrain\mysamples_344.vec -num 100 -bgcolor 0 -bgthresh 0 -w 24 -h 24
Info file name: D:\source\cascadetrain\positive\info.dat
Img file name: (NULL)
Vec file name: D:\source\cascadetrain\mysamples_344.vec
BG  file name: (NULL)
Num: 100
BG color: 0
BG threshold: 0
Invert: FALSE
Max intensity deviation: 40
Max x angle: 1.1
Max y angle: 1.1
Max z angle: 0.5
Show samples: FALSE
Width: 24
Height: 24
Max Scale: -1
RNG Seed: 12345
Create training samples from images collection...
Done. Created 100 samples
PS D:\ProgramFiles\opencv\build\install\x64\vc15\bin>
PS D:\ProgramFiles\opencv\build\install\x64\vc15\bin>

注意根據自己的目錄來填寫真實目錄。

四、訓練最終的分類器

使用opencv_traincascaded.exe程序,安裝完opencv後在目錄:D:\ProgramFiles\opencv\build\install\x64\vc15\bin 可以根據自己的安裝情況來找。
訓練命令:
.\opencv_traincascaded -data D:\source\cascadetrain\haarresult -ve c D:\source\cascadetrain\mysamples_344.vec -bg bg.txt -numPos 85 -numNeg 400 -numStages 12 -featureType HARR -w 24 -h 24 -minHitRate 0.996 -maxFalseAlarmRate 0.5 -mode ALL

這裏說明一下,可以用LBP和HAAR兩種來訓練,但是HAAR訓練會久一點,但是精準度好一點;LBP訓練的快一點,但是識別度沒那麼好。我這裏使用了HAAR訓練。
在這裏插入圖片描述

但是在使用Haar訓練的時候,stage = 8(設置的是12)的時候突然不動,CPU降了下來,但是內存還佔用着,卡住了,如下圖:
在這裏插入圖片描述

但是在退出後再執行就能繼續了,不知道什麼原因。知道的小夥伴麻煩提示一下,謝謝。
在這裏插入圖片描述
至此訓練完成。得到訓練後的分類器:cascade.xml,可以看到和opencv自帶的分類有着相似的結構:

<?xml version="1.0"?>
<opencv_storage>
<cascade>
  <stageType>BOOST</stageType>
  <featureType>HAAR</featureType>
  <height>24</height>
  <width>24</width>
  <stageParams>
    <boostType>GAB</boostType>
    <minHitRate>9.9599999189376831e-01</minHitRate>
    <maxFalseAlarm>5.0000000000000000e-01</maxFalseAlarm>
    <weightTrimRate>9.4999999999999996e-01</weightTrimRate>
    <maxDepth>1</maxDepth>
    <maxWeakCount>100</maxWeakCount></stageParams>
  <featureParams>
    <maxCatCount>0</maxCatCount>
    <featSize>1</featSize>
    <mode>ALL</mode></featureParams>
  <stageNum>11</stageNum>
  <stages>
    <!-- stage 0 -->
    <_>
      <maxWeakCount>6</maxWeakCount>
      <stageThreshold>-1.5430381298065186e+00</stageThreshold>
      <weakClassifiers>

注意根據自己的目錄來填寫真實目錄。

五、參數解析

opencv_traincascaded,參數解析。

【-info】 就是跟存放正樣本圖片目錄位置相同的描述文件的路徑,可用txt,dat等格式保存,每一行的內容爲:xxx.jpg nums left_x left_y width heght。
比如:samples_1.jpg 1 0 0 20 20這樣,就是指某個正樣本是samples_1.jpg的圖片,圖片中有1個目標區域,區域的左上角座標爲(0,0),區域的寬度爲20像素,長度爲20像素。注意樣本圖片和這裏的參數相符。

【-img】如果你要通過一張圖片的扭曲形變成多張圖片作爲樣本,就填寫這個參數,參數的內容爲要扭曲的圖片的路徑。填入後,-info參數不再有效。

【-vec】要生成用於訓練的vec文件的路徑,內容爲:xxx/xxx/xxx/xxx.vec

【-bg】 如果省略,則使用bgcolor的值填充作爲背景。就是跟存放負樣本圖片(背景圖片)目錄位置相同的描述文件的路徑,可用txt,dat等格式保存,,每一行的內容爲:xxx.jpg。這裏要注意的是,不要填入圖片的完整路徑,不然會報錯。但訓練樣本opencv_traincascade也需要傳入一個-bg參數,但那個參數的描述文件每一行是要用完整路徑的,這有點怪。

【-num】要創建的樣本的數量,使用-info生成時,不要比你準備的正樣本圖片數量大就行了

【-bgcolor】這是創建樣本是樣本扭曲函數中用來決定像素是有效還是作爲背景過濾的基本值,因爲操作的是灰度圖,所以這個值0範圍是~255。

【-bgthresh】決定背景掩碼的實際取值範圍爲bgcolor-bgthresh ——bgcolor-bgthresh

【-inv】【-randinv】這是樣本生成時,是否需要反相或隨機反相,這個在車牌這樣的數字中就需要,比如說白底黑字的車牌和藍底白字的車牌,兩者生成的樣本是相反的,前者數字是黑色,後者數字是白色。所以這個參數按你實際需要使用吧。

【-maxidev】一個用於生成前景(有效像素區域)灰度值的常數值,實際樣本的前景灰度值會根據這個參數結合隨機數產生多種不同的灰度值。

【-maxxangle】對樣本圖片的x軸方向的扭曲的最大弧度,X軸即是圖片水平方向的旋轉。

【-maxyangle】對樣本圖片的y軸方向的扭曲的最大弧度,Y軸即是圖片豎直方向的旋轉。

【-maxyangle】對樣本圖片的z軸方向的扭曲的最大弧度,Z軸即是垂直於圖像平面的方向的旋轉(可理解爲旋轉軸是一條穿過顯示器的垂線)。

【-show】樣本創建期間,是否通過imshow顯示出每一個生成的樣本圖片出來。

【-w】要創建的樣本圖片的寬度,後面的訓練樣本步驟要使用和這時一樣的值,不然會報錯

【-h】要創建的樣本圖片的高度,後面的訓練樣本步驟要使用和這時一樣的值,不然會報錯

opencv_traincascaded,參數解析:

-data 
訓練的分類器的存儲目錄
-vec 
正樣本文件,由open_createsamples.exe生成,正樣本文件後綴名爲.vec
-bg 
負樣本說明文件,主要包含負樣本文件所在的目錄及負樣本文件名
-numPos 
每級分類器訓練時所用到的正樣本數目,應小於vec文件中正樣本的數目,具體數目限制條件爲:numPos+(numStages-1)*numPos*(1-minHitRate)<=vec文件中正樣本的數目
-numNeg 
每級分類器訓練時所用到的負樣本數目,可以大於-bg指定的圖片數目
-numStages 
訓練分類器的級數,強分類器的個數
-precalcValBufSize 
緩存大小,用於存儲預先計算的特徵值,單位MB
-precalcIdxBufSize 
緩存大小,用於存儲預先計算的特徵索引,單位MB
-baseFormatSave 
僅在使用Haar特徵時有效,如果指定,級聯分類器將以老格式存儲
-stageType
     級聯類型,目前只能取BOOST
-featureType
     訓練使用的特徵類型,目前支持的特徵有Haar,LBP和HOG
-w
     訓練的正樣本的寬度,Haar特徵的w和h一般爲20,LBP特徵的w和h一般爲24,HOG特徵的w和h一般爲64
-h
     訓練的正樣本的高
-bt
     訓練分類器採用的Adaboost類型,Adaboost分爲Getle Adaboost,Real Adaboost,Discrete Adaboost,Logit Adaboost,訓練中默認採用Getle Adaboost
-minHitRate
     影響每個強分類器閾值,每一級分類器最小命中率,表示每一級強分類器對正樣本的的分類準確率
-maxFalseAlarm
     最大虛警率,影響弱分類器的閾值,表示每個弱分類器將負樣本誤分爲正樣本的比例,一般默認值爲0.5
-weightTrimRate
     0-1之間的閾值,影響參與訓練的樣本,樣本權重更新排序後(從小到大),從前面累計權重小於(1-weightTrimRate)的樣本將不參與下一次訓練,一般默認值爲0.95
-maxDepth
     每一個弱分類器決策樹的深度,默認是1,是二叉樹(stumps),只使用一個特徵。
-maxWeakCount
     每級強分類器中弱分類器的最大個數,當FA降不到指定的maxFalseAlarm時可以通過指定最大弱分類器個數停止單個強分類器
- Haar特徵,CvHaarFeatureParams繼承於CvFeatureParams
    -mode 
       值爲BASIC、CORE、ALL三種,根據值不同採用不同的Haar特徵,BASIC是基本的Haar特徵(垂直),CORE是所有的上下Haar特徵,ALL是使用所有的Haar特徵(包括垂直和45度)
- LBP特徵,CvLBPFeatureParams繼承於CvFeatureParams
      無參數
- HOG特徵,CvHOGFeatureParams繼承於CvFeatureParams
       無參數

六、驗證識別效果代碼

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

String haarfile = "D:/source/cascadetrain/haarresult/cascade.xml";
String lbpfile = "D:/source/cascadetrain/cascade.xml";
CascadeClassifier g_haarFaceClassifier, g_lbpFaceClassifier;

int main()
{
	if (!g_haarFaceClassifier.load(haarfile))
	{
		printf("load classifier error\n");
		return -1;
	}

	Mat src, gray;
	src = imread("cat3.png");
	cvtColor(src, gray, COLOR_BGR2GRAY);
	equalizeHist(gray, gray);

	vector<Rect> faces;
	g_haarFaceClassifier.detectMultiScale(gray, faces, 1.1, 4, 0, Size(65, 65));
	for (int i = 0; i < faces.size(); i++)
	{
		rectangle(src, faces[i], Scalar(0, 0, 255), 2, 8, 0);
	}
	imshow("src", src);

	waitKey(0);
	return 0;
}

七、運行結果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章