如何基于一组图像用opencv训练SVM?

如何基于一组图像用opencv训练SVM?,opencv,svm,Opencv,Svm,我有一个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

我有一个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)
OpenCV错误:cvCheckTrainData文件中的参数错误(列车数据必须是浮点矩阵)\\..\src\OpenCV\modules\ml\src\inner_functions.cpp,第857行
线程“main”CvException[org.opencv.core.CvException:..\..\..\src\opencv\modules\ml\src\inner_函数中的异常。cpp:857:错误:(-5)序列数据必须是函数cvCheckTrainData中的浮点矩阵
]
在org.opencv.ml.CvSVM.CvSVM_1(本地方法)
在org.opencv.ml.CvSVM上(CvSVM.java:80)

我无法训练SVM,知道吗?谢谢

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

假设您通过重塑图像并使用它来训练SVM知道自己在做什么,最可能的原因是您的

Mat img = Highgui.imread(file.getAbsolutePath());
无法实际读取图像,生成一个带有null
data
属性的矩阵
img
,最终将触发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类型)失效

此外,即使“重塑”在
*这个
对象上起作用,它也像一个过滤器,其效果不是永久的。如果在单个语句中使用它,而不立即使用或分配给另一个变量,那么它将是无用的。更改代码中的以下行:

img.reshape(1, 1);
trainingImages.push_back(img);
致:


我正在尝试根据我已经获得的segmets对板材进行分类,我的代码基于以下示例:您是否尝试使用CV_64F?在将
trainingData
传递到CvSVM之前,您是否检查了它的类型?谢谢@morynicz,“CvType.typeToString(trainingData.type())”将返回“CV_32FC3”。。还尝试转换为CV_64F,错误与我实际所做的相同:“trainingData.convertTo(trainingData,CvType.CV_32FC1);”我的“类”由[1]CV_32FC1 matrixOops填充。对不起,我没看到。
trainingImages.push_back(img.reshape(1, 1));