9

Edit: Here is the complete code for anyone having issues still github.com

I'm trying to do an image recognition project using SIFT and BOW. So far, I'm trying to train and build my dictionary. I've read in images from 5 different classes, computed descriptors and added them all to a python list ([]) side by side. Now, I'm trying to use the python version of BOWMeansTrainer to cluster my descriptors with k = 5 (is this correct? for 5 classes?). I'm trying to pass cluster() my descriptor vector, but I'm getting the error

Traceback (most recent call last):


File "C:\Python27\Project2\beginning.py", line 40, in <module>
    bow.cluster(des)
TypeError: descriptors data type = 17 is not supported

I'm not really sure what format to put my numpy array in, does anyone have an idea?

sift = cv2.SIFT()

descriptors = []
for path in training_paths:
    image = cv2.imread(path)
    print path
    gray = cv2.cvtColor(image, cv2.CV_LOAD_IMAGE_GRAYSCALE)
    kp, dsc= sift.detectAndCompute(gray, None)
    descriptors.append(dsc)

des = np.array(descriptors)

k=5
bow = cv2.BOWKMeansTrainer(k)
bow.cluster(des)

As you can see I keep appending the sift descriptors, and then try to convert to a numpy array (the needed format).

blurb
  • 600
  • 4
  • 20
  • The parameter k of the BoW algorithm has nothing to do with the number of classes you are trying to classify, it is the number of clusters (i.e. visual words). It basically indicates the dimensionality of the resulting feature vector, 5 is waaaay to small. I've seen it used with success with k from 500-1000 to up to 1M. Take a look [here](http://cs.nyu.edu/~fergus/teaching/vision_2012/9_BoW.pdf) – powder Apr 12 '16 at 07:57
  • you're right powder, this is an older post but I remember thinking that 5 clusters was logical because I had 5 classes, so I wanted 5 centroids. A more realistic number would be much higher – blurb Apr 12 '16 at 19:51

1 Answers1

9

Just figured it out thanks to the opencv forums, instead of using another list (I used descriptors above), just add the descriptors you find directly to your bag with bow.add(dsc)

dictionarySize = 5

BOW = cv2.BOWKMeansTrainer(dictionarySize)

for p in training_paths:
    image = cv2.imread(p)
    gray = cv2.cvtColor(image, cv2.CV_LOAD_IMAGE_GRAYSCALE)
    kp, dsc= sift.detectAndCompute(gray, None)
    BOW.add(dsc)

#dictionary created
dictionary = BOW.cluster()

EDIT: For anyone else having trouble I've uploaded the rest of the script here

blurb
  • 600
  • 4
  • 20
  • Hi, I want to make a 10-class image classification which I want to run on android smartphone. Can you tell me your findings with python?? – sau Mar 16 '16 at 09:55
  • @sau could you clarify what you're looking for? – blurb Mar 16 '16 at 20:03
  • I want to run a deep learning model on smartphone to classify image into some categories. Now I want that model to be very very small in size. – sau Mar 17 '16 at 04:57
  • @briansrlsjust upvoted your answer as this helps a lot given the lack of clear documentation on how to do this. Would you kindly edit your answer adding your full code as in your OP? I'm not sure I understand where to put `bow.add(doc)` -- thx – pepe May 02 '16 at 19:06
  • @pepe sorry it took so long, I just added the code. It really is a pain trying to figure this stuff out so I'm glad I could help. – blurb Jun 16 '16 at 16:07
  • Hey man, could you attach the rest of the code too? like what do you do after the cluster step. I cant find a good example to follow on! Thanks :) – Wboy Jul 06 '16 at 14:36
  • @Wboy I just uploaded the script to my github, you can take a look [here](https://github.com/briansrls/SIFTBOW) – blurb Jul 07 '16 at 15:57