一、今天看到签名的鉴定中有SVM一项,于是我查看了一些SVM的文献,SVM支持向量机是基于线性划分的,原理是将低维空间中的点映射到高维空间中,使之线性可分。
完成了一个项目来做实验。代码先贴上来:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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,搜索了几遍都没有,看来没有错了。