C++ opencv 2.3.1使用bow、svm训练图像和加载/保存功能

C++ opencv 2.3.1使用bow、svm训练图像和加载/保存功能,c++,xml,opencv,machine-learning,svm,C++,Xml,Opencv,Machine Learning,Svm,我是opencv的新手,尝试用opencv2.3.1对两个图像类别进行分类。 这是我的密码 void trainSVM(map<string,Mat>& classes_training_data, string& file_postfix, int response_cols, int response_type) { //train 1-vs-all SVMs vector<string> classes_names; for (map<str

我是opencv的新手,尝试用opencv2.3.1对两个图像类别进行分类。 这是我的密码

void trainSVM(map<string,Mat>& classes_training_data, string& file_postfix, int response_cols, int response_type) {

//train 1-vs-all SVMs
vector<string> classes_names;
for (map<string,Mat>::iterator it = classes_training_data.begin(); it != classes_training_data.end(); ++it) {
    classes_names.push_back((*it).first);
}

string use_postfix = file_postfix;
for (int i=0;i<classes_names.size();i++) {
    string class_ = classes_names[i];

    Mat samples(0,response_cols,response_type);
    Mat labels(0,1,CV_32FC1);

    //copy class samples and label
    cout << "adding " << classes_training_data[class_].rows << " positive" << endl;
    samples.push_back(classes_training_data[class_]);
    Mat class_label = Mat::ones(classes_training_data[class_].rows, 1, CV_32FC1);
    labels.push_back(class_label);

    //copy rest samples and label
    for (map<string,Mat>::iterator it1 = classes_training_data.begin(); it1 != classes_training_data.end(); ++it1) {
        string not_class_ = (*it1).first;
        if(not_class_.compare(class_)==0) continue;
        samples.push_back(classes_training_data[not_class_]);
        class_label = Mat::zeros(classes_training_data[not_class_].rows, 1, CV_32FC1);
        labels.push_back(class_label);
    }

    cout << "Train.." << endl;
    Mat samples_32f; samples.convertTo(samples_32f, CV_32F);
    if(samples.rows == 0) continue; //phantom class?!
    CvSVM classifier; 
    classifier.train(samples_32f,labels);

    {
        stringstream ss; 
        ss << "SVM_classifier_"; 
        if(file_postfix.size() > 0) ss << file_postfix << "_";
        ss << class_ << ".yml";
        cout << "Save.." << endl;
        classifier.save(ss.str().c_str());
    }
}
}
它运行正常。
svm.get\u support\u vector\u count()

这也是真的。 但当他补充说
svm.predict(描述符,false)

它将报告错误

"OpenCV Error: Bad argument (The sample is not a valid vector) in cvPreparePredictData, file ~/OpenCV-2.3.1/modules/ml/src/inner_functions.cpp, line 1099
terminate called after throwing an instance of 'cv::Exception'
  what():  ~/modules/ml/src/inner_functions.cpp:1099: error: (-5) The sample is not a valid vector in function cvPreparePredictData"
有什么能帮我解决这个问题吗


注意。

您好,可能您的预测变量
描述符
不是向量,通常
描述符的大小与您的单序列样本数据相同。
以下是我的opencv SVM示例代码:

int sample_num = 100;
int feature_size = 256;
Mat_<float> train_data(sample_num,feature_size);
//put your train sample datas
...
Mat_<int> label_data(sample_num,1);
//put your train sample label
TermCriteria criteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
SVMParams param( SVM::C_SVC, SVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, criteria );
SVM svm;
//svm training
svm.train(train_data, label_data, Mat(), Mat(), param);
svm.save("svmtest.xml");
SVM _svm;
_svm.load("svmtest.xml");
Mat_<float> test_data(1,feature_size);
//put your test data
...
int predict_label = _svm.predict(test_data);
int sample_num=100;
int feature_size=256;
物料序列数据(样本数量、特征尺寸);
//把你的火车样本数据
...
材料标签数据(样本数量,1);
//把你的火车样品贴上标签
术语标准(CV_TERMCRIT_EPS,1000,FLT_EPSILON);
SVMParams参数(SVM::C_SVC,SVM::RBF,10.0,8.0,1.0,10.0,0.5,0.1,空,标准);
支持向量机;
//支持向量机训练
训练(训练数据、标签数据、Mat()、Mat()、参数);
save(“svmtest.xml”);
支持向量机;
_load(“svmtest.xml”);
材料试验数据(1,特征尺寸);
//把你的测试数据
...
int predict_label=_svm.predict(测试数据);

我认为您缺少了词汇量。在加载保存在.yml文件中的经过培训的数据之前,您必须保存您的词汇量:当您使用BOW描述符(BOWImgDescriptorExtractor和bowkmeanfilter)时,因此,您可以将其加载到另一个项目中,并使用它计算测试图像的新描述符,并使用保存的yml文件进行培训。希望这能帮助您

我已经纠正了您示例中的代码。谢谢你的帮助!由于GFW,我很长时间无法登录堆栈溢出。。。哈哈 原来都是中国人啊。。。。。顺手点个赞呗~哈哈,今天最大的乐趣...声望不够点不了呀嗯嗯 没关系 加油 一起刷声望 我也是刚开始`谢谢你的回答!我成功地保存了词汇表文件。
int sample_num = 100;
int feature_size = 256;
Mat_<float> train_data(sample_num,feature_size);
//put your train sample datas
...
Mat_<int> label_data(sample_num,1);
//put your train sample label
TermCriteria criteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
SVMParams param( SVM::C_SVC, SVM::RBF, 10.0, 8.0, 1.0, 10.0, 0.5, 0.1, NULL, criteria );
SVM svm;
//svm training
svm.train(train_data, label_data, Mat(), Mat(), param);
svm.save("svmtest.xml");
SVM _svm;
_svm.load("svmtest.xml");
Mat_<float> test_data(1,feature_size);
//put your test data
...
int predict_label = _svm.predict(test_data);