How to use vlfeat sift matching function in C code?

2.1k views Asked by At

I just found one similar question here. But I just want to do a matching based on the description result from vlfeat. The goal to detect if an image contains the object in another image, based on sift feature description extracting and matching. And I need to do it in C, not Matlab.

So how can I call vl_ubcmatch function in C code?

2

There are 2 answers

0
deltheil On BEST ANSWER

So how can I call vl_ubcmatch function in C code?

This is a MEX function which is only intented to be called from MATLAB. You cannot re-use it as-is from a general purpose C program.

The goal to detect if an image contains the object in another image [...] How to do SIFT matching algorithm if I use vlfeat?

VLFeat C API does not provide SIFT matching functions out-of-the box. So basically you need to adapt the so-called ratio test [1] code section from this MATLAB C code section which is fairly easy (see below).

The main drawback if you want to perform robust matching is that this function does not take into account the geometry, i.e the keypoints coordinates.

What you need in addition is a geometrical consistency check which is typically performed by figuring out if there is an homography between the two images (using as input the descriptor correspondences obtained with the ratio test). This is done with an algorithm like RANSAC since the correspondences may include outliers.

But also you can speed up correspondences computation with a kd-tree.

So an alternative if you need a plain C implementation is relying on Open SIFT by Rob Hess which includes everything you need, as well as a ready-to-use command-line tool (and thus example) of matching:

See match.c.


typedef struct {
    int k1;
    int k2;
    double score;
} Pair;

Pair *
compare(
    Pair *pairs,
    const float *descr1,
    const float *descr2,
    int K1,
    int K2,
    int ND,
    float thresh
)
{
    int k1, k2;

    /* Loop over 1st image descr. */
    for (k1 = 0; k1 < K1; ++k1, descr1 += ND ) {
        float best = FLT_MAX;
        float second_best = FLT_MAX;
        int bestk = -1;

        /* Loop over 2nd image descr. and find the 1st and 2nd closest descr. */
        for (k2 = 0; k2 < K2; ++k2, descr2 += ND ) {
            int bin;
            float acc = 0;

            /* Compute the square L2 distance between descriptors */
            for (bin = 0 ; bin < ND ; ++bin) {
                float delta = descr1[bin] - descr2[bin];
                acc += delta*delta;
                if (acc >= second_best)
                    break;
            }

            if (acc < best) {
                second_best = best;
                best = acc;
                bestk = k2;
            }
            else if (acc < second_best) {
                second_best = acc;
            }
        }

        /* Rewind */
        descr2 -= ND*K2;

        /* Record the correspondence if the best descr. passes the ratio test */
        if (thresh * best < second_best && bestk != -1) {
            pairs->k1 = k1;
            pairs->k2 = bestk;
            pairs->score = best;
            pairs++;
        }
    }

    return pairs;
}
  • K1: number of descriptors in image 1,
  • K2: number of descriptors in image 2,
  • ND: descriptor dimension (= 128 for SIFT),
  • descr1 and descr2: descriptors of image 1 and 2 resp. in row major order, e.g K1 lines x ND columns),
  • thresh: ratio test threshold value, e.g 1.5 in MATLAB code.

[1] see 7.1 Keypoint Matching from D. Lowe's paper.

5
David C. Rankin On

You will use the vlfeat library the same way you use any other library with C. First make sure you have the library installed on your computer and know where it is installed. You will need to include the required header for each part of vlfeat you are using. Generally a generic library header for vlfeat and then a specific header for sift (e.g. #include "sift.h")(sometimes there is no general header). You will need to insure gcc or g++ command includes the proper INCLUDE_PATH and LIBRARY_PATH for your environment that will allow gcc to find your vlfeat files. (e.g. -I/path/to/dir/holding_sift.h and -L/path/to/vlfeatlib) So you will end up with something like this for C:

gcc -o exename exename.c -I/path/to/dir/holding_sift.h -L/path/to/vlfeatlib -lvl

There is documentation on line that will help. See: how to setup a basic C++ project which uses the VLFeat library If you have further questions, just drop a line in the comments.