用初次训练的SVM+HOG分类器在负样本原图上检测HardExample
難例(或叫做難樣本,Hard Example,Hard Negative,Hard Instance)是指利用第一次訓練的分類器在負樣本原圖(肯定沒有人體)上進行行人檢測時所有檢測到的矩形框,這些矩形框區域很明顯都是誤報,把這些誤報的矩形框保存為圖片,加入到初始的負樣本集合中,重新進行SVM的訓練,可顯著減少誤報。這種方法叫做自舉法(Bootstrap),自舉法首先使用初始負樣本集來訓練一個模型,然后收集被這個初始模型錯誤分類的負樣本來形成一個負樣本難例集。用此負樣本難例集訓練新的模型,此過程可以重復多次。
比如典型的誤報如下:
上圖中將樹干誤認為是人體,這些就是Hard Example,將這些矩形框保存為64*128的圖片文件,加入到負樣本集合中。
也就是說,難例就是分錯類的負樣本,將難例加入負樣本集合進行二次訓練就是告訴分類器:“這些是你上次分錯類的,要吸取教訓,改正錯誤”
初次訓練SVM+HOG分類器見:自己訓練SVM分類器進行HOG行人檢測
Navneet Dalal在CVPR2005上的HOG原論文翻譯見:http://blog.csdn.net/masibuaa/article/details/14056807
#include <iostream> #include <fstream> #include <string> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/objdetect/objdetect.hpp> #include <opencv2/ml/ml.hpp>using namespace std; using namespace cv;int hardExampleCount = 0; //hard example計數int main() {Mat src;char saveName[256];//剪裁出來的hard example圖片的文件名string ImgName;ifstream fin_detector("HOGDetectorForOpenCV_2400PosINRIA_12000Neg.txt");//打開自己訓練的SVM檢測器文件ifstream fin_imgList("INRIANegativeImageList.txt");//打開原始負樣本圖片文件列表//ifstream fin_imgList("subset.txt");//從文件中讀入自己訓練的SVM參數float temp;vector<float> myDetector;//3781維的檢測器參數while(!fin_detector.eof()){fin_detector >> temp;myDetector.push_back(temp);//放入檢測器數組}cout<<"檢測子維數:"<<myDetector.size()<<endl;//namedWindow("src",0);HOGDescriptor hog;//HOG特征檢測器hog.setSVMDetector(myDetector);//設置檢測器參數為自己訓練的SVM參數//一行一行讀取文件列表while(getline(fin_imgList,ImgName)){cout<<"處理:"<<ImgName<<endl;string fullName = "D:\\DataSet\\INRIAPerson\\INRIAPerson\\Train\\neg\\" + ImgName;//加上路徑名src = imread(fullName);//讀取圖片Mat img = src.clone();//復制原圖vector<Rect> found;//矩形框數組//對負樣本原圖進行多尺度檢測,檢測出的都是誤報hog.detectMultiScale(src, found, 0, Size(8,8), Size(32,32), 1.05, 2);//遍歷從圖像中檢測出來的矩形框,得到hard examplefor(int i=0; i < found.size(); i++){//檢測出來的很多矩形框都超出了圖像邊界,將這些矩形框都強制規范在圖像邊界內部Rect r = found[i];if(r.x < 0)r.x = 0;if(r.y < 0)r.y = 0;if(r.x + r.width > src.cols)r.width = src.cols - r.x;if(r.y + r.height > src.rows)r.height = src.rows - r.y;//將矩形框保存為圖片,就是Hard ExampleMat hardExampleImg = src(r);//從原圖上截取矩形框大小的圖片resize(hardExampleImg,hardExampleImg,Size(64,128));//將剪裁出來的圖片縮放為64*128大小sprintf(saveName,"hardexample%09d.jpg",hardExampleCount++);//生成hard example圖片的文件名imwrite(saveName, hardExampleImg);//保存文件//畫矩形框,因為hog檢測出的矩形框比實際人體框要稍微大些,所以這里需要做一些調整//r.x += cvRound(r.width*0.1);//r.width = cvRound(r.width*0.8);//r.y += cvRound(r.height*0.07);//r.height = cvRound(r.height*0.8);rectangle(img, r.tl(), r.br(), Scalar(0,255,0), 3);}//imwrite(ImgName,img);//imshow("src",src);//waitKey(100);//注意:imshow之后一定要加waitKey,否則無法顯示圖像}system("pause"); }
源碼下載,環境為VS2010 + OpenCV2.4.4
http://download.csdn.net/detail/masikkk/6549325
from:?http://blog.csdn.net/masibuaa/article/details/16113373
總結
以上是生活随笔為你收集整理的用初次训练的SVM+HOG分类器在负样本原图上检测HardExample的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在windows下运行Felzenszw
- 下一篇: 用DPM(Deformable Part