应用OpenCV正态贝叶斯分类器的时候,在网上找的例子数据都是静态数组。本人想用c++ STL中的vector来对数据进行组织,达到样本长度可变的目的。但是程序一直报断言错误,类似于error assertion failed ( 0 <= i && i < <int> vv.size())......
问题一直没解决,但是通过其他方式避免了该错误。最终代码如下:
vector<vector<float> > vecSamples/*, vecTestSamples*/;
vector<int> vecLabels/*, vecTestLabels*/;
map<string, myData>::const_iterator it = m_mapData.begin();
for (; it != m_mapData.end(); it++)
{
vecLabels.push_back(it->second.label);
vector<float> tmpSample;
for (int i = 0; i < it->second.vecCh.size(); i++)//特征数量可能会随着研究深入而改变,因此希望以vector进行组织
tmpSample.push_back(itCar->second.vecCh[i]);
vecSamples.push_back(tmpSample);
}
//将样本的四分之三作为训练样本,另四分之一作为测试样本
int trainPos = vecSamples.size() * 3 / 4;
vector<int> size{ trainPos, (int)vecSamples.front().size()};
vector<int> vecTLabels;
vecTLabels.insert(vecTLabels.begin(), vecLabels.begin(), vecLabels.begin() + trainPos);
cv::Mat labelsMat(vecTLabels), tdataMat(size, CV_32FC1);
for (int i = 0; i < trainPos; i++){
for (int j = 0; j < vecSamples[i].size(); j++){
tdataMat.at<float>(i, j) = vecSamples[i][j];
}
}
cv::Ptr<cv::ml::NormalBayesClassifier> pNBC = cv::ml::NormalBayesClassifier::create();
cv::Ptr<cv::ml::TrainData> tData = cv::ml::TrainData::create(tdataMat, cv::ml::ROW_SAMPLE, labelsMat);
cout << "开始训练。" << endl;
pNBC->train(tData);
//测试样本,统计正确率
int corractCnt(0), testCnt(vecSamples.size() - trainPos);
for (int i = trainPos; i < vecSamples.size(); i++){
//cv::Mat testMat(vecSamples[i]);
cv::Mat testMat(1, vecSamples[i].size(), CV_32FC1);
for (int j = 0; j < vecSamples[i].size(); j++)
testMat.at<float>(j) = vecSamples[i][j];
int response = pNBC->predict(testMat);
if (response == vecLabels[i])
corractCnt++;
}
cout << "训练样本数: " << trainPos << endl;
cout << "测试样本数: " << testCnt << endl;
cout << "测试正确率: " << setprecision(2) << (float)corractCnt / testCnt * 100 << "%" << endl;
注:TrainData::create()输入参数InputArray虽然可以用vector<vector<>>创建,但是我在使用的时候会报错,并没有找到解决方法。最终采用上述代码避开了这个错误。
本人新手,欢迎大家前来讨论指点。