支持向量机SVM之处理线性不可分数据



//--------------------------------------【程序说明】-------------------------------------------

// 程序描述:来自OpenCV安装目录下Samples文件夹中的官方示例程序-支持向量机SVM之处理线性不可分数据
// 测试所用操作系统: Windows 7 64bit
// 测试所用IDE版本:Visual Studio 2010
// 开发测试所用OpenCV版本: 3.0 beta

//------------------------------------------------------------------------------------------------



//QQ:1746430162

//http://bbs.21ic.com/icview-759778-1-1.html (项目展示链接)

//  本工作室是专业电子类设计开发团队,团队成员全为从事51\DSP\ ARM\fpga类嵌入式开发和图像处理、机器学习等相关算法研究多年的软、硬件开发工程师,已与全国几十家客户成功合作。 可以长期提供技术支持,承接各类相关项目开发与咨询服务。


//------------------------------------------------------------------------------------------------


//---------------------------------【头文件、命名空间包含部分】----------------------------
// 描述:包含程序所使用的头文件和命名空间
//------------------------------------------------------------------------------------------------
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>


//OpenCV3需额外加入:
#include <opencv2/imgproc.hpp>
#include "opencv2/imgcodecs.hpp"
using namespace cv::ml;


#define NTRAINING_SAMPLES   100         // 每类训练样本的数量
#define FRAC_LINEAR_SEP     0.9f        //  部分(Fraction)线性可分的样本组成部分


using namespace cv;
using namespace std;








//-----------------------------------【ShowHelpText( )函数】----------------------------------
//          描述:输出一些帮助信息
//----------------------------------------------------------------------------------------------
void ShowHelpText()
{
//输出欢迎信息和OpenCV版本
printf("\n\n\t\t\t非常感谢购买《OpenCV3编程入门》一书!\n");
printf("\n\n\t\t\t此为本书OpenCV3版的第13个配套示例程序\n");
printf("\n\n\t\t\t   当前使用的OpenCV版本为:" CV_VERSION );
printf("\n\n  ----------------------------------------------------------------------------\n");
}


//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main()
{




//设置视觉表达的参数
const int WIDTH = 512, HEIGHT = 512;
Mat I = Mat::zeros(HEIGHT, WIDTH, CV_8UC3);


ShowHelpText();
//---------------------【1】随机建立训练数据---------------------------------------
Mat trainData(2*NTRAINING_SAMPLES, 2, CV_32FC1);
Mat labels   (2*NTRAINING_SAMPLES, 1, CV_32SC1);


RNG rng(100); // 随机生成值


//建立训练数据的线性可分的组成部分
int nLinearSamples = (int) (FRAC_LINEAR_SEP * NTRAINING_SAMPLES);


// 为Class1生成随机点
Mat trainClass = trainData.rowRange(0, nLinearSamples);
// 点的x坐标为[0,0.4)
Mat c = trainClass.colRange(0, 1);
rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(0.4 * WIDTH));
// 点的Y坐标为[0,1)
c = trainClass.colRange(1,2);
rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT));




// 为Class2生成随机点
trainClass = trainData.rowRange(2*NTRAINING_SAMPLES-nLinearSamples, 2*NTRAINING_SAMPLES);
// 点的x坐标为[0.6, 1]
c = trainClass.colRange(0 , 1);
rng.fill(c, RNG::UNIFORM, Scalar(0.6*WIDTH), Scalar(WIDTH));
// 点的Y坐标为[0, 1)
c = trainClass.colRange(1,2);
rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT));



//------------------建立训练数据的非线性可分组成部分 ---------------


// 随机生成Class1和Class2的点
trainClass = trainData.rowRange(  nLinearSamples, 2*NTRAINING_SAMPLES-nLinearSamples);
// 点的x坐标为[0.4, 0.6)
c = trainClass.colRange(0,1);
rng.fill(c, RNG::UNIFORM, Scalar(0.4*WIDTH), Scalar(0.6*WIDTH));
// 点的y坐标为[0, 1)
c = trainClass.colRange(1,2);
rng.fill(c, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT));


//------------------------- 为类设置标签 ---------------------------------
labels.rowRange(                0,   NTRAINING_SAMPLES).setTo(1);  // Class 1
labels.rowRange(NTRAINING_SAMPLES, 2*NTRAINING_SAMPLES).setTo(2);  // Class 2


//------------------------ 2. 设置支持向量机的参数 --------------------
SVM::Params params;
params.svmType    = SVM::C_SVC;
params.C   = 0.1;
params.kernelType = SVM::LINEAR;
params.termCrit   = TermCriteria(TermCriteria::MAX_ITER, (int)1e7, 1e-6);


//------------------------ 3. 训练支持向量机 ----------------------------------------------------
cout << "Starting training process" << endl;
Ptr<SVM> svm = StatModel::train<SVM>(trainData, ROW_SAMPLE, labels, params);
cout << "Finished training process" << endl;


//------------------------ 4. 标出决策区域(decision regions)----------------------------------------
Vec3b green(0,100,0), 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);


if      (response == 1)    I.at<Vec3b>(j, i)  = green;
else if (response == 2)    I.at<Vec3b>(j, i)  = blue;
}


//----------------------- 5. 显示训练数据(training data)--------------------------------------------
int thick = -1;
int lineType = 8;
float px, 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);
}


//------------------------- 6. 显示支持向量(support vectors)-------------------------------------------
thick = 2;
lineType  = 8;
Mat sv = svm->getSupportVectors();


for (int i = 0; i < sv.rows; ++i)
{
const float* v = sv.ptr<float>(i);
circle( I,  Point( (int) v[0], (int) v[1]), 6, Scalar(128, 128, 128), thick, lineType);
}


imwrite("result.png", I);                   //保存图像到文件
imshow("SVM for Non-Linear Training Data", I); // 显示最终窗口
waitKey(0);
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值