1. 程式人生 > >opencv3.0函式呼叫,svm訓練分類器

opencv3.0函式呼叫,svm訓練分類器

#include <iostream>#include <fstream>#include <opencv2/opencv.hpp>#include <opencv2/ml/ml.hpp>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/objdetect/objdetect.hpp>#include <string>
#include <io.h>using namespace std;using namespace cv;using namespace cv::ml;#define PosSamNO 480    //正樣本個數   #define NegSamNO 3384  //負樣本個數   #define HardExampleNO //難例個數 int  main(int argc, char** argv){//HOG檢測器,用來計算HOG描述子的 //檢測視窗(48,48),塊尺寸(16,16),塊步長(8,8),cell尺寸(8,8),直方圖bin個數9   param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );
       cv::HOGDescriptor hog(cv::Size(64, 64), cv::Size(16, 16), cv::Size(16, 16), cv::Size(8, 8), 9);int DescriptorDim;//HOG描述子的維數,由圖片大小、檢測視窗大小、塊大小、細胞單元中直方圖bin個數決定  SVM::Params params;       params.svmType = SVM::C_SVC;       params.C = 0.1;       params.kernelType = SVM::LINEAR;//SVM::LINEAR;//SVM::LINEAR;
       params.termCrit = TermCriteria(TermCriteria::MAX_ITER, (int)10000, 1e-6);//正樣本圖片路徑檔案,具體通過圖片生成圖片路徑檔案的程式碼,在我上傳的資源裡面可以找到       std::ifstream finPos("E:/opencv_studydocumence/opencv_study/HOG+SVM/code/Release/labels_20180206/svm20180206_x.txt");//負樣本圖片的檔案列表        std::ifstream finNeg("E:/opencv_studydocumence/opencv_study/HOG+SVM/code/Release/labels_20180206/svmtrain_neg.txt");       std::string ImgName;//所有訓練樣本的特徵向量組成的矩陣,行數等於所有樣本的個數,列數等於HOG描述子維數         cv::Mat sampleFeatureMat;//訓練樣本的類別向量,行數等於所有樣本的個數,列數等於1;1表示有目標,-1表示無目標         cv::Mat sampleLabelMat;//依次讀取正樣本圖片,生成HOG描述子   for (int num = 0; num < PosSamNO && getline(finPos, ImgName); num++)       {              std::cout << "Processing:" << ImgName << std::endl;              std::cout << "1" << std::endl;              cv::Mat image = cv::imread(ImgName);//HOG描述子向量                std::vector<float> descriptors;//計算HOG描述子,檢測視窗移動步長(8,8)               hog.compute(image, descriptors, cv::Size(8, 8));//處理第一個樣本時初始化特徵向量矩陣和類別矩陣,因為只有知道了特徵向量的維數才能初始化特徵向量矩陣   if (0 == num)              {//HOG描述子的維數                       DescriptorDim = descriptors.size();//初始化所有訓練樣本的特徵向量組成的矩陣,行數等於所有樣本的個數,列數等於HOG描述子維數sampleFeatureMat                        sampleFeatureMat = cv::Mat::zeros(PosSamNO + NegSamNO + HardExampleNO, DescriptorDim, CV_32FC1);//初始化訓練樣本的類別向量,行數等於所有樣本的個數,列數等於1                       sampleLabelMat = cv::Mat::zeros(PosSamNO + NegSamNO + HardExampleNO, 1, CV_32SC1);              }//將計算好的HOG描述子複製到樣本特徵矩陣sampleFeatureMat   for (int i = 0; i < DescriptorDim; i++)              {//第num個樣本的特徵向量中的第i個元素                       sampleFeatureMat.at<float>(num, i) = descriptors[i];              }//正樣本類別為17,有目標                   sampleLabelMat.at<float>(num, 0) = 9;       }//依次讀取負樣本圖片,生成HOG描述子   for (int num = 0; num < NegSamNO && getline(finNeg, ImgName); num++)       {              std::cout << "-1"<< std::endl;              std::cout << "Processing:" << ImgName << std::endl;              cv::Mat src = cv::imread(ImgName);              cv::resize(src, src, cv::Size(64, 64));//HOG描述子向量               std::vector<float> descriptors;//計算HOG描述子,檢測視窗移動步長(8,8)                hog.compute(src, descriptors, cv::Size(8, 8));              std::cout << "descriptor dimention:" << descriptors.size() << std::endl;//將計算好的HOG描述子複製到樣本特徵矩陣sampleFeatureMat   for (int i = 0; i < DescriptorDim; i++)              {//第PosSamNO+num個樣本的特徵向量中的第i個元素                      sampleFeatureMat.at<float>(num + PosSamNO, i) = descriptors[i];              }//負樣本類別為-1,無目標               sampleLabelMat.at<float>(num + PosSamNO, 0) = -1;       }//處理HardExample負樣本   if (HardExampleNO > 0)       {//HardExample負樣本的檔案列表                std::ifstream finHardExample("svmtrain_hard.txt");//依次讀取HardExample負樣本圖片,生成HOG描述子   for (int num = 0; num < HardExampleNO && getline(finHardExample, ImgName); num++)              {                     std::cout << "2" << std::endl;                     std::cout << "Processing:" << ImgName << std::endl;                     cv::Mat src = cv::imread(ImgName, cv::IMREAD_GRAYSCALE);                     cv::resize(src, src, cv::Size(64, 64));//HOG描述子向量                        std::vector<float> descriptors;//計算HOG描述子,檢測視窗移動步長(8,8)                       hog.compute(src, descriptors, cv::Size(8, 8));//將計算好的HOG描述子複製到樣本特徵矩陣sampleFeatureMat   for (int i = 0; i < DescriptorDim; i++)                     {//第PosSamNO+num個樣本的特徵向量中的第i個元素                            sampleFeatureMat.at<float>(num + PosSamNO + NegSamNO, i) = descriptors[i];                     }//負樣本類別為-1,無目標                       sampleLabelMat.at<float>(num + PosSamNO + NegSamNO, 0) =2;              }       }//訓練SVM分類器   //迭代終止條件,當迭代滿1000次或誤差小於FLT_EPSILON時停止迭代          std::cout << "start training SVM" << std::endl;//cout << "Starting training process" << endl;Ptr<SVM> svm = StatModel::train<SVM>(sampleFeatureMat, ROW_SAMPLE, sampleLabelMat, params);       cout << "Finished training process" << endl;//訓練分類器   //svm->train(td);       std::cout << "訓練完成" << std::endl;//將訓練好的SVM模型儲存為xml檔案        svm->save("20180206_xmls/svmx_20180206.xml");return 0;}