#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 在火车,文件中训练数据,或传递整数响应 /home/buddhika/Documents/OpenCV/modules/ml/src/svm.cpp,第1618行 在抛出&#39; cv :: Exception&#39;
的实例后终止调用
答案 0 :(得分:1)
我不知道我是对的,但我想尝试一下。
现在谈论你的问题。问题似乎是SVM的实现。我首先建议你先研究一下SVM的opencv实现。 https://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html
我从SVM文档中了解到,您必须首先使用类标签向其提供培训DataSet。 根据提供的训练数据,它将训练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
如果有这个帮助,请告诉我。
答案 1 :(得分:0)
之所以发生这种情况,是因为您指定的样本位于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);