4

I just discovered that SIFT writes the Octave as packed value (octave, layer and scale).
I need this value unpacked since I have to use SIFT detector in combination with other descriptors (ORB, BRIEF, SURF, BRISK). Here you can find a similar question.
I already tried different solutions (see code below) but none seems to work in python (this one as well).
Any suggestion?

unpackOctave(keypoints[i], octave, layer, scale)     

or:

unpackOctave(const KeyPoint& kpt, int& octave, int& layer, float& scale){    
    octave = kpt.octave & 255;    
    layer = (kpt.octave >> 8) & 255;    
    octave = octave < 128 ? octave : (-128 | octave);    
    scale = octave >= 0 ? 1.f/(1 << octave) : (float)(1 << -octave);    
}
Furin
  • 532
  • 10
  • 31

2 Answers2

5

I define a Python function to unpack SIFT Octave:

#!/usr/bin/python3
## 2018.01.23 11:12:30 CST
## created by Silencer

def unpackSIFTOctave(kpt):
    """unpackSIFTOctave(kpt)->(octave,layer,scale)
    @created by Silencer at 2018.01.23 11:12:30 CST
    @brief Unpack Sift Keypoint by Silencer
    @param kpt: cv2.KeyPoint (of SIFT)
    """
    _octave = kpt.octave
    octave = _octave&0xFF
    layer  = (_octave>>8)&0xFF
    if octave>=128:
        octave |= -128
    if octave>=0:
        scale = float(1/(1<<octave))
    else:
        scale = float(1<<-octave)
    return (octave, layer, scale)

For example, I detect the sift kpts on the panda.

enter image description here

Use unpackSiftOctave to unpack the sift kpts, get a list of (octave, layer, scale). Part of the unpacked result.

[(0, 3, 1.0),
 (1, 3, 0.5),
 (-1, 3, 2.0),
 (-1, 3, 2.0),
 (2, 1, 0.25),
 (2, 1, 0.25),
 (-1, 1, 2.0),
 (-1, 1, 2.0),
 (0, 2, 1.0),
 (1, 3, 0.5),
 ...
]
Kinght 金
  • 17,681
  • 4
  • 60
  • 74
2

Kinght's answer seems correct, but I just want to add that I was able to find a good implementation of the unpackOctave(keypoint) method in a Github repository that implements the whole SIFT algorithm for keypoint detection and description in Python. It is very good for understanding SIFT and getting your hands dirty with it (if you're familiar with Python), and it comes with a two part tutorial.

This is how they implemented the unpackOctave(keypoint) method -- very similar to the original C implementation (and also to Kinght's answer).

def unpackOctave(keypoint):
    """Compute octave, layer, and scale from a keypoint
    """
    octave = keypoint.octave & 255
    layer = (keypoint.octave >> 8) & 255
    if octave >= 128:
        octave = octave | -128
    scale = 1 / float32(1 << octave) if octave >= 0 else float32(1 << -octave)
    return octave, layer, scale
nim.py
  • 467
  • 1
  • 6
  • 19