SVM多分類器的實現(Opencv3,C++)

朱銘德發表於2016-12-13

之前說要用SVM實現表情識別來著,所以找個簡單例子練練手。


慣例開始放結果,實現結果如下:

//這裡簡單對四個點分了四類,圖片顯示得很直觀。

//支援向量總共6個。

//最後測試了兩個點進行分類。



只需要配置好Opencv3的環境即可執行。

這裡用到的是cv::SVM, 老版本Opencv2410之前用的是CvSvm,推薦用最新的Opencv310。


配置環境連結:

//程式碼的備註自我感覺寫得挺多啦

下面就是簡單粗暴的程式碼啦:

#include<opencv2\opencv.hpp> 

using namespace std;
using namespace cv;
using namespace cv::ml;

int main()
{


	//訓練需要用到的資料
	int 標籤[4] = { 1, 2, 3, 4 };
	float 訓練資料[4][2] = { { 31, 12 },{ 65, 220 },{ 440, 350 },{ 400, 400 } };
	//轉為Mat以呼叫
	Mat 訓練Mat(4, 2, CV_32FC1, 訓練資料);
	Mat 標籤label(4, 1, CV_32SC1, 標籤);
	//訓練的初始化
	Ptr<SVM> svm = SVM::create();
	svm->setType(SVM::C_SVC);
	svm->setKernel(SVM::LINEAR);
	svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));
	//開始訓練
	svm->train(訓練Mat, ROW_SAMPLE, 標籤label);

	//-----------無關緊要的美工的部分-----------------------	
	//----其實對每個畫素點的座標也進行了分類----------------
	int 寬 = 512, 高 = 512;
	Mat 演示圖片 = Mat::zeros(高, 寬, CV_8UC3);
	Vec3b green(0, 255, 0), blue(255, 0, 0), red(0, 0, 255), black(0, 0, 0);
	for (int i = 0; i < 演示圖片.rows; ++i)
		for (int j = 0; j < 演示圖片.cols; ++j)
		{
			Mat sampleMat = (Mat_<float>(1, 2) << j, i);
			float response = svm->predict(sampleMat);

			if (response == 1)
				演示圖片.at<Vec3b>(i, j) = green;
			else if (response == 2)
				演示圖片.at<Vec3b>(i, j) = blue;
			else if (response == 3)
				演示圖片.at<Vec3b>(i, j) = red;
			else if (response == 4)
				演示圖片.at<Vec3b>(i, j) = black;
		}
	//--------把初始化訓練的點畫進圖片------------
	int thickness = -1;
	int lineType = 8;
	for (int 畫點 = 0; 畫點 < sizeof(標籤) / sizeof(int); 畫點++) {
		circle(演示圖片, Point(訓練資料[畫點][0], 訓練資料[畫點][1]), 10, Scalar(255, 255, 255), thickness, -1);
	}
	// 把 support vectors  cout粗來看看……
	Mat sv = svm->getSupportVectors();
	cout << "Support Vectors為:" << endl;
	for (int i = 0; i < sv.rows; ++i)
	{
		const float* v = sv.ptr<float>(i);
		cout << v[0] << " " << v[1] << endl;
	}

	//測試測試

	Mat 結果;
	float teatData[2][2] = { { 20, 11 },{ 310, 411 } };
	Mat query(2, 2, CV_32FC1, teatData);

	svm->predict(query, 結果);
	cout << "分類結果為:" << endl;
	cout << 結果;
	imshow("SVM顯示", 演示圖片);
	waitKey(-1);

}

祝大家使用分類器愉快咯,有問題歡迎留言交流哈~



相關文章