Click here to Skip to main content
15,886,919 members
Articles / OpenCV
Tip/Trick

Bag-of-Features Descriptor on SURF and ORB Features (BoF-SURF and BoF-ORB)

Rate me:
Please Sign up or sign in to vote.
4.94/5 (12 votes)
21 Sep 2013CPOL3 min read 56.1K   5.8K   12   15
An implementation of Bag-Of-Feature descriptor based on SURF and ORB features using OpenCV and C++.

Introduction

Bag-Of-Feature (BoF) is a kind of visual feature descriptor which can be used in content based image or video retrieval applications. In order to obtain a BoF descriptor, we need to extract a feature from the image. This feature can be anything such as SIFT (Scale Invariant Feature Transform), SURF (Speeded Up Robust Features), and ORB (Oriented BRIEF), etc.

With this tip, the implementations of BoF-SURF and BoF-ORB are provided. This article is prepared on the request of the readers of article, "Bag-of-Features Descriptor on SIFT Features with OpenCV (BoF-SIFT)" which describes about the Bag-of-Feature descriptor with SIFT in detail. This article only includes the changes which have been made to the original code in order to adopt it to use as BoF-SURF and BoF-ORB. Please refer to the original article for more details.

Background

SURF stands for Speeded Up Robust Feature which is more like SIFT but fast in computation. SURF algorithm gets the maximum benefits from the integral image representation which helps to the speed gain in SURF. You can read more about SURF from this article in Wikipedia.

ORB stand for Oriented BRIEF is an efficient alternative to SIFT and SURF. You can read more about ORB from this research paper "ORB: an efficient alternative to SIFT or SURF".

Using the Code

With OpenCV, we can implement BoF-SURF and BoF-ORB with just a few lines of code. Make sure that you have installed OpenCV 2.3 or higher version and Visual Studio 2008 or higher. The OpenCV version requirement is a must but still you may use other C++ flavors without any problems.

The code has two separate regions that are compiled and run independently. The first region is for obtaining the set of bags of features and the other region for obtaining the BoF descriptor for a given image/video frame. You need to run the first region of the code only once. After creating the vocabulary, you can use it with the second region of code anytime. Modifying the code line below can switch between the two regions of code.

C++
DICTIONARY_BUILD 1 // set DICTIONARY_BUILD to 1 for Step 1. 0 for step 2   

SURF Feature Extraction

In dictionary build section, we need to extract SURF feature using the following code line:

C++
int minHessian = 400; //Hessian Threshold
//Some code lines
SurfDescriptorExtractor detector(minHessian,4,2,false); 

The SurfDescriptorExtractor constructor requires minimum Hessian threshold, number of octaves, number of octave layers, whether the extended descriptor (whether the dimensionality of the descriptor is 128 or 64) and whether the SURF is upright mode (USURF).

In the descriptor extraction section the same SURF extractor and a SURF detector as in the following code:

C++
//create SURF feature point extracter
Ptr<FeatureDetector> detector(new SurfFeatureDetector(minHessian,4,2,false));
//create SURF descriptor extractor
Ptr<DescriptorExtractor> extractor(new SurfDescriptorExtractor(minHessian,4,2,false));  

Other codes are similar to the BoF-SIFT in the original article.

ORB Feature Extraction

For the extraction of ORB features, OrbDescriptorExtractor has been used. We use the default parameter values to create the detector object as in the following code:

C++
OrbDescriptorExtractor detector; 

Unlike in other features, while using ORB for obtaining the BoF vocabulary file, openCV complains about assertion fail within the openCV core library due to a type mismatching problem. The workaround is as follows:

C++
//convert featuresUnclustered to type CV_32F
Mat featuresUnclusteredF(featuresUnclustered.rows,featuresUnclustered.cols,CV_32F);
featuresUnclustered.convertTo(featuresUnclusteredF,CV_32F);
//cluster the feature vectors
Mat dictionary=bowTrainer.cluster(featuresUnclusteredF); 

In order to obtain the BoF descriptor, we need a descriptor matcher. In previous cases, the nearest neighbor technique is used. Here we use BruteForce-Hamming descriptor matcher. ORB is a binary descriptor so hamming distance for matching, works better in terms of both efficiency and performance. I experienced the type problem in this step also. Hence, I used the following code:

C++
//convert to 8bit unsigned format
Mat dictionary(dictionaryF.rows,dictionaryF.cols,CV_8U);
dictionaryF.convertTo(dictionary,CV_8U); 
//create a matcher with BruteForce-Hamming distance
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce-Hamming");	 

The detector and extractor of ORB are created as in the following code:

C++
//create SURF feature point extracter
Ptr<FeatureDetector> detector(new OrbFeatureDetector());
//create SURF descriptor extractor
Ptr<DescriptorExtractor> extractor(new OrbDescriptorExtractor());	 

Points of Interest

Please be careful when you use this code with your research, because I have used type conversion for Mat objects only for avoiding the assertion failings that occurred in the core library of openCV. Better if you can recheck the exact problem or the correct expectation of the openCV code.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
QuestionBOWKMeansTrainer constructor Pin
sky20036128-Nov-17 0:48
sky20036128-Nov-17 0:48 
Questionshowing vocabulary Pin
sky20036127-Nov-17 3:50
sky20036127-Nov-17 3:50 
QuestionThe demo code Pin
Member 1251645413-May-16 19:51
Member 1251645413-May-16 19:51 
AnswerRe: The demo code Pin
Ravimal Bandara18-May-16 20:09
Ravimal Bandara18-May-16 20:09 
QuestionHow to map a keypoint to a visual word ? Pin
Javed Iqbal18-Apr-15 5:23
Javed Iqbal18-Apr-15 5:23 
AnswerRe: How to map a keypoint to a visual word ? Pin
Ravimal Bandara19-Apr-15 18:05
Ravimal Bandara19-Apr-15 18:05 
GeneralRe: How to map a keypoint to a visual word ? Pin
Javed Iqbal20-Apr-15 3:21
Javed Iqbal20-Apr-15 3:21 
GeneralRe: How to map a keypoint to a visual word ? Pin
Ravimal Bandara20-Apr-15 5:20
Ravimal Bandara20-Apr-15 5:20 
GeneralRe: How to map a keypoint to a visual word ? Pin
Javed Iqbal20-Apr-15 8:13
Javed Iqbal20-Apr-15 8:13 
Question1000-Dimension BoVW using SIFT descriptor. Pin
prasanna4430-Nov-14 0:00
prasanna4430-Nov-14 0:00 
AnswerRe: 1000-Dimension BoVW using SIFT descriptor. Pin
Ravimal Bandara30-Nov-14 1:19
Ravimal Bandara30-Nov-14 1:19 
QuestionBuild Errors Pin
Member 1117965017-Nov-14 4:33
Member 1117965017-Nov-14 4:33 
AnswerRe: Build Errors Pin
Ravimal Bandara17-Nov-14 6:16
Ravimal Bandara17-Nov-14 6:16 
GeneralRe: Build Errors Pin
Member 1117965020-Nov-14 3:33
Member 1117965020-Nov-14 3:33 
GeneralRe: Build Errors Pin
Member 113480088-Jul-15 6:29
Member 113480088-Jul-15 6:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.