如何使用SIFTalgorithm来计算相似的两幅图像?

我已经使用了Andrea VedaldiSIFT实现来计算两个相似图像的筛选描述符(第二个图像实际上是从不同angular度放大同一个对象的图片)。

现在我无法弄清楚如何比较描述符来告诉图像有多相似

我知道这个问题,除非你以前真的玩过这些东西,否则这个问题是无法回答的,但是我认为以前做过这个的人可能会知道这个 ,于是我就提出了这个问题。

我做的小生成描述符:

>> i=imread('p1.jpg'); >> j=imread('p2.jpg'); >> i=rgb2gray(i); >> j=rgb2gray(j); >> [a, b]=sift(i); % a has the frames and b has the descriptors >> [c, d]=sift(j); 

首先,你不是应该使用vl_sift而不是筛选?

其次,您可以使用SIFT特征匹配来查找两个图像中的对应关系。 以下是一些示例代码:

  I = imread('p1.jpg'); J = imread('p2.jpg'); I = single(rgb2gray(I)); % Conversion to single is recommended J = single(rgb2gray(J)); % in the documentation [F1 D1] = vl_sift(I); [F2 D2] = vl_sift(J); % Where 1.5 = ratio between euclidean distance of NN2/NN1 [matches score] = vl_ubcmatch(D1,D2,1.5); subplot(1,2,1); imshow(uint8(I)); hold on; plot(F1(1,matches(1,:)),F1(2,matches(1,:)),'b*'); subplot(1,2,2); imshow(uint8(J)); hold on; plot(F2(1,matches(2,:)),F2(2,matches(2,:)),'r*'); 

vl_ubcmatch()基本上做到以下几点:

假设你在F1中有一个点P,你想在F2中find“最好”的匹配。 一种方法是将F1中的P的描述符与D2中的所有描述符进行比较。 通过比较,我的意思是find欧几里德距离(或两个描述符差异的L2范数)。

然后,我在F2中find两个点,比如U和V,分别与P有最低和最低的距离(比如Du和Dv)。

下面是Lowe推荐的:如果Dv / Du> = threshold(我在示例代码中使用了1.5),那么这个匹配是可以接受的。 否则,它被模糊地匹配,并被拒绝作为信件,我们不匹配F2中的任何一点到P.本质上,如果最好的和次好的匹配之间有很大的区别,你可以期望这是一个质量匹配。

这是很重要的,因为在图像中模糊的匹配有很大的空间:想象湖中的匹配点或者有多个窗口的build筑物,描述符可能看起来很相似,但是对应关系显然是错误的。

你可以用许多方法进行匹配..你可以很容易地用MATLAB自己做,也可以使用KD-tree或类似FLANN的近似数字search来加速OpenCV 。

编辑:另外, 在MATLAB中有几个kd-tree实现 。

你应该阅读David Lowe的论文 ,其中谈到如何做到这一点。 如果你想比较完全相同的对象的图像应该是足够的。 如果你想匹配同一类别的不同对象的图像(例如汽车或飞机),你可能要看Grauman和Darrell的金字塔匹配内核 。

尝试比较第一张图片中的每个描述符与第二张描述符(使用欧氏距离)。 因此,您可以根据第一个图像和第二个图像中最相似的邻居描述符之间的相似度为每个描述符分配一个分数。 所有这些分数的统计量度(总和,平均值,离差,平均误差等)可以让您估计图像的相似程度。 尝试不同的附近大小和统计措施的组合,给你最好的答案。

如果只想比较放大和旋转的图像与已知的旋转中心,则可以在对数极坐标中使用相位相关性。 通过峰值的清晰度和相位相关的直方图,您可以判断图像的接近程度。 您也可以使用傅立叶系数绝对值的欧氏距离。

如果要比较SIFT描述符,除了欧几里德距离之外,还可以使用“漫射距离” – 将描述符逐渐变得更粗糙,并将它们与原始描述符连接起来。 那样的“大规模”特征相似性将具有更多的权重。

如果你想在图像之间进行匹配,你应该使用vl_ubcmatch(如果你没有使用它)。 您可以解释输出的“分数”,看看function有多接近。 这表示两个匹配特征描述符之间的欧氏距离的平方。 您也可以改变最佳匹配和第二最佳匹配之间的阈值作为input。