openCV c ++:使用CvBoost的问题(Adaboost classifer) [英] openCV c++: Problems working with CvBoost (Adaboost classifer)
问题描述
我正在创建一个用于在城市环境图像中对人类进行分类的应用程序。
I'm creating an application for classifying humans in images of urban setting.
我按以下方式训练分类器:
I train a classifer in following manner:
int main (int argc, char **argv)
{
/* STEP 2. Opening the file */
//1. Declare a structure to keep the data
CvMLData cvml;
//2. Read the file
cvml.read_csv ("directory/train_rand.csv");
//3. Indicate which column is the response
cvml.set_response_idx (0);
/* STEP 3. Splitting the samples */
//1. Select 4000 for the training
CvTrainTestSplit cvtts (4000, true);
//2. Assign the division to the data
cvml.set_train_test_split (&cvtts);
printf ("Training ... ");
/* STEP 4. The training */
//1. Declare the classifier
CvBoost boost;
//2. Train it with 100 features
boost.train (&cvml, CvBoostParams (CvBoost::REAL,100, 0, 1, false, 0),
false);
/* STEP 5. Calculating the testing and training error */
// 1. Declare a couple of vectors to save the predictions of each sample
std::vector<float> train_responses, test_responses;
// 2. Calculate the training error
float fl1 = boost.calc_error (&cvml, CV_TRAIN_ERROR, &train_responses);
// 3. Calculate the test error
float fl2 = boost.calc_error (&cvml, CV_TEST_ERROR, &test_responses);
cout<<"Error train: "<<fl1<<endl;
cout<<"Error test: "<<fl2<<endl;
/* STEP 6. Save your classifier */
// Save the trained classifier
boost.save ("./trained_boost_4000samples-100ftrs.xml", "boost");
return 0;
}
train_rand.csv是第一列是类别的文件。其余的列将是问题的特点。例如,我可以使用三个功能。它们中的每一个表示图像中每个像素的红色,蓝色和绿色的平均值。所以我的csv文件应该看起来像这样。注意,在第一列我使用一个字符,所以OpenCV识别为一个类别。
train_rand.csv is a file where the first column is the category. The rest of the columns are going to be the features of the problem. For example, I could have used three features. Each of them represent the average of red, blue and green per pixel in the image. So my csv file should look like this. Note that in the first column I am using a character, so OpenCV recognizes that as a category.
B,124.34,45.4,12.4
B,64.14,45.23,3.23
B,42.32,125.41,23.8
R,224.4,35.34,163.87
R,14.55,12.423,89.67
...
对于我的实际问题,我使用100个功能和8000个样本。我训练分类器的一半数据,并测试其余的。
For my actual problem, I'm using 100 features and 8000 samples. I train the classifier with half of the data and test the with the rest.
训练后,我得到一个大约5%的测试错误100特征)。
After training, I get a test error of around 5% (which is pretty good for only 100 features).
现在我想在新数据中使用分类器:
Now I want to use the classifier in new data:
CvBoost boost
boost.load("directory/trained_boost_4000samples-100ftrs.xml");
float x = boost.predict(SampleData,Mat(),Range::all(),false,false);
cout<<x;
我运行这个代码超过数千个样本,它总是输出相同的值,这是2。我真的不明白我在这里做错了什么,但即使我以错误的方式训练分类器,它不会以同样的方式分类100%的时间,我之前计算的测试错误显示分类器应该工作正常。
I'm running this code over thousands of samples and it always outputs the same value, which is 2. I really don't understand what I am doing wrong here, but even if I trained to classifier in a wrong way, it wouldn't classify 100% of the times in the same way, also, the test error I calculated before shows that the classifier should work fine.
有一件事让我困扰的是SampleData必须具有与我使用的示例相同的列数培训。事情是,用于训练的数据有100列+ 1响应,如果我尝试运行分类器只有100个功能,它抛出一个异常说大小不匹配。如果我运行带有101个特性(这是绝对任意)的分类器,它的工作原理,但结果没有任何意义。
One thing that is bothering me is that SampleData has to have same number of columns as the sample I used to train. The thing is, the data used to train has 100 columns + 1 response, and if I try to run the classifier with only 100 features it throws an exception saying that sizes doesn't match. If I run the classifier with 101 features (which is absolutely arbitrary) it works, but the results doesn't make any sense.
任何人都可以帮我这个?提前感谢!
Can anyone help me with this? Thanks in advance!
回复
推荐答案
我设法获得adaBoost请通过修改SVM文档中的代码。唯一的窍门是确保有足够的样本数据(> = 11)。
I managed to get adaBoost working by adapting the code from the SVM documentation. The only trick was ensuring there was enough sample data (>= 11).
从您的代码从复制的博客:
注意:由于一个很奇怪的原因,OpenCV实现不工作
NOTE: For a very strange reason the OpenCV implementation does not work with less than 11 samples.
// Training data
float labels[11] = { 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0};
Mat labelsMat(11, 1, CV_32FC1, labels);
float trainingData[11][2] = {
{501, 10}, {508, 15},
{255, 10}, {501, 255}, {10, 501}, {10, 501}, {11, 501}, {9, 501}, {10, 502}, {10, 511}, {10, 495} };
Mat trainingDataMat(11, 2, CV_32FC1, trainingData);
// Set up SVM's parameters
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
// Train a SVM classifier
CvSVM SVM;
SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);
// Train a boost classifier
CvBoost boost;
boost.train(trainingDataMat,
CV_ROW_SAMPLE,
labelsMat);
// Test the classifiers
Mat testSample1 = (Mat_<float>(1,2) << 251, 5);
Mat testSample2 = (Mat_<float>(1,2) << 502, 11);
float svmResponse1 = SVM.predict(testSample1);
float svmResponse2 = SVM.predict(testSample2);
float boostResponse1 = boost.predict(testSample1);
float boostResponse2 = boost.predict(testSample2);
std::cout << "SVM: " << svmResponse1 << " " << svmResponse2 << std::endl;
std::cout << "BOOST: " << boostResponse1 << " " << boostResponse2 << std::endl;
// Output:
// > SVM: -1 1
// > BOOST: -1 1
这篇关于openCV c ++:使用CvBoost的问题(Adaboost classifer)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!