首页 > 代码库 > 基于SVM+HOG的花生品种识别
基于SVM+HOG的花生品种识别
早在大二时,导师做过一个花生品种识别的程序,但当时用于品种识别的特征是自定义特征;而我的当初的本科毕业设计则是基于SVM + HOG的人脸识别;在后来的工作学习中,又用到了HOG特征,想着是不是之前的花生品种的识别也能用Hog特征进行识别;正所谓学以致用,也能巩固下刚刚所学的知识;
所谓的Hog特征与SVM网上资料一大堆,而且讲解得非常详细,在这里不在做过多的讲解;
本程序的开发环境,主要是依赖于VS2013 + OpenCV2.4.9,开发环境,请自行配置,那么,下面贴出代码,不足之处,请各位大侠不吝批评指正:
特征提取功能的实现:
[cpp] view plaincopyprint?
- CvMat* dataMat = NULL;
- Book* book = xlCreateBook();
- Sheet* sheet = book->addSheet("Sheet1");
- for (int j = 1; j <= 13; ++ j)
- {
- CString strLoadPath = "SubImage\\";
- CString strFile;
- strFile.Format("s%d", j);
- strLoadPath = strLoadPath + strFile + "\\";
- for (int i = 1; i <= 45; ++i)
- {
- CString loadPath = strLoadPath;
- CString stri;
- stri.Format("%d.jpg", i);
- loadPath = loadPath + stri;
- IplImage* srcImage = cvLoadImage(loadPath);
- IplImage* grayImage = cvCreateImage(cvGetSize(srcImage), IPL_DEPTH_8U, 1);
- IplImage* hogImage = cvCreateImage(cvSize(96, 64), IPL_DEPTH_8U, 1); //用于提取Hog特征的图像
- cvCvtColor(srcImage, grayImage, CV_RGB2GRAY);
- cvResize(grayImage, hogImage, CV_INTER_LINEAR); //线性插值
- std::vector<float> vfDescriptors;
- //vfDescriptors.resize(hogImage->width * hogImage->height);
- cv::Ptr<cv::HOGDescriptor> hog = new cv::HOGDescriptor(cvSize(hogImage->width, hogImage->height), cvSize(16, 16), cvSize(8, 8), cvSize(8, 8), 9);
- hog->compute(hogImage, vfDescriptors, cv::Size(1, 1), cv::Size(0, 0)); //使用计算函数进行计算
- //CvMat* mat = cvCreateMat(45 * 13, vfDescriptors.size(), CV_32FC1);
- //cvZero(mat);
- int cols = 0;
- for (auto it = vfDescriptors.begin(); it != vfDescriptors.end(); ++it)
- {
- if (sheet)
- {
- sheet->writeNum(45 * (j-1) + (i - 1), cols++, *it); //把Hog数据存储到Excel 中
- }
- }
- //释放内存
- cvReleaseImage(&srcImage);
- srcImage = NULL;
- cvReleaseImage(&grayImage);
- grayImage = NULL;
- cvReleaseImage(&hogImage);
- hogImage = NULL;
- }// 内层 for 循环
- }
- book->save("Hog.xls");
- book->release();
SVM训练的实现代码:
[cpp] view plaincopyprint?
- Book* book = xlCreateBook();
- if (book->load("Hog.xls"))
- {
- Sheet* sheet = book->getSheet(0);
- if (sheet)
- {
- CvMat* dataMat = cvCreateMat(sheet->lastRow(), sheet->lastCol(), CV_32FC1); //存储导入的数据
- for (int i = 0; i < sheet->lastRow(); ++ i)
- {
- for (int j = 0; j < sheet->lastCol(); ++ j)
- {
- double temp = sheet->readNum(i, j);
- cvSetReal2D(dataMat, i, j, temp);
- }
- }
- MessageBox("数据导入完成");
- CvMat* lableMat = cvCreateMat(sheet->lastRow(), 1, CV_32FC1);
- cvZero(lableMat);
- for (int i = 0; i < 13; ++ i)
- {
- for (int j = 0; j < 45; ++ j)
- {
- cvSetReal2D(lableMat, i * 45 + j, 0, i + 1);
- }
- }
- CvSVM svm;
- CvSVMParams svmParams; //向量机参数
- CvTermCriteria svmCriteria; //迭代中止条件
- svmCriteria = cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);
- svmParams = CvSVMParams(CvSVM::C_SVC, CvSVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, svmCriteria);
- //利用训练数据和确定的学习参数,进行SVM学习
- svm.train(dataMat, lableMat, NULL, NULL, svmParams);
- svm.save("svm.xml");
- //以下代码用于SVM识别
- CvMat* svmResult = cvCreateMat(sheet->lastRow(), 1, CV_32FC1);
- CvMat* svmRow = NULL;
- for (int i = 0; i < sheet->lastRow(); ++ i)
- {
- svmRow = cvCreateMat(1, sheet->lastCol(), CV_32FC1);
- for (int j = 0; j < sheet->lastCol(); ++ j)
- {
- float temp = cvGetReal2D(dataMat, i, j);
- cvSetReal2D(svmRow, 0, j, temp);
- }
- unsigned int ret = 0;
- ret = svm.predict(svmRow);
- cvSetReal2D(svmResult, i, 0, ret);
- cvReleaseMat(&svmRow);
- svmRow = NULL;
- }
- int nCount = 0;
- for (int i = 0; i < 13; ++i)
- {
- for (int j = 0; j < 45; ++ j)
- {
- int ret = cvGetReal2D(svmResult, i * 45 + j, 0);
- if (ret == (i + 1))
- {
- ++nCount;
- }
- }
- }
- float recognize = 100 * nCount / 13 / 45;
- CString str;
- str.Format("SVM 识别率为: %f", recognize);
- str = str + "%";
- MessageBox(str);
- }
- }
测试功能的实现代码:
[cpp] view plaincopyprint?
- CvSVM svm;
- svm.load("svm.xml");
- CFileDialog dlg(TRUE, NULL, NULL, 0, "图片文件(*.jpg)|*.jpg||");
- if (dlg.DoModal() == IDOK)
- {
- IplImage* testImage = cvLoadImage(dlg.GetPathName());
- IplImage* grayImage = cvCreateImage(cvGetSize(testImage), IPL_DEPTH_8U, 1);
- IplImage* hogImage = cvCreateImage(cvSize(96, 64), IPL_DEPTH_8U, 1);
- cvCvtColor(testImage, grayImage, CV_RGB2GRAY);
- cvResize(grayImage, hogImage, CV_INTER_LINEAR);
- std::vector<float> vfDescriptors;
- //vfDescriptors.resize(hogImage->width * hogImage->height);
- cv::Ptr<cv::HOGDescriptor> hog = new cv::HOGDescriptor(cvSize(hogImage->width, hogImage->height), cvSize(16, 16), cvSize(8, 8), cvSize(8, 8), 9);
- hog->compute(hogImage, vfDescriptors, cv::Size(1, 1), cv::Size(0, 0)); //使用计算函数进行计算
- CvMat* mat = cvCreateMat(1, 256, CV_32FC1);
- int cols = 0;
- for (auto it = 0; it < 256; ++it)
- {
- cvSetReal2D(mat, 0, it, vfDescriptors[it]);
- }
- int ret = svm.predict(mat);
- CString str;
- switch (ret)
- {
- case 1:
- str = "品种1:P12";
- break;
- case 2:
- str = "品种2:矮2";
- break;
- case 3:
- str = "品种3:花玉22";
- break;
- case 4:
- str = "品种4:花玉25";
- break;
- case 5:
- str = "品种5:冀花2号";
- break;
- case 6:
- str = "品种6:冀花4号";
- break;
- case 7:
- str = "品种7:冀花5号";
- break;
- case 8:
- str = "品种8:鲁花9号";
- break;
- case 9:
- str = "品种9:青花6号";
- break;
- case 10:
- str = "品种10:天府3号";
- break;
- case 11:
- str = "品种11:维花8号";
- break;
- case 12:
- str = "品种12:小白沙";
- break;
- case 13:
- str = "品种13:中农108";
- break;
- }
- AfxMessageBox(str);
- //cvReleaseMat(&mat);
- }//end if
相关的程序代码,用于测试的图像样本及程序中用到的操作 Excel 的类,已经打包上传到CSDN,请自行下载:http://download.csdn.net/detail/lingtianyulong/8377461
基于SVM+HOG的花生品种识别
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。