C++ OpenCV SVM 预测不起作用

标签 c++ opencv machine-learning svm

尝试创建一个功能性的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 转换为一维数组,并将其输入到 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 等)

再次运行它,将图像大小调整到一个新目录,程序现在从该目录加载图像,我得到了与之前完全相同的错误:

cvPreparePredictData 中输入参数的大小不匹配(样本大小与用于训练的样本大小不同)

我只是不知道该做什么了。为什么它仍然抛出该错误?

编辑

我变了

Mat testDataMat1D(TestDFheight*TestDFwidth, 1, CV_32FC1, testData1D);

Mat testDataMat1D(1, TestDFheight*TestDFwidth, CV_32FC1, testData1D);

并将 .predict 放置在将 features 赋予 float 的循环内,以便将每个图像赋予 >.predict 单独因为 this question 。将 int 交换后,.cols = 1 且 .rows = TestDFheight*TestDFwidth 程序似乎实际上运行,但随后停止在图像 160 上(.exe 已停止工作)...所以这是一个新问题。

编辑2

添加了一个简单的

std::cout << testPredict;

要查看 SVM 的确定输出,它似乎与所有内容都完全匹配,直到图像 160,它停止运行:

最佳答案

请检查您的训练和测试特征向量。

我假设您的特征数据是某种形式的 cv::Mat,其中每行包含特征。 在这种情况下,您希望训练矩阵是每个图像中每个特征矩阵的串联。 这些行看起来不正确:

trainingDataFloat[i][0] = trainFeatures.rows;
trainingDataFloat[i][1] = trainFeatures.cols;

这将二维矩阵的元素设置为 trainFeatures 中的行数和列数。这与 trainFeatures 矩阵中的实际数据无关。

你想检测什么?如果每个图像都是正例和反例,那么您是否试图检测图像中的某些内容?你有什么特点?

如果您尝试在每个图像的基础上检测图像中的对象,那么您需要一个在一个 vector 中描述整个图像的特征向量。在这种情况下,您可以对训练数据执行以下操作:

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.

关于C++ OpenCV SVM 预测不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27984427/

相关文章:

c++ - 如何保存灰度图的黑色像素并将其绘制到另一个相同大小的灰度图?

java - MLKit 对象检测未检测到对象

c++ - 为什么 INT_FAST16_MAX 被定义为 INT32_MAX (VS 2015)?

c++ - CUDA ptxas 错误 "function uses too much shared data"

c++ - 为什么函数不知道数组大小?

c++ - Open GL 旋转

windows - OpenCV 2.3 (C++,QtGui),初始化一些特定的 USB 设备和设置时出现问题

c# - 包装 OpenCV C++ 以便与 C# 一起使用

algorithm - 了解支持向量回归(SVR)

python - 如何正确处理tensorflow RNN中的one-hot-encoding和多维数据