OpenCv学习笔记--支持向量机SVM线性可分情况下的OpenCv实现的超详细注释(2)

/*********************************************************************************************
程序功能:
        OpenCv2.4.8之机器学习模块---(1)支持向量机SVM-----线性可分情况下的SVM
编写环境:
        OpenCv2.4.8+VS2010
地点时间:
        陕西师范大学 2016.4.23
作者信息:
        九月
**********************************************************************************************/
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/ml/ml.hpp>

using namespace std;
using namespace cv;

int main()
{
	//【1】定义要创建的图像的宽和高
	int width =512;
	int height=512;
	//【2】创建一个指定大小的8位无符号整形的3通道RGB图像
	Mat img=Mat::zeros(height,width,CV_8UC3);
	//【3】显示创建的这个原始图片
	imshow("【1】创建的原始图片",img);
	
	
	
	//【4】设置训练的数据
	float labels[4]={1.0,-1.0,-1.0,-1.0};
	//【5】此块,创建了一个高度为3,宽度为1的32位浮点型,单通道的图像,
	Mat labelsMat(3,1,CV_32FC1,labels);

	float trainingData[4][2]={{501,10},{255,10},{501,255},{10,501}};
	Mat trainingDataMat(3,2,CV_32FC1,trainingData);

	//【6】设置支持向量机的参数
	//【7】定义一个支持向量机参数类CvSVMParams的类对象
	CvSVMParams params;
	//【8】SVM的类型,SVM的类型有(C_SVC=分类器, NU_SVC; ONE_CLASS=但分类器, EPS_SVR=回归, NU_SVR)
	params.svm_type=CvSVM::C_SVC;
	//【9】核函数类型为LINEAR---线性类型,不需要映射
	params.kernel_type=CvSVM::LINEAR;
	//【10】迭代训练过程中的终止
	//【11】最大迭代次数100,所要达到的精确度1e-6,达到最大迭代次数之后,终止迭代
	params.term_crit=cvTermCriteria(CV_TERMCRIT_ITER,100,1e-6);
	

	//【12】训练这个支持向量机SVM
	CvSVM SVM;
	//【13】训练模型,参数为:练习数据(输入数据),响应数据,指定爱好的特点,指定爱好的样本,SVM的参数
	        //【1】练习数据(输入数据),必须是CV_32FC1(32位浮点类型,单通道),数据必须是CV_ROW_SAMPLE,即特征点向量以行来存储
	        //【2】响应数据,凡是一维向量都存储在CV_32FC1(仅仅用在分类题目上)或者CV_32SC1的格局中
	SVM.train(trainingDataMat,labelsMat,Mat(),Mat(),params);
	//【14】Vec3b--向量模板类---的一个实例化的---具体类
	//【15】类Vec3b--在这块实例化了两个对象,green,blue--每一个对象表示---在这个对象中可以存储3个char字符型的数据--正好是RGB
	        //图像中的---一个像素点
	Vec3b green(0,255,0);
	Vec3b blue(255,0,0);
	//【16】显示由SVM给定的判定域
	for(int i=0;i<img.rows;++i)
		for(int j=0;j<img.cols;++j)
		{
			Mat sampleMat=(Mat_<float>(1,2)<<i,j);
			float response=SVM.predict(sampleMat);
			if(response==1)
				img.at<Vec3b>(j,i)=green;
			else if(response==-1)
				img.at<Vec3b>(j,i)=blue;
		}
	//【17】显示训练数据
		int thickness=-1;
		int lineType=8;
		circle(img,Point(501,10), 5,Scalar(0,  0,   0),thickness,lineType);
		circle(img,Point(255,10), 5,Scalar(255,255,255),thickness,lineType);
		circle(img,Point(501,255),5,Scalar(255,255,255),thickness,lineType);
		circle(img,Point(10,501), 5,Scalar(255,255,255),thickness,lineType);
	//【18】显示支持向量
		thickness=2;
		lineType=8;
	//【19】得到支持向量的个数
		int c   =SVM.get_support_vector_count();
	cout<<"-----------【支持向量的个数为】---------------"<<c<<endl;
	for(int i=0;i<c;++i)
	{
		const float* v=SVM.get_support_vector(i);
		circle(img,Point((int)v[0],(int)v[1]),6,Scalar(128,128,128),thickness,lineType);
	}
	//【20】保存这张图片
	imwrite("result.png",img);
	imshow("SVM样本的示例",img);
	waitKey(0);
	return 0;
}

你可能感兴趣的:(OpenCv学习笔记--支持向量机SVM线性可分情况下的OpenCv实现的超详细注释(2))