尝试创建功能SVM
。我有114个训练图像,60个阳性/ 54个阴性和386个测试图像,供SVM
预测。
我将训练图像功能读入float
,如下所示:
trainingDataFloat[i][0] = trainFeatures.rows;
trainingDataFloat[i][1] = trainFeatures.cols;
测试图像也一样:
testDataFloat[i][0] = testFeatures.rows;
testDataFloat[i][2] = testFeatures.cols;
然后,使用Micka的answer to this question,我将testDataFloat
转换为1维数组,然后将其提供给Mat
,以便在SVM
上进行预测:
float* testData1D = (float*)testDataFloat;
Mat testDataMat1D(height*width, 1, CV_32FC1, testData1D);
float testPredict = SVMmodel.predict(testDataMat1D);
一旦完成这一切,就会出现调试错误:
cvPreparePredictData中输入参数的大小不匹配(样本大小与训练时使用的大小不同)
看this post我发现(感谢berak):
“所有图片(用于培训和预测)必须具有相同的尺寸”
所以我添加了一个重新调整大小的函数,可以将图像重新调整为你希望的任何大小的正方形(100x100, 200x200, 1000, 1000 etc.
)
再次运行它,将图像重新调整为一个新目录,程序现在从中加载图像,我得到与以前完全相同的错误:
cvPreparePredictData中输入参数的大小不匹配(样本大小与训练时使用的大小不同)
我不知道该怎么办。为什么还会抛出这个错误?
修改
我改变了
Mat testDataMat1D(TestDFheight*TestDFwidth, 1, CV_32FC1, testData1D);
到
Mat testDataMat1D(1, TestDFheight*TestDFwidth, CV_32FC1, testData1D);
并将.predict
放置在features
给float
的循环中,以便每个图片因this question而单独提供给.predict
}。交换到int
以便.cols
= 1和.rows
= TestDFheight*TestDFwidth
程序似乎实际运行,但随后在图像160上停止(.exe has stopped working
) ......所以这是一个新的问题。
编辑2
添加了一个简单的
std::cout << testPredict;
要查看确定的SVM输出,它似乎正好匹配所有内容,直到它停止运行的图像160:
答案 0 :(得分:2)
请检查您的训练和测试特征向量。
我假设您的要素数据是某种形式的cv :: Mat,其中包含每行的功能。 在这种情况下,您希望训练矩阵是每个图像的每个特征矩阵的串联。 这些行看起来不正确:
trainingDataFloat[i][0] = trainFeatures.rows;
trainingDataFloat[i][1] = trainFeatures.cols;
这是将2d矩阵的元素设置为trainFeatures中的行数和列数。这与trainFeatures矩阵中的实际数据无关。
你想要检测什么?如果每个图像都是正面和反面的例子,那么您是否尝试检测图像中的某些内容?你有什么特色?
如果您尝试在每个图像的基础上检测图像中的对象,则需要在一个向量中描述整个图像的特征向量。在这种情况下,您可以使用您的培训数据执行此类操作:
int N; // Set to number of images you plan on using for training
int feature_size; // Set to the number of features extracted in each image. Should be constant across all images.
cv::Mat X = cv::Mat::zeros(N, feature_size, CV_32F); // Feature matrix
cv::Mat Y = cv::Mat::zeros(N, 1, CV_32F); // Label vector
// Now use a for loop to copy data into X and Y, Y = +1 for positive examples and -1 for negative examples
for(int i = 0; i < trainImages.size(); ++i)
{
X.row(i) = trainImages[i].features; // Where features is a cv::Mat row vector of size N of the extracted features
Y.row(i) = trainImages[i].isPositive ? 1:-1;
}
// Now train your cv::SVM on X and Y.