c++ - 使用 SVM 和 opencv 3 进行图像训练

标签 c++ opencv svm

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include "opencv2/imgcodecs.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
using namespace cv;
using namespace cv::ml;
using namespace std;

int main()
{
Mat img_mat = imread("/home/buddhika/workspace/project/images/t.jpg");

// Load images in the C++ format
Size size(64,124);//the image size,e.g.64x124
resize(img_mat ,img_mat ,size);//resize image

int num_files = 1;//number of images
int img_area = 64*124;//imag size
//initialize the training matrix
//The number of rows in the matrix would be 5, and the number of   columns would be the area of the image, 64*124 = 12
Mat training_mat(num_files,img_area,CV_32FC1);
// "fill in" the rows of training_mat with the data from each image.
cvtColor(img_mat,img_mat, CV_RGB2GRAY);
 imshow("",img_mat);

int ii = 0; // Current column in training_mat
//Do this for every training image
int file_num=0;
for (int i = 0; i<img_mat.rows; i++) {
    for (int j = 0; j < img_mat.cols; j++) {
        training_mat.at<float>(file_num,ii++) = img_mat.at<uchar>(i,j);
    }
}

// training matrix set up properly to pass into the SVM functions
//set up labels for each training image
//1D matrix, where each element in the 1D matrix corresponds to each row in the 2D matrix.
//-1 for non-human and 1 for human
//labels matrix
 float label = 1.0;
 cout << training_mat.rows<< endl;
 cout << training_mat.cols<< endl;
 Mat labels(1,7936 , CV_32SC1, label);

// Set up SVM's parameters
    Ptr<SVM> svmOld = SVM::create();
    svmOld->setType(SVM::C_SVC);
    svmOld->setKernel(SVM::LINEAR);
  //  svmOld->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));

    //train it based on your data

   svmOld->train(training_mat, ROW_SAMPLE, labels);
    //same svm
  svmOld->save("positive.xml");


    //Initialize SVM object
    Ptr<SVM> svmNew = SVM::create();
    //Load Previously saved SVM from XML
    //can save the trained SVM so you don't have to retrain it every time
    svmNew = SVM::load<SVM>("positive.xml");

//To test your images using the trained SVM, simply read an image, convert it to a 1D matrix, and pass that in to svm
// td.predict( training_mat);//It will return a value based on what you set as your labels

waitKey(0);
return(0);
}

这是我使用 SVM 用于正数据训练的代码。但是

svmOld->train(training_mat, ROW_SAMPLE, labels);

代码崩溃并给出以下错误。我如何克服这一点?

OpenCV Error: Bad argument (in the case of classification problem the responses must be categorical; either specify varType when creating TrainData, or pass integer responses) in train, file /home/buddhika/Documents/OpenCV/modules/ml/src/svm.cpp, line 1618 terminate called after throwing an instance of 'cv::Exception'

最佳答案

发生这种情况是因为您指定样本在 training_mat 的行上,而您将它们写在列上。

创建训练矩阵的代码应如下所示:

Mat training_mat(img_area,num_files,CV_32FC1);
// "fill in" the rows of training_mat with the data from each image.
cvtColor(img_mat,img_mat, CV_RGB2GRAY);
imshow("",img_mat);

int ii = 0; // Current column in training_mat
//Do this for every training image
int file_num=0;
for (int i = 0; i<img_mat.rows; i++) {
    for (int j = 0; j < img_mat.cols; j++) {
        training_mat.at<float>(ii++,file_num) = img_mat.at<uchar>(i,j);
    }
}

你的 labels 也应该改变:Mat labels(training_mat.rows,1 , CV_32SC1, label);

关于c++ - 使用 SVM 和 opencv 3 进行图像训练,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38350985/

相关文章:

python - 基于空间维度去除图像噪声

python - 从图像中提取表格数据

c++ - ldap_set_option() 未设置选项 "LDAP_OPT_SSL"

c++ - 为枚举赋值

c++ - #include <string> 文件在 iOS 中的 C++ 文件中找不到

python - sklearn CalibratedClassifierCV 和 SVM 出错

machine-learning - 我应该如何使用 julia 训练 SVM?

c++ - 在 int 中存储大于 INT_MAX 的数字

c++ - 模板匹配屏幕截图在断言时失败

python-2.7 - Python 中的 libsvm : getting error