以上是我上一篇文章中的代码实现,里面分别用了opencv中的SVM和LibSVM,opencv的SVM用起来更方便,但貌似内部其实也是基于Libsvm,同样的参数训练出来的结果是一致的,里面有Libsvm的调用过程,如果用libsvm需要在工程里面添加libsvm的源码文件分别是svm.h和svm.cpp,林智仁的库里自带的那两个核心文件即可。

libsvm的用法让人更感觉是在用C的写法,opencv封装过的易用性更好,稍后我会把工程文件放到github上供大家下载,若有什么错误,还请批评指教~,这里用的是Minist的数据集,图像时我经过处理后的单张图像,大小为20*20,里面有详细的函数使用说明

[https://github.com/YihangLou/SVM-Minist-HandWriting-Recognition] Github上的工程链接

  1. // DigitsRec_HOG_SVM.cpp : 定义控制台应用程序的入口点。
  2. #include "opencv2/opencv.hpp"
  3. #include "fstream"
  4. #include "svm.h"
  5. using namespace std;
  6. using namespace cv;
  7. #define srcfeature
  8. vector<string> trainImageList;//训练图像列表,此处路径
  9. vector<int> trainLabelList; //标签
  10. vector<string> testImageList;//训练图像列表,此处路径
  11. string trainImageFile= "D:\\WorkSpace\\homework\\PatternRecognization\\第一次作业\\minist\\train_image\\imagelist.txt";
  12. string testImageFile = "D:\\WorkSpace\\homework\\PatternRecognization\\第一次作业\\minist\\test_image\\imagelist.txt";
  13. string testBasePath = "D:\\WorkSpace\\homework\\PatternRecognization\\第一次作业\\minist\\test_image\\";
  14. string trainBasePath = "D:\\WorkSpace\\homework\\PatternRecognization\\第一次作业\\minist\\train_image\\";
  15. string SVMModel ="svm_model.xml";
  16. CvMat * dataMat;
  17. CvMat * labelMat;
  18. //***************************************************************
  19. // 名称: readTrainFileList
  20. // 功能: 读取训练的图像列表和图像的位置
  21. // 权限: public
  22. // 返回值: void
  23. // 参数: string trainImageFile 文件列表
  24. // 参数: string basePath 基地址
  25. // 参数: vector<string> & trainImageList 图像路径list
  26. // 参数: vector<int> & trainLabelList 图像标签list
  27. //***************************************************************
  28. void readTrainFileList(string trainImageFile, string basePath, vector<string> &trainImageList, vector<int> &trainLabelList)
  29. {
  30. ifstream readData( trainImageFile );
  31. string buffer;
  32. while( readData )
  33. {
  34. if( getline( readData, buffer))
  35. {
  36. int label = int((buffer[0])-'0');//在我这里路径中第一个文件夹就是类别
  37. trainLabelList.push_back( label);
  38. trainImageList.push_back( buffer );//图像路径
  39. }
  40. }
  41. readData.close();
  42. cout<<"Read Train Data Complete"<<endl;
  43. }
  44. //***************************************************************
  45. // 名称: readTestFileList
  46. // 功能: 读测试文件
  47. // 权限: public
  48. // 返回值: void
  49. // 参数: string testImageFile
  50. // 参数: string basePath
  51. // 参数: vector<string> & testImageList 测试图像列表
  52. //***************************************************************
  53. void readTestFileList(string testImageFile, string basePath, vector<string> &testImageList)
  54. {
  55. ifstream readData( testImageFile ); //加载测试图片集合
  56. string buffer;
  57. while( readData )
  58. {
  59. if( getline( readData, buffer))
  60. {
  61. testImageList.push_back( buffer );//图像路径
  62. }
  63. }
  64. readData.close();
  65. cout<<"Read Test Data Complete"<<endl;
  66. }
  67. //***************************************************************
  68. // 名称: processHogFeature
  69. // 功能: 计算Hog特征
  70. // 权限: public
  71. // 返回值: void
  72. // 参数: vector<string> trainImageList
  73. // 参数: vector<int> trainLabelList
  74. // 参数: CvMat * & dataMat
  75. // 参数: CvMat * & labelMat
  76. //***************************************************************
  77. void processHogFeature(vector<string> trainImageList,vector<int> trainLabelList, CvMat * &dataMat,CvMat * &labelMat)
  78. {
  79. int trainSampleNum = trainImageList.size();
  80. dataMat = cvCreateMat( trainSampleNum, 324, CV_32FC1 ); //324为Hog feature Size
  81. cvSetZero( dataMat );
  82. labelMat = cvCreateMat( trainSampleNum, 1, CV_32FC1 );
  83. cvSetZero( labelMat );
  84. IplImage* src;
  85. IplImage* trainImg=cvCreateImage(cvSize(20,20),8,3);//20 20
  86. for( int i = 0; i != trainImageList.size(); i++ )
  87. {
  88. src=cvLoadImage( (trainBasePath + trainImageList[i]).c_str(),1);
  89. if( src == NULL )
  90. {
  91. cout<<" can not load the image: "<<(trainBasePath + trainImageList[i]).c_str()<<endl;
  92. continue;
  93. }
  94. //cout<<"Calculate Hog Feature "<<(trainBasePath + trainImageList[i]).c_str()<<endl;
  95. cvResize(src,trainImg);
  96. HOGDescriptor *hog=new HOGDescriptor(cvSize(20,20),cvSize(10,10),cvSize(5,5),cvSize(5,5),9);
  97. vector<float>descriptors;
  98. hog->compute(trainImg, descriptors,Size(1,1), Size(0,0));
  99. int j =0;
  100. for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
  101. {
  102. cvmSet(dataMat,i,j,*iter);//存储HOG特征
  103. j++;
  104. }
  105. cvmSet( labelMat, i, 0, trainLabelList[i] );
  106. //cout<<"Image and label "<<trainImageList[i].c_str()<<" "<<trainLabelList[i]<<endl;
  107. }
  108. cout<<"Calculate Hog Feature Complete"<<endl;
  109. cout<<dataMat<<endl;
  110. }
  111. void processNonFeature(vector<string> trainImageList,vector<int> trainLabelList, CvMat * &dataMat,CvMat * &labelMat)
  112. {
  113. int trainSampleNum = trainImageList.size();
  114. dataMat = cvCreateMat( trainSampleNum, 400, CV_32FC1 ); //324为Hog feature 大小,需提前设置
  115. cvSetZero( dataMat );
  116. labelMat = cvCreateMat( trainSampleNum, 1, CV_32FC1 );
  117. cvSetZero( labelMat );
  118. IplImage* src;
  119. IplImage* resizeImg=cvCreateImage(cvSize(20,20),8,3);//20 20是训练样本的大小
  120. for( int i = 0; i != trainImageList.size(); i++ )
  121. {
  122. src=cvLoadImage( (trainBasePath + trainImageList[i]).c_str(),1);
  123. if( src == NULL )
  124. {
  125. cout<<" can not load the image: "<<(trainBasePath + trainImageList[i]).c_str()<<endl;
  126. continue;
  127. }
  128. //cout<<"Calculate Hog Feature "<<(trainBasePath + trainImageList[i]).c_str()<<endl;
  129. cvResize(src,resizeImg);
  130. IplImage * grayImage = cvCreateImage(cvGetSize(resizeImg), IPL_DEPTH_8U, 1);
  131. cvCvtColor(resizeImg,grayImage,CV_BGR2GRAY);
  132. //二值化图像
  133. IplImage * binaryImage = cvCreateImage(cvGetSize(grayImage),IPL_DEPTH_8U,1);
  134. cvThreshold(grayImage,binaryImage,25,255,CV_THRESH_BINARY);
  135. //cvNamedWindow("src");
  136. //cvShowImage("src", src);
  137. //cvNamedWindow("show");
  138. //cvShowImage("show", binaryImage);
  139. //cvWaitKey(0);//这里是看一下二值化的效果怎么样
  140. HOGDescriptor *hog=new HOGDescriptor(cvSize(20,20),cvSize(10,10),cvSize(5,5),cvSize(5,5),9);
  141. vector<float>descriptors;
  142. int j =0; //j为矩阵的水平坐标,要把特征从vector中拷贝过来
  143. uchar * tmp = new uchar;
  144. for(int n=0;n<binaryImage->height;n++)
  145. { for(int m=0;m<binaryImage->width;m++)
  146. {
  147. *tmp=((uchar *)(binaryImage->imageData + n*binaryImage->widthStep))[m];
  148. cvmSet(dataMat,i,j,*tmp);//存储HOG特征
  149. j++;
  150. }
  151. }
  152. cvmSet( labelMat, i, 0, trainLabelList[i] );
  153. //cout<<"Image and label "<<trainImageList[i].c_str()<<" "<<trainLabelList[i]<<endl;
  154. }
  155. cout<<"Calculate Hog Feature Complete"<<endl;
  156. }
  157. //***************************************************************
  158. // 名称: trainSVM
  159. // 功能: 此处用的是opencv的SVM训练
  160. // 权限: public
  161. // 返回值: void
  162. // 参数: CvMat * & dataMat
  163. // 参数: CvMat * & labelMat
  164. //***************************************************************
  165. void trainSVM(CvMat * & dataMat,CvMat * & labelMat )
  166. {
  167. cout<<"train svm start"<<endl;
  168. cout<<dataMat<<endl;
  169. CvSVM svm;
  170. CvSVMParams param;//这里是SVM训练相关参数
  171. CvTermCriteria criteria;
  172. criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
  173. param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );
  174. svm.train( dataMat, labelMat, NULL, NULL, param );//训练数据
  175. svm.save( SVMModel.c_str());
  176. cout<<"SVM Training Complete"<<endl;
  177. }
  178. //***************************************************************
  179. // 名称: trainLibSVM
  180. // 功能: 此处用的是LibSVM库的SVM训练
  181. // 权限: public
  182. // 返回值: void
  183. // 参数: CvMat * & dataMat
  184. // 参数: CvMat * & labelMat
  185. //***************************************************************
  186. void trainLibSVM(CvMat *& dataMat, CvMat * & labelMat)
  187. {
  188. cout<<"LibSVM start"<<endl;
  189. //配置SVM参数
  190. svm_parameter param;
  191. //param.svm_type = C_SVC;
  192. param.svm_type = EPSILON_SVR;
  193. param.kernel_type = RBF;
  194. param.degree = 10.0;
  195. param.gamma = 0.09;
  196. param.coef0 = 1.0;
  197. param.nu = 0.5;
  198. param.cache_size = 1000;
  199. param.C = 10.0;
  200. param.eps = 1e-3;
  201. param.p = 1.0;
  202. //svm_prob读取
  203. svm_problem svm_prob;
  204. int sampleNum = dataMat->rows;
  205. int vectorLength = dataMat->cols;
  206. svm_prob.l = sampleNum;
  207. svm_prob.y = new double [sampleNum];
  208. for (int i = 0; i < sampleNum; i++)
  209. {
  210. svm_prob.y[i] = cvmGet(labelMat,i,0);
  211. }
  212. cout<<"LibSVM middle"<<endl;
  213. svm_prob.x = new svm_node * [sampleNum];
  214. for (int i = 0; i < sampleNum; i++)
  215. {
  216. svm_node * x_space = new svm_node [vectorLength + 1];
  217. for (int j = 0; j < vectorLength; j++)
  218. {
  219. x_space[j].index = j;
  220. x_space[j].value = cvmGet(dataMat,i,j);
  221. }
  222. x_space[vectorLength].index = -1;//注意,结束符号,一开始忘记加了
  223. svm_prob.x[i] = x_space;
  224. }
  225. cout<<"LibSVM end"<<endl;
  226. svm_model * svm_model = svm_train(&svm_prob, &param);
  227. #ifdef srcfeature
  228. svm_save_model("libsvm_minist_src_feature_model_.model",svm_model);
  229. #else
  230. svm_save_model("libsvm_minist_model.model",svm_model);
  231. #endif
  232. for (int i=0 ; i < sampleNum; i++)
  233. {
  234. delete [] svm_prob.x[i];
  235. }
  236. delete [] svm_prob.y;
  237. svm_free_model_content(svm_model);
  238. }
  239. //***************************************************************
  240. // 名称: testSVM
  241. // 功能: 测试opencv训练的SVM准确率
  242. // 权限: public
  243. // 返回值: void
  244. // 参数: vector<string> testImageList
  245. // 参数: string SVMModel
  246. //***************************************************************
  247. void testSVM(vector<string> testImageList, string SVMModel)
  248. {
  249. CvSVM svm;
  250. svm.load(SVMModel.c_str());//加载模型文件
  251. IplImage* testImage;
  252. IplImage* tempImage;
  253. char buffer[512];
  254. ofstream ResultOutput( "predict_result.txt" );//把预测结果存储在这个文本中
  255. for( int j = 0; j != testImageList.size(); j++ )//依次遍历所有的待检测图片
  256. {
  257. testImage = cvLoadImage( (testBasePath+testImageList[j]).c_str(), 1);
  258. if( testImage == NULL )
  259. {
  260. cout<<" can not load the image: "<<(testBasePath+testImageList[j]).c_str()<<endl;
  261. continue;
  262. }
  263. tempImage =cvCreateImage(cvSize(20,20),8,3);
  264. cvZero(tempImage);
  265. cvResize(testImage,tempImage);
  266. HOGDescriptor *hog=new HOGDescriptor(cvSize(20,20),cvSize(10,10),cvSize(5,5),cvSize(5,5),9);
  267. vector<float>descriptors;
  268. hog->compute(tempImage, descriptors,Size(1,1), Size(0,0));
  269. CvMat* TempMat=cvCreateMat(1,descriptors.size(),CV_32FC1);
  270. int n=0;
  271. for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
  272. {
  273. cvmSet(TempMat,0,n,*iter);
  274. n++;
  275. }
  276. int resultLabel = svm.predict(TempMat);//检测结果
  277. sprintf( buffer, "%s %d\r\n",testImageList[j].c_str(),resultLabel );
  278. ResultOutput<<buffer;
  279. }
  280. cvReleaseImage(&testImage);
  281. cvReleaseImage(&tempImage);
  282. ResultOutput.close();
  283. cout<<"SVM Predict Complete"<<endl;
  284. }
  285. //***************************************************************
  286. // 名称: testLibSVM
  287. // 功能: 测试LisbSVM训练的模型的分类性能
  288. // 权限: public
  289. // 返回值: void
  290. // 参数: string LibSVMModelFile
  291. // 参数: vector<string> testImageList
  292. // 参数: string SVMModel
  293. //***************************************************************
  294. void testLibSVM(string LibSVMModelFile, vector<string> testImageList, string SVMModel)
  295. {
  296. svm_model * svm = svm_load_model(LibSVMModelFile.c_str());
  297. IplImage* testImage;
  298. IplImage* tempImage;
  299. char buffer[512];
  300. ofstream ResultOutput( "libsvm_predict_result.txt" );
  301. for( int j = 0; j != testImageList.size(); j++ )//依次遍历所有的待检测图片
  302. {
  303. testImage = cvLoadImage( (testBasePath+testImageList[j]).c_str(), 1);
  304. if( testImage == NULL )
  305. {
  306. cout<<" can not load the image: "<<(testBasePath+testImageList[j]).c_str()<<endl;
  307. continue;
  308. }
  309. tempImage =cvCreateImage(cvSize(20,20),8,3);
  310. cvZero(tempImage);
  311. cvResize(testImage,tempImage);
  312. HOGDescriptor *hog=new HOGDescriptor(cvSize(20,20),cvSize(10,10),cvSize(5,5),cvSize(5,5),9);
  313. vector<float>descriptors;
  314. hog->compute(tempImage, descriptors,Size(1,1), Size(0,0));
  315. svm_node * inputVector = new svm_node [ descriptors.size()+1];
  316. int n = 0;
  317. for(vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
  318. {
  319. inputVector[n].index = n;
  320. inputVector[n].value = *iter;
  321. n++;
  322. }
  323. inputVector[n].index = -1;
  324. int resultLabel = svm_predict(svm,inputVector);//分类结果
  325. sprintf( buffer, "%s %d\r\n",testImageList[j].c_str(),resultLabel );
  326. ResultOutput<<buffer;
  327. delete [] inputVector;
  328. }
  329. svm_free_model_content(svm);
  330. cvReleaseImage(&testImage);
  331. cvReleaseImage(&tempImage);
  332. ResultOutput.close();
  333. cout<<"SVM Predict Complete"<<endl;
  334. }
  335. //***************************************************************
  336. // 名称: releaseAll
  337. // 功能: 释放相应的资源
  338. // 权限: public
  339. // 返回值: void
  340. //***************************************************************
  341. void releaseAll()
  342. {
  343. cvReleaseMat( &dataMat );
  344. cvReleaseMat( &labelMat);
  345. cout<<"Release All Complete"<<endl;
  346. }
  347. //***************************************************************
  348. // 名称: main
  349. // 功能: 这里用了两种SVM,一种是opencv中的,一种是libsvm中的,训练测试需要选择相对应的svm
  350. // 权限: public
  351. // 返回值: int
  352. //***************************************************************
  353. int main()
  354. {
  355. readTrainFileList(trainImageFile,trainBasePath,trainImageList,trainLabelList);
  356. processHogFeature(trainImageList,trainLabelList, dataMat,labelMat);
  357. //trainSVM(dataMat,labelMat );
  358. //processNonFeature(trainImageList,trainLabelList, dataMat,labelMat);
  359. trainLibSVM(dataMat,labelMat);
  360. //readTestFileList( testImageFile, testBasePath, testImageList);
  361. testLibSVM("libsvm_minist_model.model",testImageList,SVMModel);
  362. //testSVM( testImageList, SVMModel);
  363. releaseAll();
  364. return 0;
  365. }

libsvm Minist Hog 手写体识别(源码文件)的更多相关文章

  1. libsvm Minist Hog 手写体识别

    统计手写数字集的HOG特征 转载请注明出处,楼燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/ 这篇文章是模式识别的小作业,利用sv ...

  2. [C/C++] 各种C/C++编译器对UTF-8源码文件的兼容性测试(VC、GCC、BCB)

    在不同平台上开发C/C++程序时,为了避免源码文件乱码,得采用UTF-8编码来存储源码文件.但是很多编译器对UTF-8源码文件兼容性不佳,于是我做了一些测试,分析了最佳保存方案. 一.测试程序 为了测 ...

  3. 《UNIX网络编程(第3版)》unp.h等源码文件的编译安装

    操作系统:Mac OS X 10.11.5 1.下载书中的源代码:点击下载 2.切换到解压后的目录 unpv13e,先查看下 README,依次执行: ./configure cd lib make ...

  4. Erlang千万级用户游戏框架(Openpoker)源码文件分析清单

    openpoker源码 erlang写的网游服务器源码,OpenPoker是一个大型多人扑克网游,内建支持了容错能力,负载平衡和无限制的规模大小.本文是openpoker源码文件功能的一个清单式说明: ...

  5. C++ 多源码文件简单组织

    C++ 多源码文件简单组织 基本上和C的是一样的,只不过C++的方法要在类中声明.看一个简单实例.ainimal.h  类里面对外公开的信息. 点击(此处)折叠或打开 #ifndef _ANIMAL_ ...

  6. Python源码文件中带有中文时,输出乱码

    Python源码文件中带有中文时,文件头应加注释: #!/usr/bin/env python # -*- coding: utf-8 -*- 第一行注释是为了告诉Linux/OS X系统,这是一个P ...

  7. 对threading模块源码文件的解读(不全)

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #对threading模块源码文件的解读(不全) import threading #类 #Thread() ...

  8. TFS二次开发-基线文件管理器(5)-源码文件的读取

      在上一节中,我们在保存标签之前,已经将勾选的文件路径保存到了Listbox中,这里只需要将保存的数据输出去为txt文档就可以做版本控制了.   版本文件比较复杂的是如何读取,也就是如何通过文件路径 ...

  9. go语言的源码文件的分类及含义

    Go源码文件:名称以.go为后缀,内容以Go语言代码组织的文件 多个Go源码文件是需要用代码包组织起来的 源码文件分为三类:命令源码文件.库源码文件(go语言程序) 测试源码文件(辅助源码文件) 命令 ...

随机推荐

  1. javascript创建对象的几种方式

    javascript创建对象简单的说,无非就是使用内置对象或各种自定义对象,当然还可以用JSON:但写法有很多种,也能混合使用.主要为下面几种:1.对象字面量的方式 person={firstname ...

  2. js 将json对象转成字符串

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. firefox中flash经常崩溃

    建议: 1.安装flashblck插件 2.添加配置文件 在C:\Windows\SysWOW64\Macromed\Flash添加mmc.cfg. mmc.cfg的内容: SlientAutoUpd ...

  4. 传说中的AutoCAD公司 - 欧特克(Autodesk)招聘开发顾问-上海或北京

    如果您热衷新技术,垂涎科技前沿,对编程有狂热的热情,乐于帮助别人打造解决方案,喜爱分享和交流,英文沟通无障碍,来吧,把简历丢过来! 如果您刚毕业不久,那也不要因为工作经历尚浅而怯步,我们也非常欢迎您! ...

  5. SharePoint 2013 – Workflow Manager 1.0 offline download

    [http://sharepointdeal.wordpress.com/2013/03/13/sharepoint-2013-workflow-manager-1-0-offline-downloa ...

  6. Java解析Soap XML

    package com.jstrd.tipstock.webservice.jt.base; import java.io.ByteArrayInputStream; import java.util ...

  7. Map集合概述

    java集合最后一站之Map,给自己的总结画个句号... Map用于保存具有映射关系的数据. 1.HashMap和Hashtable实现类 HashMap和Hashtable都是Map接口的典型实现类 ...

  8. <转>关于Certificate、Provisioning Profile、App ID的介绍及其之间的关系

    转自:http://www.cnblogs.com/cywin888/p/3263027.html 刚接触iOS开发的人难免会对苹果的各种证书.配置文件等不甚了解,可能你按照网上的教程一步一步的成功申 ...

  9. mac 下如何切换jdk的版本

    1.打开.bash_profile文件添加一个函数 #add a function for switch idk version.function jdkset() { if [ $# -ne 0 ] ...

  10. 网络热恋之SDWebImage

    SDWebImage-master 是一个非常强大的三方. 当需要应用SDWeb时把文件夹里的SDWebImage文件夹放入工程里. 在需要使用网络获取图片的文件里进入头文件#import " ...