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


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

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

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

    特征提取功能的实现:

    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训练的实现代码:

    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.     }  


    测试功能的实现代码:

    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

  • 相关阅读:
    一些集群操作以及问题查询
    .a 文件 和 so 文件
    KNN算法
    opendir函数和readdir函数内涵及用法
    tps 和 qps的区别
    Git使用(积累一些常用的命令)
    MurmurHash
    HyperLogLog
    MySQL主从不生效且无错误
    正则表达式与SQL
  • 原文地址:https://www.cnblogs.com/lingtianyulong/p/4253782.html
Copyright © 2020-2023  润新知