【SVM理论到实践3】OpenCv中自带的两个例子:线性可分和线性不可分代码解读
2017-03-03 22:44
537 查看
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/ml/ml.hpp> using namespace cv; int main() { //【1】创建可视化的窗口 int width = 512; int height = 512; cv::Mat image = Mat::zeros(height, width, CV_8UC3); //【2】设置训练数据 float labels[4] = {1.0, -1.0, -1.0, -1.0}; cv::Mat labelsMat(4, 1, CV_32FC1, labels); //[0]构造了一个列向量的矩阵头 float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} }; cv::Mat trainingDataMat(4, 2, CV_32FC1, trainingData); //[1]构造一个执行数组trainingData的矩阵头 //【3】设置支持向量机的参数 CvSVMParams params; params.svm_type = CvSVM::C_SVC; //[2]SVM的类型 params.kernel_type = CvSVM::LINEAR; //[3]核函数的类型::线性 params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6); //[4]终止准则函数,当迭代到最大值时,终止迭代 //【4】训练SVM CvSVM SVM; //[5]实例化一个SVM类的实例 SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params); //[6]参数为:输入数据,响应,xx,xx,SVM的参数 cv::Vec3b green(0,255,0); //[7]Vec3b这是一个3维的列向量,可以存储3个字符型数据 cv::Vec3b blue (255,0,0); //【5】显示由SVM决定的区域 for (int i = 0; i < image.rows; ++i) for (int j = 0; j < image.cols; ++j) { Mat sampleMat = (Mat_<float>(1,2) << i,j); float response = SVM.predict(sampleMat); //[8]predict()函数是用来做预测的,输入参数为样本,返回值为1或者-1 if (response == 1) image.at<Vec3b>(j, i) = green; else if (response == -1) image.at<Vec3b>(j, i) = blue; } //【6】画出训练数据 int thickness = -1; int lineType = 8; circle( image, Point(501, 10), 5, Scalar( 0, 0, 0), thickness, lineType); circle( image, Point(255, 10), 5, Scalar(255, 255, 255), thickness, lineType); circle( image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType); circle( image, Point( 10, 501), 5, Scalar(255, 255, 255), thickness, lineType); //【7】显示支持向量 thickness = 2; lineType = 8; int c = SVM.get_support_vector_count(); std::cout<<"支持向量的个数为 = "<<c<<std::endl; for(int i = 0; i < c; ++i) { const float* v = SVM.get_support_vector(i); circle( image,Point( (int) v[0], (int) v[1]),6,Scalar(128, 128, 128), thickness, lineType); } imwrite("result.png", image); // save the image imshow("SVM Simple Example", image); // show it to the user waitKey(0); }
/***************************************************************************************************** 程序功能: SVM线性不可分的情况示例程序解读 程序说明: 1)本训练程序中,一共有两类样本,是一个基于SVM的二分类问题;其中每类样本集的数量为100个样本,其 中90个样本是线性可分的,10个是线性不可分的 2)这200个样本的具体数据存储在trainData内;trainData是一个200行2列的矩阵,其中第一列存储的样本是 X值;第二列存储的样本是Y值;每一列的前90个元素是第一类线性可分的部分,后90个元素是第二类 线性可分的部分,中间的20个元素是线性不可分的部分。 开发环境: VS2012 + OpenGl(GLUT3.7) + OpenCv2.4.9 + Halcon10.0 时间地点: 陕西师范大学----2017.3.2 作 者: 九月 *****************************************************************************************************/ #include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/ml/ml.hpp> #define NTRAINING_SAMPLES 100 //[1]每个样本集的数量 #define FRAC_LINEAR_SEP 0.9f //[2]其中线性可分的部分 using namespace cv; using namespace std; int main() { //【1】创建一个可视化的图像 const int WIDTH = 512; const int HEIGHT = 512; cv::Mat I = Mat::zeros(HEIGHT, WIDTH, CV_8UC3); //[3]Matlab风格的矩阵的初始化 Mat trainData(2*NTRAINING_SAMPLES, 2, CV_32FC1); //[4]训练样本数据的存储矩阵 Mat labels (2*NTRAINING_SAMPLES, 1, CV_32FC1); //[5]训练样本类别的存储矩阵 RNG rng(100); //[6]设定随机数的种子 //[7]设定线性可分部分的训练数据量 int nLinearSamples = (int) (FRAC_LINEAR_SEP * NTRAINING_SAMPLES); //【2】设定第一类中的数据 Mat trainClass = trainData.rowRange(0, nLinearSamples);//[8]从整个数据取出[0,89]行的数据 Mat c = trainClass.colRange(0, 1); //[9]取出第一列 //[10]随机生成X的值:[0,0.4*WIDTH] rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(0.4 * WIDTH)); c = trainClass.colRange(1,2); //[11]取出第二列 rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT)); //[12]随机生成Y的值 //【3】设定第二类中的数据 //[13]从整个数据中取出[110,199]行 trainClass = trainData.rowRange(2*NTRAINING_SAMPLES-nLinearSamples, 2*NTRAINING_SAMPLES); c = trainClass.colRange(0 , 1); //[14]取出第一列 //[15]随机生成X的值[0.6*WIDTH,WIDTH] rng.fill(c, RNG::UNIFORM, Scalar(0.6*WIDTH), Scalar(WIDTH)); //[16]取出第二列 c = trainClass.colRange(1,2); rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT)); //[17]随机生成Y的值 //【4】线性不可分的数据 trainClass = trainData.rowRange( nLinearSamples, 2*NTRAINING_SAMPLES-nLinearSamples); c = trainClass.colRange(0,1); rng.fill(c, RNG::UNIFORM, Scalar(0.4*WIDTH), Scalar(0.6*WIDTH)); c = trainClass.colRange(1,2); rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT)); //【5】为所有数据设置标签: //1)前100个为第一类数据 //2)后100个为第二类数据 labels.rowRange( 0, NTRAINING_SAMPLES).setTo(1); // Class 1 labels.rowRange(NTRAINING_SAMPLES, 2*NTRAINING_SAMPLES).setTo(2); // Class 2 //【6】设置支持向量机SVM的参数 CvSVMParams params; params.svm_type = SVM::C_SVC; params.C = 0.1; params.kernel_type = SVM::LINEAR; params.term_crit = TermCriteria(CV_TERMCRIT_ITER, (int)1e7, 1e-6); //【7】训练SVM std::cout << "Starting training process" << endl; CvSVM svm; svm.train(trainData, labels, Mat(), Mat(), params); std::cout << "Finished training process" << endl; //【8】显示判决区域 cv::Vec3b green(0,100,0); cv::Vec3d blue (100,0,0); for (int i = 0; i < I.rows; ++i) for (int j = 0; j < I.cols; ++j) { Mat sampleMat = (Mat_<float>(1,2) << i, j); float response = svm.predict(sampleMat); //[1]判决函数 if (response == 1) I.at<Vec3b>(j, i) = green; //[2]第一类 else if (response == 2) I.at<Vec3b>(j, i) = blue; //[3]第二类 } //【9】显示训练数据 int thick = -1; int lineType = 8; float px; float py; // Class 1 for (int i = 0; i < NTRAINING_SAMPLES; ++i) { px = trainData.at<float>(i,0); py = trainData.at<float>(i,1); circle(I, Point( (int) px, (int) py ), 3, Scalar(0, 255, 0), thick, lineType); } // Class 2 for (int i = NTRAINING_SAMPLES; i <2*NTRAINING_SAMPLES; ++i) { px = trainData.at<float>(i,0); py = trainData.at<float>(i,1); circle(I, Point( (int) px, (int) py ), 3, Scalar(255, 0, 0), thick, lineType); } //【10】显示支持向量点 thick = 2; lineType = 8; int x = svm.get_support_vector_count(); for (int i = 0; i < x; ++i) { const float* v = svm.get_support_vector(i); circle( I, Point( (int) v[0], (int) v[1]), 6, Scalar(128, 128, 128), thick, lineType); } imwrite("result.png", I); // save the Image imshow("SVM for Non-Linear Training Data", I); // show it to the user waitKey(0); }
相关文章推荐
- 【OpenCV2.4】SVM处理线性不可分的例子
- 【SVM理论到实践2】OpenCv中的支持向量机SVM源代码的解读
- OpenCV 2.x + SVM线性不可分处理
- svm从理论到opencv实践
- OpenCV 2.4+ C++ SVM线性不可分处理
- OpenCV 2.4+ C++ SVM线性不可分处理
- (OpenCV)SVM:从理论到OpenCV实践
- SVM:从理论到OpenCV实践
- [置顶] SVM:从理论到OpenCV实践
- OpenCV之ml 模块. 机器学习:支持向量机(SVM)介绍 支持向量机对线性不可分数据的处理
- SVM:从理论到OpenCV实践
- OPENCV SVM介绍和自带例子
- 【SVM理论到实践4】基于OpenCv中的SVM的手写体数字识别
- SVM理论与OpenCV实践
- OpenCV支持向量机SVM对线性不可分数据的处理
- SVM通俗原理与OpenCV应用例子代码分析
- opencv3.0机器学习之SVM使用(多类线性不可分)
- Opencv自带的SVM
- opencv下自带例子总结
- 怎么用java代码写一个线性布局;布局里面有两个按钮是水平的