【问题标题】:Image train using SVM and opencv 3使用 SVM 和 opencv 3 的图像训练
【发布时间】:2016-11-16 00:00:31
【问题描述】:
#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 错误:参数错误(在分类问题的情况下 回答必须是明确的;创建时指定 varType TrainData,或传递整数响应)在火车,文件 /home/buddhika/Documents/OpenCV/modules/ml/src/svm.cpp,第 1618 行 在抛出 'cv::Exception' 的实例后调用终止

【问题讨论】:

    标签: c++ opencv svm


    【解决方案1】:

    发生这种情况是因为您在将样本写入列时指定样本位于 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);

    【讨论】:

    • 它生成 SVM 文件。但它是空的,我仍然有上述错误。
    【解决方案2】:

    我不知道我是否正确,但我想尝试一下。

    现在谈论您的问题。由于问题似乎是SV​​M的实现。我首先建议您先研究SVM的opencv实现。 https://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html

    我从 SVM 文档中了解到,您必须首先为其提供带有类标签的训练数据集。 根据提供的训练数据,它将训练 SVM。此外,您还必须针对正面标签和负面标签对其进行训练。

    您正在做的事情完全是错误的。我已经在我的机器上运行了您的代码并对其进行了一些调试。使用此调试代码。

    Mat img_mat = imread("C:\\Users\\saurabh chandra\\Desktop\\52.png");
    Mat img_mat1 = imread("C:\\Users\\saurabh chandra\\Desktop\\53.png");
    Size size(64, 124);                
    resize(img_mat, img_mat, size);   
    resize(img_mat1, img_mat1, size);
    int num_files = 2;             
    int img_area = 64 * 124;      
    
    
    cvtColor(img_mat, img_mat, CV_RGB2GRAY);  
    cvtColor(img_mat1, img_mat1, COLOR_BGR2GRAY);
    
    int ii = 0; 
    
    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);
    }
    
     }
    
    ii = 0;
     file_num =file_num+1;
    
     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);
         }
      }
    
    
     float label[2] = { 1.0,1.0 };
     cout << training_mat.rows << endl;
     cout << training_mat.cols << endl;
     Mat labels(2, 1, CV_32SC1, label);
    
     Ptr<SVM> svmOld = SVM::create();
     svmOld->setType(SVM::C_SVC);
     svmOld->setKernel(SVM::LINEAR);
     svmOld->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));
    
     svmOld->train(training_mat, ROW_SAMPLE, labels);
     svmOld->save("positive.xml");
    
     waitKey(0);
     return 0;
    }
    

    此代码将 SVM 训练结果保存到 Positive.xml 文件中。我已经为两个图像实现了您的代码。 但我建议您使用良好且大型的训练数据以获得更好的结果。

    为了更好地了解 SVM 的实现,您可以在此处查看。

    using OpenCV and SVM with images

    如果有帮助,请告诉我。

    【讨论】:

      猜你喜欢
      • 2017-08-25
      • 2015-01-22
      • 2015-06-03
      • 2016-03-29
      • 2015-05-04
      • 2015-07-25
      • 1970-01-01
      • 2015-04-18
      相关资源
      最近更新 更多