SIFT+SVM 使用Bag of Features


Bag-of-Features Descriptor on SIFT Features with OpenCV (BoF-SIFT)

通过DICTIONARY_BUILD  1  建立字典

通过DICTIONARY_BUILD  2 计算特征

通过特征可以进行SVM训练


// 0515_BoFSIFT.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"


#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv2/nonfree/features2d.hpp>
#include <fstream>
using namespace cv;
using namespace std;

#define DICTIONARY_BUILD 1 // set DICTIONARY_BUILD 1 to do Step 1, otherwise it goes to step 2

int _tmain(int argc, _TCHAR* argv[])
	{	
#if DICTIONARY_BUILD == 1

	//Step 1 - Obtain the set of bags of features.
	vector<string> img_path;    

	int nLine = 0;    
	string buf;    
	ifstream svm_data( "_list.txt" );    

	while( svm_data )    
		{    
		if( getline( svm_data, buf ) )    
			{    	   
			img_path.push_back( buf );    	
			}    
		}    
	svm_data.close();    
	//to store the input file names
	char * filename = new char[100];		
	//to store the current input image
	Mat input;	

	//To store the keypoints that will be extracted by SIFT
	vector<KeyPoint> keypoints;
	//To store the SIFT descriptor of current image
	Mat descriptor;
	//To store all the descriptors that are extracted from all the images.
	Mat featuresUnclustered;
	//The SIFT feature extractor and descriptor
	SiftDescriptorExtractor detector;	
	//I select 20 (1000/50) images from 1000 images to extract feature descriptors and build the vocabulary

	int len = img_path.size();
	for(int f=0;f<len;f+=50){		
		//create the file name of an image
		

		//open the file
		input = imread(img_path[f], CV_LOAD_IMAGE_GRAYSCALE); //Load as grayscale				
		//detect feature points
		detector.detect(input, keypoints);
		//compute the descriptors for each keypoint
		detector.compute(input, keypoints,descriptor);		
		//put the all feature descriptors in a single Mat object 
		featuresUnclustered.push_back(descriptor);		
		//print the percentage
		printf("%i percent done\n",f/10);
		}	


	//Construct BOWKMeansTrainer
	//the number of bags
	int dictionarySize=200;
	//define Term Criteria
	TermCriteria tc(CV_TERMCRIT_ITER,100,0.001);
	//retries number
	int retries=1;
	//necessary flags
	int flags=KMEANS_PP_CENTERS;
	//Create the BoW (or BoF) trainer
	BOWKMeansTrainer bowTrainer(dictionarySize,tc,retries,flags);
	//cluster the feature vectors
	Mat dictionary=bowTrainer.cluster(featuresUnclustered);	
	//store the vocabulary
	FileStorage fs("dictionary.yml", FileStorage::WRITE);
	fs << "vocabulary" << dictionary;
	fs.release();

#else
	//Step 2 - Obtain the BoF descriptor for given image/video frame. 
	vector<string> img_path;    

	int nLine = 0;    
	string buf;    
	ifstream svm_data( "_list.txt" );    

	while( svm_data )    
		{    
		if( getline( svm_data, buf ) )    
			{    	   
			img_path.push_back( buf );    	
			}    
		}    
	svm_data.close();    
	//prepare BOW descriptor extractor from the dictionary    
	Mat dictionary; 
	FileStorage fs("dictionary.yml", FileStorage::READ);
	fs["vocabulary"] >> dictionary;
	fs.release();	

	//create a nearest neighbor matcher
	Ptr<DescriptorMatcher> matcher(new FlannBasedMatcher);
	//create Sift feature point extracter
	Ptr<FeatureDetector> detector(new SiftFeatureDetector());
	//create Sift descriptor extractor
	Ptr<DescriptorExtractor> extractor(new SiftDescriptorExtractor);	
	//create BoF (or BoW) descriptor extractor
	BOWImgDescriptorExtractor bowDE(extractor,matcher);
	//Set the dictionary with the vocabulary we created in the first step
	bowDE.setVocabulary(dictionary);

	//To store the image file name
	char * filename = new char[100];
	//To store the image tag name - only for save the descriptor in a file
	char * imageTag = new char[10];

	//open the file to write the resultant descriptor
	FileStorage fs1("descriptor.yml", FileStorage::WRITE);	

	//the image file with the location. change it according to your image file location
		
	//read the image
	Mat img=imread(img_path[2],CV_LOAD_IMAGE_GRAYSCALE);		
	//To store the keypoints that will be extracted by SIFT
	vector<KeyPoint> keypoints;		
	//Detect SIFT keypoints (or feature points)
	detector->detect(img,keypoints);
	//To store the BoW (or BoF) representation of the image
	Mat bowDescriptor;		
	//extract BoW (or BoF) descriptor from given image
	bowDE.compute(img,keypoints,bowDescriptor);

	//prepare the yml (some what similar to xml) file
	sprintf(imageTag,"img1");			
	//write the new BoF descriptor to the file
	fs1 << imageTag << bowDescriptor;		

	//You may use this descriptor for classifying the image.

	//release the file storage
	fs1.release();
#endif
	printf("\ndone\n");	
	return 0;
	}


你可能感兴趣的:(SVM,sift)