利用SVM解决2维空间向量的3级分类问题
2014-02-26 17:06
323 查看
【原文:http://blog.csdn.net/firefight/article/details/6400060】
为了学习OPENCV SVM分类器, 参考网上的"利用SVM解决2维空间向量的分类问题"实现并改为C++代码,仅供参考
环境:OPENCV2.2 + VS2008
步骤:
1,生成随机的点,并按一定的空间分布将其归类
2,创建SVM并利用随机点样本进行训练
3,将整个空间按SVM分类结果进行划分,并显示支持向量
[cpp] view
plaincopy
#include "stdafx.h"
#include <opencv2/opencv.hpp>
void drawCross(Mat &img, Point center, Scalar color)
{
int col = center.x > 2 ? center.x : 2;
int row = center.y> 2 ? center.y : 2;
line(img, Point(col -2, row - 2), Point(col + 2, row + 2), color);
line(img, Point(col + 2, row - 2), Point(col - 2, row + 2), color);
}
int newSvmTest(int rows, int cols, int testCount)
{
if(testCount > rows * cols)
return 0;
Mat img = Mat::zeros(rows, cols, CV_8UC3);
Mat testPoint = Mat::zeros(rows, cols, CV_8UC1);
Mat data = Mat::zeros(testCount, 2, CV_32FC1);
Mat res = Mat::zeros(testCount, 1, CV_32SC1);
//Create random test points
for (int i= 0; i< testCount; i++)
{
int row = rand() % rows;
int col = rand() % cols;
if(testPoint.at<unsigned char>(row, col) == 0)
{
testPoint.at<unsigned char>(row, col) = 1;
data.at<float>(i, 0) = float (col) / cols;
data.at<float>(i, 1) = float (row) / rows;
}
else
{
i--;
continue;
}
if (row > ( 50 * cos(col * CV_PI/ 100) + 200) )
{
drawCross(img, Point(col, row), CV_RGB(255, 0, 0));
res.at<unsigned int>(i, 0) = 1;
}
else
{
if (col > 200)
{
drawCross(img, Point(col, row), CV_RGB(0, 255, 0));
res.at<unsigned int>(i, 0) = 2;
}
else
{
drawCross(img, Point(col, row), CV_RGB(0, 0, 255));
res.at<unsigned int>(i, 0) = 3;
}
}
}
//Show test points
imshow("dst", img);
waitKey(0);
/////////////START SVM TRAINNING//////////////////
CvSVM svm = CvSVM();
CvSVMParams param;
CvTermCriteria criteria;
criteria= cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);
/* SVM种类:CvSVM::C_SVC
Kernel的种类:CvSVM::RBF
degree:10.0(此次不使用)
gamma:8.0
coef0:1.0(此次不使用)
C:10.0
nu:0.5(此次不使用)
p:0.1(此次不使用)
然后对训练数据正规化处理,并放在CvMat型的数组里。*/
param= CvSVMParams (CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, criteria);
svm.train(data, res, Mat(), Mat(), param);
for (int i= 0; i< rows; i++)
{
for (int j= 0; j< cols; j++)
{
Mat m = Mat::zeros(1, 2, CV_32FC1);
m.at<float>(0,0) = float (j) / cols;
m.at<float>(0,1) = float (i) / rows;
float ret = 0.0;
ret = svm.predict(m);
Scalar rcolor;
switch ((int) ret)
{
case 1: rcolor= CV_RGB(100, 0, 0); break;
case 2: rcolor= CV_RGB(0, 100, 0); break;
case 3: rcolor= CV_RGB(0, 0, 100); break;
}
line(img, Point(j,i), Point(j,i), rcolor);
}
}
imshow("dst", img);
waitKey(0);
//Show support vectors
int sv_num= svm.get_support_vector_count();
for (int i= 0; i< sv_num; i++)
{
const float* support = svm.get_support_vector(i);
circle(img, Point((int) (support[0] * cols), (int) (support[1] * rows)), 5, CV_RGB(200, 200, 200));
}
imshow("dst", img);
waitKey(0);
return 0;
}
int main(int argc, char** argv)
{
return newSvmTest(400, 600, 100);
}
学习样本:
分类:
支持向量:
为了学习OPENCV SVM分类器, 参考网上的"利用SVM解决2维空间向量的分类问题"实现并改为C++代码,仅供参考
环境:OPENCV2.2 + VS2008
步骤:
1,生成随机的点,并按一定的空间分布将其归类
2,创建SVM并利用随机点样本进行训练
3,将整个空间按SVM分类结果进行划分,并显示支持向量
[cpp] view
plaincopy
#include "stdafx.h"
#include <opencv2/opencv.hpp>
void drawCross(Mat &img, Point center, Scalar color)
{
int col = center.x > 2 ? center.x : 2;
int row = center.y> 2 ? center.y : 2;
line(img, Point(col -2, row - 2), Point(col + 2, row + 2), color);
line(img, Point(col + 2, row - 2), Point(col - 2, row + 2), color);
}
int newSvmTest(int rows, int cols, int testCount)
{
if(testCount > rows * cols)
return 0;
Mat img = Mat::zeros(rows, cols, CV_8UC3);
Mat testPoint = Mat::zeros(rows, cols, CV_8UC1);
Mat data = Mat::zeros(testCount, 2, CV_32FC1);
Mat res = Mat::zeros(testCount, 1, CV_32SC1);
//Create random test points
for (int i= 0; i< testCount; i++)
{
int row = rand() % rows;
int col = rand() % cols;
if(testPoint.at<unsigned char>(row, col) == 0)
{
testPoint.at<unsigned char>(row, col) = 1;
data.at<float>(i, 0) = float (col) / cols;
data.at<float>(i, 1) = float (row) / rows;
}
else
{
i--;
continue;
}
if (row > ( 50 * cos(col * CV_PI/ 100) + 200) )
{
drawCross(img, Point(col, row), CV_RGB(255, 0, 0));
res.at<unsigned int>(i, 0) = 1;
}
else
{
if (col > 200)
{
drawCross(img, Point(col, row), CV_RGB(0, 255, 0));
res.at<unsigned int>(i, 0) = 2;
}
else
{
drawCross(img, Point(col, row), CV_RGB(0, 0, 255));
res.at<unsigned int>(i, 0) = 3;
}
}
}
//Show test points
imshow("dst", img);
waitKey(0);
/////////////START SVM TRAINNING//////////////////
CvSVM svm = CvSVM();
CvSVMParams param;
CvTermCriteria criteria;
criteria= cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);
/* SVM种类:CvSVM::C_SVC
Kernel的种类:CvSVM::RBF
degree:10.0(此次不使用)
gamma:8.0
coef0:1.0(此次不使用)
C:10.0
nu:0.5(此次不使用)
p:0.1(此次不使用)
然后对训练数据正规化处理,并放在CvMat型的数组里。*/
param= CvSVMParams (CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, criteria);
svm.train(data, res, Mat(), Mat(), param);
for (int i= 0; i< rows; i++)
{
for (int j= 0; j< cols; j++)
{
Mat m = Mat::zeros(1, 2, CV_32FC1);
m.at<float>(0,0) = float (j) / cols;
m.at<float>(0,1) = float (i) / rows;
float ret = 0.0;
ret = svm.predict(m);
Scalar rcolor;
switch ((int) ret)
{
case 1: rcolor= CV_RGB(100, 0, 0); break;
case 2: rcolor= CV_RGB(0, 100, 0); break;
case 3: rcolor= CV_RGB(0, 0, 100); break;
}
line(img, Point(j,i), Point(j,i), rcolor);
}
}
imshow("dst", img);
waitKey(0);
//Show support vectors
int sv_num= svm.get_support_vector_count();
for (int i= 0; i< sv_num; i++)
{
const float* support = svm.get_support_vector(i);
circle(img, Point((int) (support[0] * cols), (int) (support[1] * rows)), 5, CV_RGB(200, 200, 200));
}
imshow("dst", img);
waitKey(0);
return 0;
}
int main(int argc, char** argv)
{
return newSvmTest(400, 600, 100);
}
学习样本:
分类:
支持向量:
相关文章推荐
- Relation Extraction中SVM分类样例unbalance data问题解决 -松弛变量与惩罚因子
- SVM解决多分类问题的方法
- 利用SVM实现一个三类分类问题
- SVM如何解决多分类问题
- Relation Extraction中SVM分类样例unbalance data问题解决 -松弛变量与惩罚因子
- 支持向量机之使用核SVM解决非线性分类问题
- SVM怎样解决多分类问题
- Relation Extraction中SVM分类样例unbalance data问题解决 -松弛变量与惩罚因子
- 利用NSInvocation给NSObject添加一个分类方法,解决传递多参数问题
- Relation Extraction中SVM分类样例unbalance data问题解决 -松弛变量与惩罚因子
- 利用spring完美解决java中文问题
- 利用位运算解决排序问题(摘自编程珠玑)
- 第十周项目3利用二叉树遍历解决问题(计算二叉树节点个数)
- 利用Memcache解决数据库高并发访问的瓶颈问题
- 第十周项目3【利用二叉树遍历思想解决问题】
- 第十周项目3-利用二叉树遍历思想解决问题
- 利用穷举法解决组合问题,背包问题,变量相等问题
- [JSP] 利用Filter解决Servlet输出中文乱码的问题
- hdu 4975 最大流问题解决队伍和矩阵,利用矩阵dp优化
- 利用深度搜索法解决八皇后问题