首页 > 代码库 > 基于SVM+HOG的花生品种识别

基于SVM+HOG的花生品种识别

早在大二时,导师做过一个花生品种识别的程序,但当时用于品种识别的特征是自定义特征;而我的当初的本科毕业设计则是基于SVM + HOG的人脸识别;在后来的工作学习中,又用到了HOG特征,想着是不是之前的花生品种的识别也能用Hog特征进行识别;正所谓学以致用,也能巩固下刚刚所学的知识;

所谓的Hog特征与SVM网上资料一大堆,而且讲解得非常详细,在这里不在做过多的讲解;

 

本程序的开发环境,主要是依赖于VS2013 + OpenCV2.4.9,开发环境,请自行配置,那么,下面贴出代码,不足之处,请各位大侠不吝批评指正:

特征提取功能的实现:

 

[cpp] view plaincopyprint?技术分享技术分享
 
  1. CvMat* dataMat = NULL;  
  2. Book* book = xlCreateBook();  
  3. Sheet* sheet = book->addSheet("Sheet1");  
  4.   
  5. for (int j = 1; j <= 13; ++ j)  
  6. {  
  7.     CString strLoadPath = "SubImage\\";  
  8.     CString strFile;  
  9.     strFile.Format("s%d", j);  
  10.     strLoadPath = strLoadPath + strFile + "\\";  
  11.   
  12.     for (int i = 1; i <= 45; ++i)  
  13.     {  
  14.         CString loadPath = strLoadPath;  
  15.         CString stri;  
  16.         stri.Format("%d.jpg", i);  
  17.         loadPath = loadPath + stri;  
  18.   
  19.         IplImage* srcImage = cvLoadImage(loadPath);  
  20.         IplImage* grayImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1);  
  21.         IplImage* hogImage = cvCreateImage(cvSize(96, 64), IPL_DEPTH_8U, 1);        //用于提取Hog特征的图像  
  22.   
  23.         cvCvtColor(srcImage, grayImage, CV_RGB2GRAY);  
  24.   
  25.         cvResize(grayImage, hogImage, CV_INTER_LINEAR);   //线性插值  
  26.   
  27.         std::vector<float> vfDescriptors;  
  28.         //vfDescriptors.resize(hogImage->width * hogImage->height);  
  29.         cv::Ptr<cv::HOGDescriptor> hog = new cv::HOGDescriptor(cvSize(hogImage->width, hogImage->height), cvSize(16, 16), cvSize(8, 8), cvSize(8, 8), 9);  
  30.         hog->compute(hogImage, vfDescriptors, cv::Size(1, 1), cv::Size(0, 0));       //使用计算函数进行计算  
  31.   
  32.         //CvMat* mat = cvCreateMat(45 * 13, vfDescriptors.size(), CV_32FC1);  
  33.         //cvZero(mat);  
  34.   
  35.         int cols = 0;  
  36.   
  37.         for (auto it = vfDescriptors.begin(); it != vfDescriptors.end(); ++it)  
  38.         {  
  39.             if (sheet)  
  40.             {  
  41.                 sheet->writeNum(45 * (j-1) + (i - 1), cols++, *it);    //把Hog数据存储到Excel 中  
  42.             }  
  43.         }  
  44.   
  45.         //释放内存  
  46.         cvReleaseImage(&srcImage);  
  47.         srcImage = NULL;  
  48.         cvReleaseImage(&grayImage);  
  49.         grayImage = NULL;  
  50.         cvReleaseImage(&hogImage);  
  51.         hogImage = NULL;  
  52.   
  53.     }// 内层 for 循环  
  54.   
  55. }  
  56.   
  57. book->save("Hog.xls");  
  58. book->release();  


SVM训练的实现代码:

 

 

