【发布时间】:2012-03-26 03:21:09
【问题描述】:
我正在尝试使用 SVM、openCV、C++ 和 Visual Studio 2008(mfc 应用程序)创建一个简单的 OCR 应用程序。
我的训练样本是机器打印数字 (0-9) 的二进制图像。我想使用 DAGSVM 来解决这个多类问题。所以我需要创建45个SVM,每个都是2类的SVM(SVM(0,1), SVM(0,2)...SVM(8,9))。
事情是这样发展的:
SVM 的参数:
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
第 i 类训练图像的数据存储在矩阵 trainData[i] 中(每行是 28x28 图像的像素,这意味着矩阵有 784 列)。 在训练每个 SVM 时,我创建了 2 个矩阵,称为 curTrainData 和 curTrainLabel。
for (int i = 0; i < 9; i++)
for (int j = i+1; j < 10; j++)
{
curTrainData.create(trainData[i].rows + trainData[j].rows, 784, CV_32FC1);
curTrainLabel.create(curTrainData.rows, 1, CV_32FC1);
// merge 2 matrix: trainData[i] & trainData[j]
for (int k = 0; k < trainData[i].rows; k++)
{
curTrainLabel.at<float>(k, 0) = 1.0; // class of digit i
for (int l = 0; l < 784; l++)
curTrainData.at<float>(k,l) = trainData[i].at<float>(k,l);
}
for (int k = 0; k < trainData[j].rows; k++)
{
curTrainLabel.at<float>(k + trainData[i].rows, 0) = -1.0; // class of digit j
for (int l = 0; l < 784; l++)
curTrainData.at<float>(k + trainData[i].rows,l) = trainData[j].at<float>(k,l);
}
svms[i][j].train(curTrainData, curTrainLabel, Mat(), Mat(), params);
}
我在调用 svms[i][j].train... 时遇到错误。完整的错误是:
Unhandled exception at 0x75b5d36f in svm.exe: Microsoft C++ exception: cv::Exception at memory location 0x0022af8c..
说实话,我并不完全了解 openCV 中实现的 SVM,也找不到任何使用图像对象的示例。
如果有人能告诉我什么是错的,我真的很感激:(
09/03 更新: 我弄错了。错误来自:
str.Format(_T("Results\trained_%d_%d.xml"), i, j);
svms[i][j].save(CT2A(str));
str 是一个 CString 变量。
即使我更改为:
svms[i][j].save("Results\trained.xml");
我已经创建了文件夹 Results 并且其他文件都很好地写入其中(用于方法 fopen()、imwrite()...的文件)。不知道svm这个save方法为什么不能添加文件夹。
【问题讨论】:
-
只是一个猜测,但这看起来只是一个内存问题,
svms声明在哪里,它的大小是多少? (必须在循环语句之后至少 9x10) -
@Smash:是的,我使用 10x10 数组。事实证明问题出在调用 svm.save() 中(就像我上面的更新一样)。如果我可以保存模型,我每次只需要使用一个 svm。
-
如果你使用反斜杠\,你必须把\\代替(或者你可以使用前斜杠/)
标签: c++ image-processing opencv machine-learning svm