2013-06-01 36 views
6

我有JPG格式底片图像的阳性的文件夹和另一个,我想训练基于SVM的图像是,我已经做了以下的,但我收到一个错误:如何根据一组图像训练一个支持opencv的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) 

我无法设法训练支持向量机,任何想法?谢谢

+0

我试图分类基础上我已经得到segmets板,我的代码是基于这个例子:https://开头的github .com/MasteringOpenCV/code/blob/master/Chapter5_NumberPlateRecognition/trainSVM.cpp –

+0

您尝试使用CV_64F吗?并且您是否确实要在传递到CvSVM之前检查'trainingData'类型是什么? – morynicz

+0

谢谢@morynicz,'CvType.typeToString(trainingData.type())'将返回“CV_32FC3”..也尝试转换为CV_64F与相同的错误 –

回答

11

假设你知道你被重塑的图像,并用它来训练SVM做什么,这是最可能的原因是你的

Mat img = Highgui.imread(file.getAbsolutePath()); 

未能实际读取的图像,生成矩阵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)); 
0

正如错误所述,您需要更改矩阵的类型,从整数类型(可能是CV_8U)更改为浮点型CV_32F或CV_64F。要做到这一点你可以使用cv::Mat::convertTo()Here有点关于矩阵的深度和类型。

+0

其实我做的:'trainingData.convertTo(trainingData,CvType.CV_32FC1); “和我的'类'填充[1] CV_32FC1的矩阵 –

+0

糟糕。对不起,没有看到。 – morynicz