Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Finding top similar images from a database using SIFT

0 down vote favorite

I am working on project and using SIFT features (OpenCV implementation) for image matching. I need to return top 10-15 images in the database which are similar to the query image. I'm using a visual bag-of-words approach to make a vocabulary first and then do the matching. I've found similar questions but didn't find the appropriate answer.

Here is code to generate a dictionary from database images:

char * filename = new char[100];

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;

for(int f=1;f<20;f++) // 20 images in database {
sprintf(filename,"/home/kamikaze/testing/bagofwords/images/%i.jpg",f);

input = imread(filename, 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);

}

int dictionarySize=200;

TermCriteria tc(CV_TERMCRIT_ITER,100,0.001);

int retries=1;

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();

Here's my code to extract a BoW descriptor from query image using this vocabulary:

Mat dictionary; FileStorage fs("dictionary.yml", FileStorage::READ); fs["vocabulary"] >> dictionary; fs.release();

Ptr<descriptormatcher> matcher(new FlannBasedMatcher); Ptr<featuredetector> detector(new SiftFeatureDetector()); Ptr<descriptorextractor> extractor(new SiftDescriptorExtractor);
BOWImgDescriptorExtractor bowDE(extractor,matcher); bowDE.setVocabulary(dictionary);

char * filename = new char[100]; 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. sprintf(filename,"G:\testimages\image\1.jpg");
Mat img=imread(filename,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);

sprintf(imageTag,"img1");
fs1 << imageTag << bowDescriptor;

fs1.release();


I don't know how can I make use of bowDescriptor for getting similar images in the database.

click to hide/show revision 2
No.2 Revision

updated 2016-03-14 02:28:52 -0600

berak gravatar image

Finding top similar images from a database using SIFT

0 down vote favorite

I am working on project and using SIFT features (OpenCV implementation) for image matching. I need to return top 10-15 images in the database which are similar to the query image. I'm using a visual bag-of-words approach to make a vocabulary first and then do the matching. I've found similar questions but didn't find the appropriate answer.

Here is code to generate a dictionary from database images:

char * filename = new char[100];        

Mat input;

Mat input; //To store the keypoints that will be extracted by SIFT vector<keypoint> keypoints;

vector<KeyPoint> keypoints; //To store the SIFT descriptor of current image Mat descriptor;

descriptor; //To store all the descriptors that are extracted from all the images. Mat featuresUnclustered;

featuresUnclustered; //The SIFT feature extractor and descriptor SiftDescriptorExtractor detector;

detector; for(int f=1;f<20;f++) // 20 images in database {
sprintf(filename,"/home/kamikaze/testing/bagofwords/images/%i.jpg",f);

      
    sprintf(filename,"/home/kamikaze/testing/bagofwords/images/%i.jpg",f);

    input = imread(filename, 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);

}

featuresUnclustered.push_back(descriptor); } int dictionarySize=200;

dictionarySize=200; TermCriteria tc(CV_TERMCRIT_ITER,100,0.001);

tc(CV_TERMCRIT_ITER,100,0.001); int retries=1;

retries=1; int flags=KMEANS_PP_CENTERS;

flags=KMEANS_PP_CENTERS; //Create the BoW (or BoF) trainer BOWKMeansTrainer bowTrainer(dictionarySize,tc,retries,flags);

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();

Here's my code to extract a BoW descriptor from query image using this vocabulary:

vocabulary: Mat dictionary; FileStorage fs("dictionary.yml", FileStorage::READ); fs["vocabulary"] >> dictionary; fs.release();

Ptr<descriptormatcher> Ptr<DescriptorMatcher> matcher(new FlannBasedMatcher); Ptr<featuredetector> Ptr<FeatureDetector> detector(new SiftFeatureDetector()); Ptr<descriptorextractor> Ptr<DescriptorExtractor> extractor(new SiftDescriptorExtractor);
BOWImgDescriptorExtractor bowDE(extractor,matcher); bowDE.setVocabulary(dictionary);

bowDE.setVocabulary(dictionary); char * filename = new char[100]; char * imageTag = new char[10];

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

//the image file with the location. sprintf(filename,"G:\testimages\image\1.jpg");
sprintf(filename,"G:\\testimages\\image\\1.jpg"); Mat img=imread(filename,CV_LOAD_IMAGE_GRAYSCALE);

//To store the keypoints that will be extracted by SIFT vector<keypoint> vector<KeyPoint> keypoints;

//Detect SIFT keypoints (or feature points) detector->detect(img,keypoints);

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

bowDE.compute(img,keypoints,bowDescriptor); sprintf(imageTag,"img1");
fs1 << imageTag << bowDescriptor;

fs1.release();

fs1.release();

I don't know how can I make use of bowDescriptor for getting similar images in the database.

click to hide/show revision 3
No.3 Revision

updated 2016-03-14 04:03:41 -0600

berak gravatar image

Finding top similar images from a database using SIFT

0 down vote favorite

I am working on project and using SIFT features (OpenCV implementation) for image matching. I need to return top 10-15 images in the database which are similar to the query image. I'm using a visual bag-of-words approach to make a vocabulary first and then do the matching. I've found similar questions but didn't find the appropriate answer.

Here is code to generate a dictionary from database images:

char * filename = new char[100];        

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;

for(int f=1;f<20;f++)            // 20 images in database
{       
    sprintf(filename,"/home/kamikaze/testing/bagofwords/images/%i.jpg",f);

    input = imread(filename, 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);      

}

int dictionarySize=200;

TermCriteria tc(CV_TERMCRIT_ITER,100,0.001);

int retries=1;

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();   

Here's my code to extract a BoW descriptor from query image using this vocabulary:

Mat dictionary; 
FileStorage fs("dictionary.yml", FileStorage::READ);
fs["vocabulary"] >> dictionary;
fs.release();   

Ptr<DescriptorMatcher> matcher(new FlannBasedMatcher);
Ptr<FeatureDetector> detector(new SiftFeatureDetector());
Ptr<DescriptorExtractor> extractor(new SiftDescriptorExtractor);    
BOWImgDescriptorExtractor bowDE(extractor,matcher);
bowDE.setVocabulary(dictionary);

char * filename = new char[100];
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. 
sprintf(filename,"G:\\testimages\\image\\1.jpg");       
Mat img=imread(filename,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);

sprintf(imageTag,"img1");           
fs1 << imageTag << bowDescriptor;       

fs1.release();

I don't know how can I make use of bowDescriptor for getting similar images in the database.