过程:
1.载入正样本图像
2.载入负样本图像
3.探测特征
4.提取特征
5. 将正样本特征和负样本特征合成训练样本特征矩阵
6. 输入训练矩阵和样本标签到SVM,进行训练
7. 保存SVM训练结果
问题:
对于surf特征的探测和提取均奏效,但是对于orb特征SVM训练会使程序崩溃,提示为“一个不可处理的异常产生在内存xxxxxxx ”。
比较两个代码所产生的训练矩阵发现,surf特征的训练矩阵为double类型,而orb特征的训练矩阵为uchar。将说char类型转换为
double类型,程序运行成功。
代码如下
/* * @author smells2 */ #include <iostream> #include <fstream> #include <vector> #include <time.h> #include <assert.h> #include <cmath> #include <opencv2/core/core.hpp> #include <opencv2/features2d/features2d.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/nonfree/features2d.hpp> #include <opencv2/ml/ml.hpp> using namespace std; using namespace cv; #define SVMTRAN 0 static void Help() { cout << "======================================================"<<endl; cout << " This program is used to train matches with SVM" << endl; cout << "======================================================"<<endl; } void getDescriptors(vector<string>& file_paths, vector<Mat>& descriptors_arry) { //using to store training images. clock_t time_start = clock(); vector<Mat> img_objs; for (size_t i = 0;i < file_paths.size();i++) { Mat temp_img = imread(file_paths[i],CV_LOAD_IMAGE_GRAYSCALE); if (!temp_img.data) { cerr << "ERROR: open " << file_paths[i] <<" image is failed!" <<endl; exit(0); } img_objs.push_back(temp_img); cout << "file: " << file_paths[i] << " is loaded." << endl; } //get descriptors for each image //!{ const int min_hessian = 400; OrbFeatureDetector surf_hessian_detector( min_hessian ); OrbDescriptorExtractor surf_extractor; //OrbDescriptorExtractor surf_extractor; for (size_t i = 0;i < img_objs.size();i++) { vector<KeyPoint> keyPoints; surf_hessian_detector.detect(img_objs[i],keyPoints); Mat descriptors; surf_extractor.compute(img_objs[i],keyPoints,descriptors); descriptors_arry.push_back(descriptors); cout << "file: " << file_paths[i] << " descriptors is extrated." << endl; } //!} clock_t time_end = clock(); cout << "cost time: " << (float)(time_end - time_start)/1000 << " seconds." << endl; } int main(int arg, char** argv) { Help(); clock_t total_time_start = clock(); //Open train data configuration #if _DEBUG ifstream fin("../images/train_positive.txt"); #else if (arg < 4) { cerr << "Usage: command <positive_samples_path> <negative_samples_path> <output_SVM_XML_path>" <<endl; exit(0); } ifstream fin(argv[1]); #endif if (!fin) { #if _DEBUG cerr << "file open failed!" << endl; #else cerr << argv[1] <<" open failed!" << endl; #endif exit(0); } string buf; // file_paths is used to store files vector<string> file_paths; while(getline(fin,buf)) { file_paths.push_back(buf); buf.clear(); } //close file_paths file fstream fin.close(); vector<Mat> descriptors_positive; getDescriptors(file_paths,descriptors_positive); if (fin.is_open()) { fin.close(); } #if _DEBUG fin.open("../images/train_negative.txt"); #else fin.open(argv[2]); #endif if (!fin) { #if _DEBUG cerr << "file open is failed, negative" << endl; #else cerr << argv[2] << "open failed." << endl; #endif exit(0); } vector<string> negative_file_paths; buf.clear(); while(getline(fin,buf)) { negative_file_paths.push_back(buf); buf.clear(); } vector<Mat> descriptors_negative; getDescriptors(negative_file_paths,descriptors_negative); //Merge training data assert(descriptors_positive.size() > 0); int train_mat_row = 0; int train_mat_row_positive = 0; int train_mat_row_negative = 0; int train_mat_col = descriptors_positive[0].cols; for (size_t i = 0; i < descriptors_positive.size();i++) { #if _DEBUG cout << i << " rows: " << descriptors_positive[i].rows<< " col: " << descriptors_positive[i].cols << endl; #endif train_mat_row += descriptors_positive[i].rows; train_mat_row_positive += descriptors_positive[i].rows; } for (size_t i = 0; i < descriptors_negative.size();i++) { #if _DEBUG cout << i << " rows: " << descriptors_negative[i].rows<< " col: " << descriptors_negative[i].cols << endl; #endif train_mat_row += descriptors_negative[i].rows; train_mat_row_negative += descriptors_negative[i].rows; } Mat train_samples; float* _labels = new float[train_mat_row_positive+train_mat_row_negative]; for (int i = 0;i < train_mat_row_positive;i++) { _labels[i] = 1.0; } for (int i = train_mat_row_positive;i < train_mat_row_positive+train_mat_row_negative;i++) { _labels[i] = -1.0; } for (size_t i = 0; i < descriptors_positive.size(); i++) { Mat _t; _t.create(descriptors_positive[i].rows,descriptors_positive[i].cols,CV_32FC1); descriptors_positive[i].convertTo(_t,CV_32FC1); train_samples.push_back(_t); //train_samples.push_back(descriptors_positive[i]); } #if _DEBUG //cout << train_samples << endl; #endif for (size_t i = 0; i< descriptors_negative.size(); i++) { Mat _t; _t.create(descriptors_negative[i].rows,descriptors_negative[i].cols,CV_32FC1); descriptors_negative[i].convertTo(_t,CV_32FC1); train_samples.push_back(_t); //train_samples.push_back(descriptors_negative[i]); } Mat train_lables(train_mat_row_positive+train_mat_row_negative,1,CV_32FC1,_labels); #if _DEBUG // cout << train_lables << endl; #endif //Train SVM SVMParams params; params.svm_type = CvSVM::C_SVC; params.kernel_type = CvSVM::LINEAR; TermCriteria terminated(CV_TERMCRIT_ITER,1000,1e-6); CvSVM SVM; SVM.train(train_samples,train_lables,Mat(),Mat(),params); #if _DEBUG SVM.save("../images/train_SVM.xml"); #else SVM.save(argv[3]); #endif #if _DEBUG //predict vector<Mat> descriptor_predict; vector<string> predict_path; predict_path.push_back(string("../images/train/4.JPG")); getDescriptors(predict_path,descriptor_predict); Mat res; Mat _t; _t.create(descriptor_predict[0].rows,descriptor_predict[0].cols,CV_32FC1); descriptor_predict[0].convertTo(_t,CV_32FC1); SVM.predict(_t,res); cout << res << endl; #endif //release memory if (_labels) { delete _labels; _labels = NULL; } clock_t total_time_end = clock(); cout << "total cost time: "<< (double)(total_time_end-total_time_start)/1000 << " seconds."<<endl; }