OrbFeatureDetector, OrbDescriptorExtractor, SVM 报错问题

过程:

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;
} 

你可能感兴趣的:(OrbFeatureDetector, OrbDescriptorExtractor, SVM 报错问题)