Search code examples
pythonopencvsift

OpenCV (Python) unpack SIFT Octave


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);    
}

Solution

  • 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),
     ...
    ]