OpenCV中的HOG+SVM物体分类 问题

康王1991 2016-07-08 11:16:10
最近在学习分类器匹配的类容,参考了一篇博客:http://blog.csdn.net/a784763307/article/details/17307093

引用程序如下:
#include "cv.h"  
#include "highgui.h"
#include "stdafx.h"
#include <ml.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace cv;
using namespace std;


int main(int argc, char** argv)
{
int ImgWidht = 160;
int ImgHeight = 120;
vector<string> img_path;
vector<int> img_catg;
int nLine = 0;
string buf;
ifstream svm_data("C:/Users/zhiwen/Desktop/SVMHOG/SVMHOG/SVM_DATA.txt");//D:\王志文\C++资料夹\C++编程小练习\SVMHOG\SVMHOG中文路径错误
unsigned long n;

while (svm_data)
{
if (getline(svm_data, buf))
{
nLine++;
if (nLine < 5)
{
img_catg.push_back(1);
img_path.push_back(buf);//图像路径
}
else
{
img_catg.push_back(0);
img_path.push_back(buf);//图像路径
}
}
}
svm_data.close();//关闭文件

Mat data_mat, res_mat;
int nImgNum = nLine; //读入样本数量
////样本矩阵,nImgNum:横坐标是样本数量, WIDTH * HEIGHT:样本特征向量,即图像大小
//data_mat = Mat::zeros( nImgNum, 12996, CV_32FC1 );
//类型矩阵,存储每个样本的类型标志
res_mat = Mat::zeros(nImgNum, 1, CV_32FC1);

Mat src;
Mat trainImg = Mat::zeros(ImgHeight, ImgWidht, CV_8UC3);//需要分析的图片

for (string::size_type i = 0; i != img_path.size(); i++)
{
src = imread(img_path[i].c_str(), 1);

cout << " processing " << img_path[i].c_str() << endl;

resize(src, trainImg, cv::Size(ImgWidht, ImgHeight), 0, 0, INTER_CUBIC);//---------------------出现错误中断(监视发现图片并没有读取成功,最好不用中文路径名)
HOGDescriptor *hog = new HOGDescriptor(cvSize(ImgWidht, ImgHeight), cvSize(16, 16), cvSize(8, 8), cvSize(8, 8), 9); //具体参数变换160*120的原因
vector<float>descriptors;//结果数组
hog->compute(trainImg, descriptors, Size(1, 1), Size(0, 0)); //调用计算函数开始计算
if (i == 0)
{
data_mat = Mat::zeros(nImgNum, descriptors.size(), CV_32FC1); //根据输入图片大小进行分配空间
}
cout << "HOG dims: " << descriptors.size() << endl;
n = 0;
for (vector<float>::iterator iter = descriptors.begin(); iter != descriptors.end(); iter++)
{
data_mat.at<float>(i, n) = *iter;
n++;
}
//cout<<SVMtrainMat->rows<<endl;
res_mat.at<float>(i, 0) = img_catg[i];
cout << " end processing " << img_path[i].c_str() << " " << img_catg[i] << endl;
}

CvSVM svm ;
CvSVMParams param;
CvTermCriteria criteria;
criteria = cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON);
param = CvSVMParams(CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria);

/*
SVM种类:CvSVM::C_SVC
Kernel的种类:CvSVM::RBF
degree:10.0(此次不使用)
gamma:8.0
coef0:1.0(此次不使用)
C:10.0
nu:0.5(此次不使用)
p:0.1(此次不使用)
然后对训练数据正规化处理,并放在CvMat型的数组里。
*/
//(5)SVM学习
svm.train(data_mat, res_mat, Mat(), Mat(), param);
//利用训练数据和确定的学习参数,进行SVM学习
svm.save("C:/Users/zhiwen/Desktop/SVMHOG/SVMHOG/SVM_DATA.xml");

//检测样本
vector<string> img_tst_path;
ifstream img_tst("C:/Users/zhiwen/Desktop/SVMHOG/SVMHOG/SVM_TEST.txt");
while (img_tst)
{
if (getline(img_tst, buf))
{
img_tst_path.push_back(buf);
}
}
img_tst.close();

Mat test;
char line[512];
ofstream predict_txt("C:/Users/zhiwen/Desktop/SVMHOG/SVMHOG/SVM_PREDICT.txt");
for (string::size_type j = 0; j != img_tst_path.size(); j++)
{
test = imread(img_tst_path[j].c_str(), 1);//读入图像
resize(test, trainImg, cv::Size(ImgWidht, ImgHeight), 0, 0, INTER_CUBIC);//要搞成同样的大小才可以检测到
HOGDescriptor *hog = new HOGDescriptor(cvSize(ImgWidht, ImgHeight), cvSize(16, 16), cvSize(8, 8), cvSize(8, 8), 9); //具体意思见参考文章1,2
vector<float>descriptors;//结果数组
hog->compute(trainImg, descriptors, Size(1, 1), Size(0, 0)); //调用计算函数开始计算
cout << "The Detection Result:" << endl;
cout << "HOG dims: " << descriptors.size() << endl;
Mat SVMtrainMat = Mat::zeros(1, descriptors.size(), CV_32FC1);
n = 0;
for (vector<float>::iterator iter = descriptors.begin(); iter != descriptors.end(); iter++)
{
SVMtrainMat.at<float>(0, n) = *iter;
n++;
}

int ret = svm.predict(SVMtrainMat);
std::sprintf(line, "%s %d\r\n", img_tst_path[j].c_str(), ret);
printf("%s %d\r\n", img_tst_path[j].c_str(), ret);
getchar();
predict_txt << line;
}
predict_txt.close();

return 0;
}


结果调试时发现,可以读取SVM_DATA.TXT里的第一附图存入数组,当FOR读取第二幅就会出错中断,不知道是不是溢出问题?还是什么问题,SVM_DATA.TXT如下:




程序出错点


谢谢指教。
...全文
654 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2016-07-08
  • 打赏
  • 举报
回复
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒:再牛×的老师也无法代替学生自己领悟和上厕所! 单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