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