代码改变世界

初识SVM

2012-05-09 21:39  sensensen  阅读(327)  评论(0编辑  收藏  举报

一、今天看到签名的鉴定中有SVM一项,于是我查看了一些SVM的文献,SVM支持向量机是基于线性划分的,原理是将低维空间中的点映射到高维空间中,使之线性可分。

完成了一个项目来做实验。代码先贴上来:

View Code
  1 // testsvm.cpp : Defines the entry point for the console application.
  2 //
  3 
  4 #include "stdafx.h"
  5 
  6 #include "cv.h"    
  7 #include "highgui.h"    
  8    
  9 #include "ml.h"    
 10 #include "time.h"  
 11        
 12 #include "ctype.h"   
 13        
 14 #include <iostream>    
 15 using namespace std;   
 16        
 17 int main()   
 18 {   
 19     int size = 400;
 20     const int s = 100;             
 21     int i, j, sv_num;   
 22     IplImage *img;  
 23     CvSVM svm = CvSVM::CvSVM();    
 24             
 25         CvSVMParams param;   
 26         CvTermCriteria criteria;//停止迭代的标准    
 27         CvRNG rng = cvRNG(time(NULL));   
 28         CvPoint pts[s];         //定义1000个点    
 29         float data[s*2];        //点的坐标    
 30         int res[s];             //点的所属类    
 31         CvMat data_mat, res_mat;   
 32         CvScalar rcolor;   
 33         const float *support;   
 34     
 35         // (1)图像区域的确保和初始化    
 36         img= cvCreateImage(cvSize(size, size), IPL_DEPTH_8U, 3);   
 37         cvZero(img);   
 38         //确保画像区域,并清0(用黑色作初始化处理)。    
 39        
 40         // (2)学习数据的生成    
 41         for (i= 0; i< s; i++) 
 42         {   
 43             pts[i].x= cvRandInt(&rng) % size;   //用随机整数赋值    
 44             pts[i].y= cvRandInt(&rng) % size;   
 45             if (pts[i].y> 50 * cos(pts[i].x* CV_PI/ 100) + 200) 
 46             {   
 47             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));   
 48             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));   
 49             res[i] = 1;   
 50             }   
 51             else
 52             {   
 53                 if (pts[i].x> 200) 
 54                 {   
 55                     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));   
 56                     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));   
 57                     res[i] = 2;   
 58                 }   
 59                 else 
 60                 {   
 61                 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));   
 62                     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));   
 63                     res[i] = 3;   
 64                 }   
 65             }   
 66         }   
 67         //生成2维随机训练数据,并将其值放在CvPoint数据类型的数组pts[ ]中。    
 68        
 69         // (3)学习数据的显示    
 70         cvNamedWindow("SVM", CV_WINDOW_AUTOSIZE);   
 71         cvShowImage("SVM", img);   
 72         cvWaitKey(0);   
 73        
 74         // (4)学习参数的生成    
 75         for (i= 0; i< s; i++) 
 76         {   
 77             data[i* 2] = float (pts[i].x) / size;   
 78             data[i* 2 + 1] = float (pts[i].y) / size;   
 79         }   
 80         cvInitMatHeader(&data_mat, s, 2, CV_32FC1, data);   
 81         cvInitMatHeader(&res_mat, s, 1, CV_32SC1, res);   
 82         criteria= cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);   
 83         param= CvSVMParams (CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, criteria);   
 84 //
 85 //76.            SVM种类:CvSVM::C_SVC  
 86 //77.            Kernel的种类:CvSVM::RBF  
 87 //78.            degree:10.0(此次不使用)  
 88 //79.            gamma:8.0  
 89 //80.            coef0:1.0(此次不使用)  
 90 //81.            C:10.0  
 91 //82.            nu:0.5(此次不使用)  
 92 //83.            p:0.1(此次不使用)  
 93 //84.            然后对训练数据正规化处理,并放在CvMat型的数组里。  
 94 
 95        
 96         //☆☆☆☆☆☆☆☆☆(5)SVM学习☆☆☆☆☆☆☆☆☆☆☆☆    
 97         svm.train(&data_mat, &res_mat, NULL, NULL, param);// 98         //☆☆利用训练数据和确定的学习参数,进行SVM学习☆☆☆☆        
 99        
