我正在尝试调用SVM.train()
计算出的训练数据上的HOGDescriptor
。
HOGDescriptor hog = HOGDescriptor();
vector<Mat> gradients;
compute(trainingImgs, gradients);
cout << "descriptors generated: " << gradients[0].size() << endl;
vector<int> labels;
labels.assign(gradients.size(), 1);
//set up SVM properties
Ptr<SVM> svm = SVM::create();
svm->setCoef0(0.0);
svm->setDegree(3);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 1000, 1e-3));
svm->setGamma(0);
svm->setKernel(SVM::LINEAR);
svm->setNu(0.5);
svm->setP(0.1); // for EPSILON_SVR, epsilon in loss function?
svm->setC(0.01); // From paper, soft classifier
svm->setType(SVM::EPS_SVR); // C_SVC; // EPSILON_SVR; // may be also NU_SVR; // do regression task
//max length of the descriptor vectors, I am a maths programmer now
int n = gradients[0].rows;
Mat trainData = Mat(gradients.size(), gradients[0].rows, CV_32FC1);
cout << "trainData size: " << trainData.rows << "x" << trainData.cols << endl;
Mat tmp(1, n, CV_32FC1);
for (int i = 0; i < gradients.size(); i++)
{
//this would probably be better as a single operation butfuckit
transpose(gradients[i], tmp);
tmp.copyTo(trainData.row((int)i));
cout << "arbitrary item in " << i << "th Mat: " << trainData.at<float>(i, 93426) << endl;
}
cout << "copy operation complete" << endl;
//actually train the SVM
svm->train(trainData, ROW_SAMPLE, labels);
cout << "training complete" << endl;
计算定义为
void compute(const vector<Mat> &imgs, vector<Mat>& gradList)
{
HOGDescriptor hog;
vector<float> descriptors;
for (int i = 0; i < imgs.size(); i++)
{
hog.compute(imgs[i], descriptors, Size(8, 8), Size(0, 0));
gradList.push_back(Mat(descriptors).clone());
}
}
和trainingImgs
是5张测试训练图像(全部相同)中的vector<Mat>
。
问题在于svm->train()
调用会生成Error: Assertion failed (sv_count != 0)
。
我可以找到的关于此错误的唯一信息是,它可能意味着训练数据为空,但看起来似乎什么都不是,只是打印到控制台上之后。
从source code看来,sv_count
是其对应的_alpha
值大于0的样本数,但是我无法跟踪生成_alpha
值的位置
我正在使用Visual Studio 2019中的CMake构建OpenCV(4.1.2-dev)
。
感谢您的帮助。