有关于SVM的理论可以参考opencv_tutorials.pdf
译文可以参考博客:
http://blog.csdn.net/dwb1015/article/details/12841305
本文通过svm进行多类分类
源码如下:
//编程环境:VS2012 + Opencv2.4.9
#include <fstream>
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
#define COUNT 21 //读入的点个数
int main()
{
//从文件载入数据
float data[COUNT][2];
ifstream fin1("data.txt");
for(int i=0;i<COUNT;i++)
{
fin1>>data[i][0];
fin1>>data[i][1];
}
fin1.close();
//显示读入的数据
for(int i=0;i<COUNT;i++)
{
cout<<data[i][0]<<" ";
cout<<data[i][1]<<" "<<endl;
}
float label[COUNT][1];
ifstream fin2("label.txt");
for(int i=0;i<COUNT;i++)
{
fin2>>label[i][0];
}
fin2.close();
//显示读入的数据
for(int i=0;i<COUNT;i++)
{
cout<<label[i][0]<<" "<<endl;
}
Mat trainData(COUNT, 2, CV_32FC1, data);
Mat trainLabel(COUNT, 1, CV_32FC1, label);
cout<<"trainData"<<trainData<<endl;
cout<<"trainLabel"<<trainLabel<<endl;
CvSVM svm;
CvSVMParams param;
param.svm_type = CvSVM::C_SVC; //n(n>2)的分类器,其中参数C是异常惩罚因子,可以进行不完全分类
//param.svm_type = CvSVM::NU_SVC; //n(n>2)类似不完全分类的分类器,参数nu(nu属于[0,1]),取代了C_SVC类型的异常惩罚因子C;
//param.svm_type = CvSVM::ONE_CLASS; //单分类器,用一个分界线对特征空间进行分割。
param.kernel_type = CvSVM::LINEAR; //线性核函数,此核函数在分类是速度最快,分类将在原始空间中完成;
//param.kernel_type = CvSVM::POLY; //多项式核
//param.kernel_type = CvSVM::RBF; //径向基核,对于大部分情况都是选择此类型
//param.kernel_type = CvSVM::SIGMOID; //sigmoid核函数
param.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6); //SVM迭代终止条件,CV_TERMCRIT_ITER为终止条件类型,100为最大迭代次数,1e-6为结果的准确率
//训练SVM
svm.train(trainData, trainLabel, Mat(), Mat(), param);
Mat image = Mat::zeros(500, 500, CV_8UC3);
Vec3b green(0,255,0), blue(255,0,0), red(0,0,255),gray(125,125,125);
for (int i = 0; i < image.cols; i++)
{
for (int j = 0; j < image.rows; j++)
{
Mat sampleMat = (Mat_<float>(1,2) << i,j);
float response = svm.predict(sampleMat);
if(response == 3)
image.at<Vec3b>(j,i) = green;
if(response == 2)
image.at<Vec3b>(j,i) = gray;
if(response == 1)
image.at<Vec3b>(j,i) = blue;
if(response == 0)
image.at<Vec3b>(j,i) = red;
}
}
for (int i = 0; i < COUNT; i++)
{
Point p(data[i][0],data[i][1]);
if (label[i][0]==0)
circle( image, p, 3, Scalar(255, 255, 0), -1, 8);
if (label[i][0]==1)
circle( image, p, 3, Scalar(255, 0, 255), -1, 8);
if (label[i][0]==2)
circle( image, p, 3, Scalar(0, 255, 255), -1, 8);
if (label[i][0]==3)
circle( image, p, 3, Scalar(0, 0, 0), -1, 8);
}
imshow("result",image);
imwrite("output.jpg",image);
waitKey(0);
return 0;
}
label.txt:
0
1
0
2
0
0
0
1
0
3
3
1
0
1
1
2
2
2
0
0
2
data.txt:
100 250
250 450
150 160
300 420
210 120
90 20
70 60
330 210
80 200
400 120
420 200
300 300
50 130
270 300
320 310
490 450
480 480
420 400
250 250
230 270
400 300