100         // (6)学习结果的绘图    
101     for (i= 0; i< size; i++) {   
102             for (j= 0; j< size; j++) {   
103                 CvMat m;   
104                 float ret = 0.0;   
105                 float a[] = { float (j) / size, float (i) / size };   
106                 cvInitMatHeader(&m, 1, 2, CV_32FC1, a);   
107                 ret= svm.predict(&m);   
108                 switch ((int) ret) {   
109                     case 1:   
110                         rcolor= CV_RGB(100, 0, 0);   
111                         break;   
112                     case 2:   
113                         rcolor= CV_RGB(0, 100, 0);   
114                         break;   
115                     case 3:   
116                         rcolor= CV_RGB(0, 0, 100);   
117                         break;   
118                 }   
119                 cvSet2D(img, i, j, rcolor);   
120             }   
121         }   
122         //为了显示学习结果,通过输入图像区域的所有像素(特征向量)并进行分类。然后对输入像素用所属等级的颜色绘图。    
123        
124         // (7)训练数据的再绘制    
125         for (i= 0; i< s; i++) {   
126             CvScalar rcolor;   
127             switch (res[i]) {   
128                 case 1:   
129                     rcolor= CV_RGB(255, 0, 0);   
130                     break;   
131                 case 2:   
132                     rcolor= CV_RGB(0, 255, 0);   
133                     break;   
134                 case 3:   
135                 rcolor= CV_RGB(0, 0, 255);   
136                     break;   
137             }   
138             cvLine(img, cvPoint(pts[i].x- 2, pts[i].y- 2), cvPoint(pts[i].x+ 2, pts[i].y+ 2), rcolor);   
139             cvLine(img, cvPoint(pts[i].x+ 2, pts[i].y- 2), cvPoint(pts[i].x- 2, pts[i].y+ 2), rcolor);   
140         }   
141     //将训练数据在结果图像上重复的绘制出来。    
142        
143         // (8)支持向量的绘制    
144         sv_num= svm.get_support_vector_count();   
145         for (i= 0; i< sv_num; i++) {   
146             support = svm.get_support_vector(i);   
147             cvCircle(img, cvPoint((int) (support[0] * size), (int) (support[1] * size)), 5, CV_RGB(200, 200, 200));   
148         }   
149         //用白色的圆圈对支持向量作标记。    
150        
151         // (9)图像的显示     
152         cvNamedWindow("SVM", CV_WINDOW_AUTOSIZE);   
153         cvShowImage("SVM", img);   
154         cvWaitKey(0);   
155         cvDestroyWindow("SVM");   
156         cvReleaseImage(&img);   
157         return 0;   
158         //显示实际处理结果的图像,直到某个键被按下为止。    
159     
160     }  

运行时注意一下OPENCV的设置中有在后面Link部分添加cxcore.lib 等。

文件已经保存在文件testsvm中了。

二、傻瓜也会用Libsvm

下载到了一篇pdf文档,里面采用命令行的方式对libsvm进行调用,文档我也会传到文件中,其中的方法我都试过,有小问题的地方我也标注出来了。主要用到Python和gnuplot以及libsvm。

运行体会了svm的使用,很棒!

三、这个博客

http://blog.csdn.net/flydreamGG/article/details/4470121

以上是一个很好的博客,不解释。还有博客中提到笔者给SVM的源码做了注释,文档我也下下来了,一并放在文件中。

 

最后,我的程序里,似乎没有用到SVM,搜索了几遍都没有,看来没有错了。