//利用SVM解决2维空间向量的3级分类问题
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include <ML.H>
#include <TIME.H>
#include <CTYPE.H>
#include <IOSTREAM>
using namespace std;
int main(int argc, char **argv)
{
int size = 400; //图像的长度和宽度
const int s = 100; //试验点个数(可更改!!)
int i, j, sv_num;
IplImage *img;
CvSVM svm = CvSVM(); //★★★
CvSVMParams param;
CvTermCriteria criteria;//停止迭代的标准
CvRNG rng = cvRNG(time(NULL));
CvPoint pts[s]; //定义1000个点
float data[s*2]; //点的坐标
int res[s]; //点的所属类
CvMat data_mat, res_mat;
CvScalar rcolor;
const float *support;
// (1)图像区域的确保和初始化
img= cvCreateImage(cvSize(size, size), IPL_DEPTH_8U, 3);
cvZero(img);
//确保画像区域,并清0(用黑色作初始化处理)。
// (2)学习数据的生成
for (i= 0; i< s; i++) {
pts[i].x= cvRandInt(&rng) % size; //用随机整数赋值
pts[i].y= cvRandInt(&rng) % size;
if (pts[i].y> 50 * cos(pts[i].x* CV_PI/ 100) + 200) {
cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), CV_RGB(255, 0, 0));
cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), CV_RGB(255, 0, 0));
res[i] = 1;
}
else {
if (pts[i].x> 200) {
cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), CV_RGB(0, 255, 0));
cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), CV_RGB(0, 255, 0));
res[i] = 2;
}
else {
cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), CV_RGB(0, 0, 255));
cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), CV_RGB(0, 0, 255));
res[i] = 3;
}
}
}
//生成2维随机训练数据,并将其值放在CvPoint数据类型的数组pts[ ]中。
// (3)学习数据的显示
cvNamedWindow("SVM", CV_WINDOW_AUTOSIZE);
cvShowImage("SVM", img);
cvWaitKey(0);
// (4)学习参数的生成
for (i= 0; i< s; i++) {
data[i* 2] = float (pts[i].x) / size;
data[i* 2 + 1] = float (pts[i].y) / size;
}
cvInitMatHeader(&data_mat, s, 2, CV_32FC1, data);
cvInitMatHeader(&res_mat, s, 1, CV_32SC1, res);
criteria= cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);
param= CvSVMParams (CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, criteria);
/*
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型的数组里。
*/
//☆☆☆☆☆☆☆☆☆(5)SVM学习☆☆☆☆☆☆☆☆☆☆☆☆
svm.train(&data_mat, &res_mat, NULL, NULL, param);//☆
//☆☆利用训练数据和确定的学习参数,进行SVM学习☆☆☆☆
// (6)学习结果的绘图
for (i= 0; i< size; i++) {
for (j= 0; j< size; j++) {
CvMat m;
float ret = 0.0;
float a[] = { float (j) / size, float (i) / size };
cvInitMatHeader(&m, 1, 2, CV_32FC1, a);
ret= svm.predict(&m);
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;
}
cvSet2D(img, i, j, rcolor);
}
}
//为了显示学习结果,通过输入图像区域的所有像素(特征向量)并进行分类。然后对输入像素用所属等级的颜色绘图。
// (7)训练数据的再绘制
for (i= 0; i< s; i++) {
CvScalar rcolor;
switch (res[i]) {
case 1:
rcolor= CV_RGB(255, 0, 0);
break;
case 2:
rcolor= CV_RGB(0, 255, 0);
break;
case 3:
rcolor= CV_RGB(0, 0, 255);
break;
}
cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), rcolor);
cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), rcolor);
}
//将训练数据在结果图像上重复的绘制出来。
// (8)支持向量的绘制
sv_num= svm.get_support_vector_count();
for (i= 0; i< sv_num; i++) {
support = svm.get_support_vector(i);
cvCircle(img, cvPoint((int) (support[0] * size), (int) (support[1] * size)), 5, CV_RGB(200, 200, 200));
}
//用白色的圆圈对支持向量作标记。
// (9)图像的显示
cvNamedWindow("SVM", CV_WINDOW_AUTOSIZE);
cvShowImage("SVM", img);
cvWaitKey(0);
cvDestroyWindow("SVM");
cvReleaseImage(&img);
return 0;
//显示实际处理结果的图像,直到某个键被按下为止。
}
svm代码,忘了从哪搜到的,共享之
最新推荐文章于 2024-11-21 20:00:00 发布