Image searching system using Bag Of Features method
Question: I am doing a project making visual search system using Bag Of Features method
but have little question. If I understood the method correctly, the method has
few steps.

  1. Feature extraction from an image
  2. Vector quantization
  3. Image searching from a database

I am stock at between 2 and 3. I use python package called scikit-learn to
quantize the feature vectors extracted using SIFT algorithm in opencv. For
now, I set the cluster size 8 with default setting. I tried to generate
histogram out of the output codebook and display it. I tried this with same
image several times but all the histograms looked different. The code is
below. It is a simple code.

    
    
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.cluster import KMeans
    
    def feature_extract(img):
        sift = cv2.SIFT()
        gray = img
        kp, des = sift.detectAndCompute(gray, None)
        return kp, des
    
    
    def codebook(k, des):
        km = KMeans(n_clusters=k, max_iter=500)
        km.fit(des)
        codebook = km.cluster_centers_
        label = km.labels_
        return codebook, label
    
    img = cv2.imread('sift_example.jpg', 0)
    kp, des = feature_extract(img)
    
    k = 8
    codebook, label = codebook(k, des)
    plt.hist(label, bins=range(0,9), align='left'), plt.show()
    

I suspect that the problem come from the clustering error. Since the initial
centers for clustering is set to random, the final converged centers are
different. Is there any solution to this?


Answer: You are right about the randomness of KMeans initial centers, but I would
assume that if you dont explicitely change the initial seed of the random
number generator, then it would always pick the same "random" features as
initial centers. Another reason could be that, if feature detection/extraction
is multithreaded, the features computed on your image can appear in different
orders between each run. You might check that aswell.

Alternatively, you can pass your own centers to KMeans as initial centroids so
you could pick them or generate them by yourself to make sure KMeans starts
with always the same initial centers

