14

OpenCV has very good documentation on generating SIFT descriptors, but this is a version of "weak SIFT", where the key points are detected by the original Lowe algorithm. The OpenCV example reads something like:

img = cv2.imread('home.jpg')
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

sift = cv2.SIFT()
kp = sift.detect(gray,None)
kp,des = sift.compute(gray,kp)

What I'm looking for is strong/dense SIFT, which does not detect keypoints but instead calculates SIFT descriptors for a set of patches (e.g. 16x16 pixels, 8 pixels padding) covering an image as a grid. As I understand it, there are two ways to do this in OpenCV:

  • I could divide the image in a grid myself, and somehow convert those patches to KeyPoints
  • I could use a grid-based feature detector

In other words, I'd have to replace the sift.detect() line with something that gives me the keypoints I require.

My problem is that the rest of the OpenCV documentation, especially wrt Python, is severely lacking, so I have no idea how to achieve either of these things. I see in the C++ documentation that there are keypoint detectors for grid, but I don't know how to use these from Python.

The alternative is to switch to VLFeat, which has a very good DSift/PHOW implementation but means that I'll have to switch from python to matlab.

Any ideas? Thanks.

Doa
  • 1,965
  • 4
  • 19
  • 35
  • The newest versions of OpenCV (or at least its Python bindings) don't seem to support .detect and .compute anymore... Instead you have to use .detectAndCompute, which means that it's no longer possible to generate your own keypoints. – bard Dec 03 '13 at 00:11
  • That is not true for opencv3 – P.R. Nov 13 '15 at 21:57

3 Answers3

23

You can use Dense Sift in opencv 2.4.6 <. Creates a feature detector by its name.

cv2.FeatureDetector_create(detectorType)

Then "Dense" string in place of detectorType

eg:-

dense=cv2.FeatureDetector_create("Dense")
kp=dense.detect(imgGray)
kp,des=sift.compute(imgGray,kp)
madan ram
  • 1,260
  • 2
  • 19
  • 26
  • Not that I want to Hijack this answer, but is it possible to do the same in c++? Could someone point me in the right direction? – The Nomadic Coder May 28 '14 at 12:51
  • 1
    @SemicolonWarrier Yes, it is possible. Look here http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html#featuredetector-create – Yasser Souri Aug 10 '14 at 17:08
4

I'm not sure what your goal is here, but be warned, the SIFT descriptor calculation is extremely slow and was never designed to be used in a dense fashion. That being said, OpenCV makes it fairly trivial to do so.

Basically instead of using sift.detect(), you just fill in the keypoint array yourself by making a grid a keypoints however dense you want them. Then a descriptor will be calculated for each keypoint when you pass the keypoints to sift.compute().

Depending on the size of your image and the speed of your machine, this might take a very long time. If copmutational time is a factor, I suggest you look at some of the binary descriptors OpenCV has to offer.

David Nilosek
  • 1,422
  • 9
  • 13
  • 1
    Thanks David. My question then would be: with what exactly do I fill the keypoint array? Can I somehow deduce the correct format from the OpenCV API page? Thanks for the heads up on SIFT speed, the VLFeat dense sift implementation appears to be really fast so I guess I'll have to go with that. – Doa Nov 23 '13 at 23:06
  • 1
    Also, the goal is the use it for scene/object classification, for which dense sift appears to be better suited than "normal" sift. – Doa Nov 23 '13 at 23:07
  • I just answered the question with an example here http://stackoverflow.com/a/33702400/2156909 if it is still of interest. – P.R. Nov 13 '15 at 21:56
2

Inspite of the OpenCV way being the standard, it was too slow for me. So for that, I used pyvlfeat, which is basically python bindings to VL-FEAT. The functions carry similar syntax as the Matlab functions

The Nomadic Coder
  • 580
  • 1
  • 4
  • 16