cvPreparePredictData中不支持的格式或格式组合(输入样本必须具有32fC1类型)

时间:2016-05-26 16:45:43

标签: c++ opencv

我尝试训练自己的SVM来检测人物,我将图像序列调整为320x240。我在训练过程中将图像转换为灰色,而我测试我将测试图像转换为灰色,但是我收到了错误。

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv/cv.h>
#include <iostream>
#include <vector>

#include <stdio.h>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <fstream>

using namespace std;
using namespace cv;

int main(int argc, char* argv[]) {
    String folder = "output/*.jpg";
    vector<String> filenames;
    glob(folder, filenames);

    Mat gray,gray1;

    int img_area=320*240;
    Mat training_mat(filenames.size(),img_area,CV_32FC1);
    Mat labels(filenames.size(),1,CV_32FC1);

    for(int i = 0; i < 900; i++){
        labels.at<float>(i,0)=1;
    }
    for(int i = 900; i < filenames.size(); i++){
        labels.at<float>(i,0)=-1;
    }

    for (size_t i = 0; i < filenames.size(); ++i){
        Mat img = imread(filenames[i]);
        cvtColor(img, gray, CV_RGB2GRAY);
        int ii = 0; 
        for (int k = 0; k < gray.rows; k++) {
            for (int j = 0; j < gray.cols; j++) {
                training_mat.at<float>(i,ii++) = gray.at<uchar>(k,j);
            }
        }
    }

    CvSVMParams params;
    params.svm_type = CvSVM::C_SVC;
    params.kernel_type = CvSVM::POLY;
    params.gamma = 3;
    params.degree = 3;
    CvSVM svm;
    svm.train(training_mat, labels, Mat(), Mat(), params);
    svm.save("svm_filename"); // saving
    svm.load("svm_filename"); // loading
    Mat image = imread("output/500.jpg");
    cvtColor(image, gray1, CV_RGB2GRAY);
    int response = svm.predict(gray1);

    if(response == 1){
        cout << "person " << endl ;
    }
    return 0;
}

我编译程序时遇到了这个错误:

  

OpenCV错误:cvPreparePredictData中不支持的格式或格式组合(输入样本必须具有32fC1类型),文件/home/mourad/opencv/opencv-2.4.10/modules/ml/src/inner_functions.cpp,第1102行终止抛出'cv :: Exception'的实例后调用

2 个答案:

答案 0 :(得分:1)

您也应该将gray1转换为32FC1

cvtColor(image, gray1, CV_RGB2GRAY);
gray1.convertTo(gray1, CV_32FC1, 1.0/255.0); // <-- add this line before predict
int response = svm.predict(gray1);

另请注意,以下代码不是从uchar转换为float的正确方法,因为它们可能适用于不同的范围:[0,255]和{{1} }。

[0,1]

答案 1 :(得分:0)

我将此添加到我的程序中:

cvtColor(image,gray1, CV_RGB2GRAY);
Mat image_mat(1,img_area,CV_32FC1);
int jj=0;
for (int k = 0; k < gray1.rows; k++) {
        for (int j = 0; j < gray1.cols; j++) {

        image_mat.at<float>(0,jj++) = gray.at<uchar>(k,j);
        }
    }

int response=svm.predict(image_mat);
if(response == 1){

    cout << "person detected" << endl;
}

但程序运行并没有显示任何内容。