C++ OpenCV SVM 预测不工作
C++ OpenCV SVM Predict Not Working
正在尝试创建功能 SVM
。我有 114 张训练图像、60 张 Positive/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 的 ,我将 testDataFloat
变成一维数组,然后像这样将它提供给 Mat
,以便预测 SVM
:
float* testData1D = (float*)testDataFloat;
Mat testDataMat1D(height*width, 1, CV_32FC1, testData1D);
float testPredict = SVMmodel.predict(testDataMat1D);
一切就绪后,出现调试错误:
cvPreparePredictData
中输入参数的大小不匹配(样本大小与用于训练的样本大小不同)
查看 this post 我发现(感谢 berak):
"all images (used in training & prediction) have to be the same size"
所以我加入了一个 re-size 函数,可以 re-size 图像以任何你想要的大小都是方形的 (100x100, 200x200, 1000, 1000 etc.
)
运行 再次将图像 re-sized 复制到程序现在从中加载图像的新目录,我得到与之前完全相同的错误:
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 has stopped working
)...所以这是一个新问题。
编辑 2
添加了一个简单的
std::cout << testPredict;
查看 SVM 的确定输出,它似乎正匹配所有内容,直到图像 160,它停止 运行ning:
请检查您的训练和测试特征向量。
我假设您的要素数据是某种形式的 cv::Mat,每行都包含要素。
在这种情况下,您希望训练矩阵是每个图像的每个特征矩阵的串联。
这些行看起来不正确:
trainingDataFloat[i][0] = trainFeatures.rows;
trainingDataFloat[i][1] = trainFeatures.cols;
这是将二维矩阵的一个元素设置为 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.
正在尝试创建功能 SVM
。我有 114 张训练图像、60 张 Positive/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 的 testDataFloat
变成一维数组,然后像这样将它提供给 Mat
,以便预测 SVM
:
float* testData1D = (float*)testDataFloat;
Mat testDataMat1D(height*width, 1, CV_32FC1, testData1D);
float testPredict = SVMmodel.predict(testDataMat1D);
一切就绪后,出现调试错误:
cvPreparePredictData
中输入参数的大小不匹配(样本大小与用于训练的样本大小不同)查看 this post 我发现(感谢 berak):
"all images (used in training & prediction) have to be the same size"
所以我加入了一个 re-size 函数,可以 re-size 图像以任何你想要的大小都是方形的 (100x100, 200x200, 1000, 1000 etc.
)
运行 再次将图像 re-sized 复制到程序现在从中加载图像的新目录,我得到与之前完全相同的错误:
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 has stopped working
)...所以这是一个新问题。
编辑 2
添加了一个简单的
std::cout << testPredict;
查看 SVM 的确定输出,它似乎正匹配所有内容,直到图像 160,它停止 运行ning:
请检查您的训练和测试特征向量。
我假设您的要素数据是某种形式的 cv::Mat,每行都包含要素。 在这种情况下,您希望训练矩阵是每个图像的每个特征矩阵的串联。 这些行看起来不正确:
trainingDataFloat[i][0] = trainFeatures.rows;
trainingDataFloat[i][1] = trainFeatures.cols;
这是将二维矩阵的一个元素设置为 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.