1. 程式人生 > >【機器學習--SVM+Hog特徵描述進行影象分類】

【機器學習--SVM+Hog特徵描述進行影象分類】

Hog特徵描述子作為深度學習之前比較火的人工特徵描述子,往往和svm結合應用於行人檢測等分類領域,在機器學習中仍具有比較好的應用。


具體在opencv使用步驟如下:

  1. Hog特徵的資料集與標籤資料集製作處理。
  2. 訓練svm分類器
  3. 載入分類器進行預測

手寫數字的識別是在很多領域常常遇見的情況,雖然簡單但是不可或缺,也適合將整個處理過程進行統一學習。具體程式碼如下:


#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

https://www.cnblogs.com/denny402/p/5032839.html

https://www.cnblogs.com/cheermyang/p/5624333.html