【機器學習--SVM+Hog特徵描述進行影象分類】
阿新 • • 發佈:2018-11-05
Hog特徵描述子作為深度學習之前比較火的人工特徵描述子,往往和svm結合應用於行人檢測等分類領域,在機器學習中仍具有比較好的應用。
具體在opencv使用步驟如下:
- Hog特徵的資料集與標籤資料集製作處理。
- 訓練svm分類器
- 載入分類器進行預測
手寫數字的識別是在很多領域常常遇見的情況,雖然簡單但是不可或缺,也適合將整個處理過程進行統一學習。具體程式碼如下:
#include <iostream> #include <fstream> #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; using namespace cv::ml; int main(){ //winsize(64,128),blocksize(16,16),blockstep(8,8),cellsize(8,8),bins9 //檢測視窗(64,128),塊尺寸(16,16),塊步長(8,8),cell尺寸(8,8),直方圖bin個數9 HOGDescriptor hog(Size(128, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9); //HOG檢測器,用來計算HOG描述子的 int DescriptorDim;//HOG描述子的維數,由圖片大小、檢測視窗大小、塊大小、細胞單元中直方圖bin個數決定 Mat sampleFeatureMat;//所有訓練樣本的特徵向量組成的矩陣,行數等於所有樣本的個數,列數等於HOG描述子維數 Mat sampleLabelMat;//訓練樣本的類別向量,行數等於所有樣本的個數,列數等於1;1表示有人,-1表示無人 Ptr<SVM> svm = SVM::create();//SVM分類器 string ImgName;//圖片名(絕對路徑) ifstream fin("Image/img.txt");//正樣本圖片的檔名列表 if (!fin) { cout << "Pos/Neg imglist reading failed..." << endl; return -1; } for (int num = 0; num < 200 && getline(fin, ImgName); num++){ std::cout << "Now processing original positive image: " << ImgName << endl; ImgName = "Image/" + ImgName;//加上正樣本的路徑名 Mat src = imread(ImgName);//讀取圖片 //if (CENTRAL_CROP) // src = src(Rect(16, 16, 128, 128));//將96*160的INRIA正樣本圖片剪裁為64*128,即剪去上下左右各16個畫素 vector<float> descriptors;//HOG描述子向量 hog.compute(src, descriptors, Size(8, 8));//計算HOG描述子,檢測視窗移動步長(8,8) //處理第一個樣本時初始化特徵向量矩陣和類別矩陣,因為只有知道了特徵向量的維數才能初始化特徵向量矩陣 if (0 == num) { DescriptorDim = descriptors.size(); //初始化所有訓練樣本的特徵向量組成的矩陣,行數等於所有樣本的個數,列數等於HOG描述子維數sampleFeatureMat sampleFeatureMat = Mat::zeros(200, DescriptorDim, CV_32FC1); //初始化訓練樣本的類別向量,行數等於所有樣本的個數,列數等於1;1表示有人,0表示無人 sampleLabelMat = Mat::zeros(200, 1, CV_32SC1);//sampleLabelMat的資料型別必須為有符號整數型 } //將計算好的HOG描述子複製到樣本特徵矩陣sampleFeatureMat for (int i = 0; i<DescriptorDim; i++) sampleFeatureMat.at<float>(num, i) = descriptors[i];//第num個樣本的特徵向量中的第i個元素 sampleLabelMat.at<int>(num, 0) = num / 20;//正樣本類別為1,有人 } fin.close(); //輸出樣本的HOG特徵向量矩陣到檔案 svm->setType(SVM::C_SVC); svm->setC(0.01); svm->setKernel(SVM::LINEAR); svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 3000, 1e-6)); std::cout << "Starting training..." << endl; svm->train(sampleFeatureMat, ROW_SAMPLE, sampleLabelMat);//訓練分類器 std::cout << "Finishing training..." << endl; //將訓練好的SVM模型儲存為xml檔案 svm->SVM::save("SVM_HOG.xml"); //imshow("src", src); waitKey(); return 0; }
參考部落格:https://blog.csdn.net/jellyfish0507/article/details/80510713?utm_source=blogxgwz3