簡體   English   中英

使用SVM和opencv 3的圖像訓練

[英]Image train using SVM and opencv 3

#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錯誤:錯誤的參數(在分類問題的情況下,響應必須是分類的;在創建TrainData時指定varType,或者傳遞整數響應)在火車,文件/ home / buddhika / Documents / OpenCV / modules / ml / src / svm中.cpp,第1618行在引發'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);

我不知道我是否正確,但是我想嘗試一下。

現在討論您的問題,因為問題似乎出在SVM的實現上,我首先建議您先研究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的實現,您可以在此處進行檢查。

將OpenCV和SVM與圖像一起使用

如果有幫助,請告訴我。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM