clc; clear all; close all; 
imageDir = fullfile(toolboxdir('vision'),'visiondata','structureFromMotion');
imds = imageDatastore(imageDir); 
[features, featureMetrics] = exampleExtractor(I); 
extractor = @exampleExtractor; 
imageIndex = indexImages(imds); 
Creating an inverted image index using Bag-Of-Features.
-------------------------------------------------------
Creating Bag-Of-Features.
-------------------------
* Selecting feature point locations using the Detector method.
* Extracting SURF features from the selected feature point locations.
** detectSURFFeatures is used to detect key points for feature extraction.
* Extracting features from 5 images...done. Extracted 2980 features.
* Keeping 80 percent of the strongest features from each category.
* Balancing the number of features across all image categories to improve clustering.
** Image category 1 has the least number of strongest features: 2384.
** Using the strongest 2384 features from each of the other image categories.
* Creating a 2384 word visual vocabulary.
* Number of levels: 1
* Branching factor: 2384
* Number of clustering steps: 1
* [Step 1/1] Clustering vocabulary level 1.
* Number of features          : 2384
* Number of clusters          : 2384
* Initializing cluster centers...100.00%.
* Clustering...completed 1/100 iterations (~0.03 seconds/iteration)...converged in 1 iterations.
* Finished creating Bag-Of-Features
Encoding images using Bag-Of-Features.
--------------------------------------
* Encoding 5 images...done.
Finished creating the image index.
bag = bagOfFeatures(imds, 'CustomExtractor', extractor, ...
            'TreeProperties', [2, 10], 'StrongestFeatures', 1); 
Creating Bag-Of-Features.
-------------------------
* Extracting features using a custom feature extraction function: exampleExtractor.
* Extracting features from 5 images...done. Extracted 242966 features.
* Keeping 100 percent of the strongest features from each category.
* Creating a 100 word visual vocabulary.
* Number of levels: 2
* Branching factor: 10
* Number of clustering steps: 11
* [Step 1/11] Clustering vocabulary level 1.
* Number of features          : 242966
* Number of clusters          : 10
* Initializing cluster centers...100.00%.
* Clustering...completed 44/100 iterations (~0.35 seconds/iteration)...converged in 44 iterations.
* [Step 2/11] Clustering vocabulary level 2, branch 1.
* Number of features          : 42488
* Number of clusters          : 10
* Initializing cluster centers...100.00%.
* Clustering...completed 32/100 iterations (~0.05 seconds/iteration)...converged in 32 iterations.
* [Step 3/11] Clustering vocabulary level 2, branch 2.
* Number of features          : 13566
* Number of clusters          : 10
* Initializing cluster centers...100.00%.
* Clustering...completed 33/100 iterations (~0.03 seconds/iteration)...converged in 33 iterations.
* [Step 4/11] Clustering vocabulary level 2, branch 3.
* Number of features          : 26142
* Number of clusters          : 10
* Initializing cluster centers...100.00%.
* Clustering...completed 41/100 iterations (~0.04 seconds/iteration)...converged in 41 iterations.
* [Step 5/11] Clustering vocabulary level 2, branch 4.
* Number of features          : 27133
* Number of clusters          : 10
* Initializing cluster centers...100.00%.
* Clustering...completed 31/100 iterations (~0.04 seconds/iteration)...converged in 31 iterations.
* [Step 6/11] Clustering vocabulary level 2, branch 5.
* Number of features          : 24487
* Number of clusters          : 10
* Initializing cluster centers...100.00%.
* Clustering...completed 31/100 iterations (~0.04 seconds/iteration)...converged in 31 iterations.
* [Step 7/11] Clustering vocabulary level 2, branch 6.
* Number of features          : 16289
* Number of clusters          : 10
* Initializing cluster centers...100.00%.
* Clustering...completed 20/100 iterations (~0.04 seconds/iteration)...converged in 20 iterations.
* [Step 8/11] Clustering vocabulary level 2, branch 7.
* Number of features          : 18651
* Number of clusters          : 10
* Initializing cluster centers...100.00%.
* Clustering...completed 31/100 iterations (~0.05 seconds/iteration)...converged in 31 iterations.
* [Step 9/11] Clustering vocabulary level 2, branch 8.
* Number of features          : 37195
* Number of clusters          : 10
* Initializing cluster centers...100.00%.
* Clustering...completed 27/100 iterations (~0.06 seconds/iteration)...converged in 27 iterations.
* [Step 10/11] Clustering vocabulary level 2, branch 9.
* Number of features          : 14981
* Number of clusters          : 10
* Initializing cluster centers...100.00%.
* Clustering...completed 46/100 iterations (~0.04 seconds/iteration)...converged in 46 iterations.
* [Step 11/11] Clustering vocabulary level 2, branch 10.
* Number of features          : 22034
* Number of clusters          : 10
* Initializing cluster centers...100.00%.
* Clustering...completed 37/100 iterations (~0.04 seconds/iteration)...converged in 37 iterations.
* Finished creating Bag-Of-Features
function [features, featureMetrics, varargout] = exampleExtractor(I)
    [height, width, numChannels] = size(I); 
    gridX = 1:gridStep:width; 
    gridY = 1:gridStep:height; 
    [X,Y] = meshgrid(gridX, gridY); 
    gridLocations = [X(:), Y(:)]; 
    multiscaleGridPoints = [SIFTPoints(gridLocations, 'Scale', 1.6); 
                            SIFTPoints(gridLocations, 'Scale', 3.2); 
                            SIFTPoints(gridLocations, 'Scale', 4.8)]; 
    features = extractFeatures(grayImage, multiscaleGridPoints, ...
                                'Upright', true, 'Method', 'SIFT'); 
    featureMetrics = var(features, [], 2); 
        varargout{1} = multiscaleGridPoints.Location; 
Creating an inverted image index using Bag-Of-Features.
-------------------------------------------------------
Creating Bag-Of-Features.
-------------------------
* Selecting feature point locations using the Detector method.
* Extracting SURF features from the selected feature point locations.
** detectSURFFeatures is used to detect key points for feature extraction.