/********************************************************************************************* 程序功能: 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; }