我有一个基于训练自己的SVM来检测特定轮廓的项目。我写了一些代码,但是没有用,所以我想确保我一切都很好。我还想提到我是OpenCV世界的新手,如果我写一些愚蠢的东西,对不起,这是我的想象:
1)首先,我收集一些材料进行培训。我创建了两个文件夹,其中包含一些正样本(我要检测的轮廓-大约200个样本)和负文件夹(各不相同-大约1300个样本)。图片为64x128。
2)第二步是创建每个样本的特征向量。在这里,我不确定图片中的哪些信息很重要。在我的情况下,我在图片上使用HOG并将每个像素的梯度放在特征向量上,但也许最好从HSV图片中获取H值?这是一些代码:
std::vector<float> featureVector;
hog.compute(image, featureVector);
3)我创建Mat来保留所有这些向量。 1行= 1个特征向量。因此,例如,当我有1500个样本时,我得到了1500行矩阵。这是我的方法:
trainingData = cv::Mat::ones(sizePositive + sizeNegative, 3780, CV_32FC1);
labels = cv::Mat::zeros(sizePositive + sizeNegative, 1, CV_32S);
for (int i = 0; i < sizePositive; i++)
{
for (int j = 0; j < 3780; j++)
{
trainingData.at<float>(i, j) = features[j];
}
labels.at<int>(i, 0) = 1;
}
for (int i = 0; i < sizeNegative; i++)
{
std::vector<float> features = calculateFeatures(filenamesNegative[i]);
for (int j = 0; j < 3780; j++)
{
trainingData.at<float>(i+sizePositive, j) = features[j];
}
labels.at<int>(i+sizePositive, 0) = -1;
}
在这一步中,我还创建标签矩阵,当它是正样本时放置1,当它是负样本时放置-1。
4)之后,我准备好训练了吗?我具有带有特征向量和标签的trainingData,该标签定义了哪个样本为阳性和哪个样本为阴性。 (我用标签和trainingData检查了XML文件,它们看起来不错)。这是我训练SVM的方法:
cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
// set the parameters
svm->setType(cv::ml::SVM::C_SVC);
svm->setKernel(cv::ml::SVM::LINEAR);
// create training data object
cv::Ptr<cv::ml::TrainData> tData = cv::ml::TrainData::create(trainingData, cv::ml::SampleTypes::ROW_SAMPLE, labels);
// train svm to optimal parameters using opencv autotraining
svm->trainAuto(tData);
您怎么看?这是好主意吗?我做错了吗?因为似乎该SVM没有学任何东西:/ 感谢您的帮助和建议。