[cpp] view plaincopyprint?技术分享技术分享
 
  1. Book* book = xlCreateBook();  
  2.   
  3.     if (book->load("Hog.xls"))  
  4.     {  
  5.         Sheet* sheet = book->getSheet(0);  
  6.   
  7.         if (sheet)  
  8.         {  
  9.   
  10.             CvMat* dataMat = cvCreateMat(sheet->lastRow(), sheet->lastCol(), CV_32FC1);       //存储导入的数据  
  11.   
  12.             for (int i = 0; i < sheet->lastRow(); ++ i)  
  13.             {  
  14.                 for (int j = 0; j < sheet->lastCol(); ++ j)  
  15.                 {  
  16.                     double temp = sheet->readNum(i, j);  
  17.                     cvSetReal2D(dataMat, i, j, temp);  
  18.                 }  
  19.             }  
  20.               
  21.             MessageBox("数据导入完成");  
  22.   
  23.             CvMat* lableMat = cvCreateMat(sheet->lastRow(), 1, CV_32FC1);  
  24.             cvZero(lableMat);  
  25.   
  26.             for (int i = 0; i < 13; ++ i)  
  27.             {  
  28.                 for (int j = 0; j < 45; ++ j)  
  29.                 {  
  30.                     cvSetReal2D(lableMat, i * 45 + j, 0, i + 1);  
  31.                 }  
  32.             }  
  33.   
  34.             CvSVM svm;  
  35.             CvSVMParams svmParams;                      //向量机参数  
  36.             CvTermCriteria  svmCriteria;                //迭代中止条件  
  37.             svmCriteria = cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);  
  38.   
  39.             svmParams = CvSVMParams(CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, svmCriteria);  
  40.   
  41.             //利用训练数据和确定的学习参数,进行SVM学习  
  42.             svm.train(dataMat, lableMat, NULL, NULL, svmParams);  
  43.             svm.save("svm.xml");  
  44.   
  45.             //以下代码用于SVM识别  
  46.             CvMat* svmResult = cvCreateMat(sheet->lastRow(), 1, CV_32FC1);  
  47.             CvMat* svmRow = NULL;  
  48.   
  49.             for (int i = 0; i < sheet->lastRow(); ++ i)  
  50.             {  
  51.                 svmRow = cvCreateMat(1, sheet->lastCol(), CV_32FC1);  
  52.   
  53.                 for (int j = 0; j < sheet->lastCol(); ++ j)  
  54.                 {  
  55.                     float temp = cvGetReal2D(dataMat, i, j);  
  56.                     cvSetReal2D(svmRow, 0, j, temp);  
  57.                 }  
  58.   
  59.                 unsigned int ret = 0;  
  60.                 ret = svm.predict(svmRow);  
  61.                 cvSetReal2D(svmResult, i, 0, ret);  
  62.   
  63.                 cvReleaseMat(&svmRow);  
  64.                 svmRow = NULL;  
  65.             }  
  66.   
  67.             int nCount = 0;  
  68.   
  69.             for (int i = 0; i < 13; ++i)  
  70.             {  
  71.                 for (int j = 0; j < 45; ++ j)  
  72.                 {  
  73.                     int ret = cvGetReal2D(svmResult, i * 45 + j, 0);  
  74.                     if (ret == (i + 1))  
  75.                     {  
  76.                         ++nCount;  
  77.                     }  
  78.                 }  
  79.             }  
  80.   
  81.             float recognize = 100 * nCount / 13 / 45;  
  82.   
  83.             CString str;  
  84.             str.Format("SVM 识别率为: %f", recognize);  
  85.             str = str + "%";  
  86.             MessageBox(str);  
  87.   
  88.         }  
  89.     }  


测试功能的实现代码:

 

 

[cpp] view plaincopyprint?技术分享技术分享
 
  1. CvSVM svm;  
  2.     svm.load("svm.xml");  
  3.   
  4.     CFileDialog dlg(TRUE, NULL, NULL, 0, "图片文件(*.jpg)|*.jpg||");  
  5.     if (dlg.DoModal() == IDOK)  
  6.     {  
  7.         IplImage* testImage = cvLoadImage(dlg.GetPathName());  
  8.         IplImage* grayImage = cvCreateImage(cvGetSize(testImage), IPL_DEPTH_8U, 1);  
  9.         IplImage* hogImage = cvCreateImage(cvSize(96, 64), IPL_DEPTH_8U, 1);  
  10.   
  11.         cvCvtColor(testImage, grayImage, CV_RGB2GRAY);  
  12.         cvResize(grayImage, hogImage, CV_INTER_LINEAR);  
  13.   
  14.         std::vector<float> vfDescriptors;  
  15.         //vfDescriptors.resize(hogImage->width * hogImage->height);  
  16.         cv::Ptr<cv::HOGDescriptor> hog = new cv::HOGDescriptor(cvSize(hogImage->width, hogImage->height), cvSize(16, 16), cvSize(8, 8), cvSize(8, 8), 9);  
  17.         hog->compute(hogImage, vfDescriptors, cv::Size(1, 1), cv::Size(0, 0));       //使用计算函数进行计算  
  18.       
  19.         CvMat* mat = cvCreateMat(1, 256, CV_32FC1);  
  20.   
  21.         int cols = 0;  
  22.   
  23.         for (auto it = 0; it < 256; ++it)  
  24.         {  
  25.             cvSetReal2D(mat, 0, it, vfDescriptors[it]);  
  26.         }  
  27.   
  28.       
  29.         int  ret = svm.predict(mat);  
  30.         CString str;  
  31.         switch (ret)  
  32.         {  
  33.         case 1:  
  34.             str = "品种1:P12";  
  35.             break;  
  36.         case 2:  
  37.             str = "品种2:矮2";  
  38.             break;  
  39.         case 3:  
  40.             str = "品种3:花玉22";  
  41.             break;  
  42.         case 4:  
  43.             str = "品种4:花玉25";  
  44.             break;  
  45.         case 5:  
  46.             str = "品种5:冀花2号";  
  47.             break;  
  48.         case 6:  
  49.             str = "品种6:冀花4号";  
  50.             break;  
  51.         case 7:  
  52.             str = "品种7:冀花5号";  
  53.             break;  
  54.         case 8:  
  55.             str = "品种8:鲁花9号";  
  56.             break;  
  57.         case 9:  
  58.             str = "品种9:青花6号";  
  59.             break;  
  60.         case 10:  
  61.             str = "品种10:天府3号";  
  62.             break;  
  63.         case 11:  
  64.             str = "品种11:维花8号";  
  65.             break;  
  66.         case 12:  
  67.             str = "品种12:小白沙";  
  68.             break;  
  69.         case 13:  
  70.             str = "品种13:中农108";  
  71.             break;  
  72.         }  
  73.         AfxMessageBox(str);  
  74.         //cvReleaseMat(&mat);  
  75.     }//end if     


相关的程序代码,用于测试的图像样本及程序中用到的操作 Excel 的类,已经打包上传到CSDN,请自行下载:http://download.csdn.net/detail/lingtianyulong/8377461

基于SVM+HOG的花生品种识别