我刚刚在这里发现了一个类似的问题。但我只想根据vlfeat
. 基于筛选特征描述提取和匹配检测图像是否包含另一图像中的对象的目标。我需要用 C 来做,而不是 Matlab。
那么如何vl_ubcmatch
在 C 代码中调用函数呢?
那么如何
vl_ubcmatch
在 C 代码中调用函数呢?
这是一个MEX 函数,仅打算从 MATLAB 中调用。您不能从通用 C 程序中按原样重复使用它。
检测图像是否包含另一个图像中的对象的目标 [...] 如果我使用 vlfeat,如何进行 SIFT 匹配算法?
VLFeat C API 不提供开箱即用的 SIFT 匹配函数。所以基本上你需要从这个相当容易的MATLAB C 代码部分改编所谓的比率测试[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),descr1
和descr2
: 图像 1 和 2 的描述符。按行主要顺序,例如K1
行 xND
列),thresh
:比率测试阈值,例如1.5
在 MATLAB 代码中。[1] 参见D. Lowe 论文中的7.1 关键点匹配。
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.