如何在C代码中使用vlfeat筛选匹配函数?

时间:2014-11-14 07:31:32

标签: c sift vlfeat

我刚刚发现了一个类似的问题here。但我只想根据vlfeat的描述结果进行匹配。基于筛选特征描述提取和匹配来检测图像是否包含另一图像中的对象的目标。我需要用C语言,而不是Matlab。

那么如何在C代码中调用vl_ubcmatch函数?

2 个答案:

答案 0 :(得分:2)

  

那么如何在C代码中调用vl_ubcmatch函数?

这是MEX function意图从MATLAB调用。您无法按原样从通用C程序中重复使用它。

  

检测图像是否包含另一个图像中的对象的目标[...]如果我使用vlfeat,如何进行SIFT匹配算法?

VLFeat C API不提供开箱即用的SIFT匹配功能。所以基本上你需要调整这个MATLAB C code section中所谓的比率测试 [1]代码部分,这很容易(见下文)。

如果你想进行强健匹配,主要的缺点是这个函数没有考虑几何,即关键点坐标。

您还需要进行几何一致性检查,通常通过确定两个图像之间是否存在单应性(使用比率测试获得的描述符对应关系作为输入)来执行。这是通过像RANSAC这样的算法完成的,因为对应关系可能包括异常值。

但您也可以使用kd-tree加速对应计算。

如果你需要一个简单的C实现,那么另一个选择就是依靠Rob Hess的Open SIFT,其中包括你需要的一切,以及一个随时可用的命令行工具(例如)匹配:

请参阅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:图片1中的描述符数量,
  • K2:图像2中的描述符数量,
  • ND:描述符维度(对于SIFT = 128),
  • descr1descr2:图片1和2的描述符。按行主要顺序,例如K1行x ND列),
  • thresh:比率测试阈值,例如MATLAB代码中的1.5

[1]见D. Lowe的论文中的7.1 Keypoint Matching

答案 1 :(得分:0)

您将使用vlfeat库,方法与使用C的任何其他库相同。首先确保您的计算机上安装了库并知道它的安装位置。您需要为正在使用的vlfeat的每个部分添加所需的标头。通常是vlfeat的通用库标头,然后是sift的特定标头(例如#include "sift.h")(有时没有通用标头)。您需要确保gccg++命令包含适用于您的环境的INCLUDE_PATHLIBRARY_PATH,以便gcc找到您的vlfeat文件。 (例如-I/path/to/dir/holding_sift.h-L/path/to/vlfeatlib)所以你最终会得到类似 C 的内容:

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

有一些在线文档可以提供帮助。请参阅:how to setup a basic C++ project which uses the VLFeat library如果您还有其他问题,请在评论中添加一行。