我有一个正面文件夹和另一个JPG格式的底片图像,我想根据这些图像训练一个SVM,我做了以下但是收到错误:
Mat classes = new Mat();
Mat trainingData = new Mat();
Mat trainingImages = new Mat();
Mat trainingLabels = new Mat();
CvSVM clasificador;
for (File file : new File(path + "positives/").listFiles()) {
Mat img = Highgui.imread(file.getAbsolutePath());
img.reshape(1, 1);
trainingImages.push_back(img);
trainingLabels.push_back(Mat.ones(new Size(1, 1), CvType.CV_32FC1));
}
for (File file : new File(path + "negatives/").listFiles()) {
Mat img = Highgui.imread(file.getAbsolutePath());
img.reshape(1, 1);
trainingImages.push_back(img);
trainingLabels.push_back(Mat.zeros(new Size(1, 1), CvType.CV_32FC1));
}
trainingImages.copyTo(trainingData);
trainingData.convertTo(trainingData, CvType.CV_32FC1);
trainingLabels.copyTo(classes);
CvSVMParams params = new CvSVMParams();
params.set_kernel_type(CvSVM.LINEAR);
clasificador = new CvSVM(trainingData, classes, new Mat(), new Mat(), params);
当我尝试运行时,我获得了:
OpenCV Error: Bad argument (train data must be floating-point matrix) in cvCheckTrainData, file ..\..\..\src\opencv\modules\ml\src\inner_functions.cpp, line 857
Exception in thread "main" CvException [org.opencv.core.CvException: ..\..\..\src\opencv\modules\ml\src\inner_functions.cpp:857: error: (-5) train data must be floating-point matrix in function cvCheckTrainData
]
at org.opencv.ml.CvSVM.CvSVM_1(Native Method)
at org.opencv.ml.CvSVM.<init>(CvSVM.java:80)
我无法设法训练SVM,任何想法?感谢
答案 0 :(得分:11)
假设您通过重塑图像并使用它来训练SVM来了解您正在做什么,最可能的原因是您的
Mat img = Highgui.imread(file.getAbsolutePath());
无法实际读取图像,生成具有null img
属性的矩阵data
,最终会在OpenCV代码中触发以下内容:
// check parameter types and sizes
if( !CV_IS_MAT(train_data) || CV_MAT_TYPE(train_data->type) != CV_32FC1 )
CV_ERROR( CV_StsBadArg, "train data must be floating-point matrix" );
基本上train_data
未通过第一个条件(作为有效矩阵)而不是第二个条件失败(类型为CV_32FC1)。
此外,即使重塑在*this
对象上工作,它也会像过滤器一样,其效果不是永久性的。如果它在单个语句中使用而没有立即使用或分配给另一个变量,那么它将是无用的。更改代码中的以下行:
img.reshape(1, 1);
trainingImages.push_back(img);
为:
trainingImages.push_back(img.reshape(1, 1));
答案 1 :(得分:0)
正如错误所说,你需要改变你的矩阵的类型,从整数类型,可能是CV_8U,到浮点1,CV_32F或CV_64F。要做到这一点你可以使用cv::Mat::convertTo()
。 Here有点深度和类型的矩阵。