我想比较哪五个最相似的图像与输入图像。
为此,我想使用SIFT(VLFeat library)并比较各自的描述符。
因此,我使用vl_ubcmatch
(doc here)方法计算图像之间的相似度。
这是代码:
path_dir = './img/';
imgs = dir(path_dir);
imgs = imgs(3 : end);
numImgs = size(imgs);
numImgs = numImgs(1);
path1 = './img/car01.jpg';
Ia = imread(path1);
Ia = single(rgb2gray(Ia));
[fa, da] = vl_sift(Ia);
results = struct;
m = 0;
j = 1; % indice dell'img (del for)
for img = imgs'
path = strcat(path_dir, img.name);
if(strcmp(path1, path) == 0)
Ib = imread(path);
Ib = single(rgb2gray(Ib));
[fb, db] = vl_sift(Ib);
[matches, scores] = vl_ubcmatch(da, db);
s = sum(scores);
[r, c] = size(scores);
m = s ./ c;
results(j).measure = m;
results(j).img = path;
j = j + 1;
end
end
从代码中可以看出,我认为我会使用均值来衡量相似度,但我得到的结果并不令人满意(例如,它告诉我杯子的输入图像更像是一个树比另一个杯子。)
根据你的说法,拥有更多相同的描述符,但描述符的相似性或相似性较低但具有较大的相似性是否更好? 我有50个不同类别(杯子,树木,人物,桌子和汽车)的图像,并且,如果输入图像,程序将返回5个最相似的图像,最好属于同一类别。
我可以使用什么测量值代替均值来获得更精确的分类? 谢谢!
答案 0 :(得分:0)
根据您的代码,您可以衡量图像(Ia
)与所有其他图像(Ib
)之间的相似度。因此,您将Ia
的SIFT描述符与所有Ib
的SIFT描述符进行比较 - 它们为您提供每个图像对(matches
)的要素匹配列表以及每个要素的欧几里德距离对(scores
)。
现在使用图像对的所有scores
的平均值作为相似性的度量并不是一种非常强大的方法,因为只有一个特征匹配的图像对可能(偶然)导致更好的“相似性”而不是具有许多功能的图像对 - 我认为这对你的任务来说是一个不切实际的解决方案。
关于你的问题,拥有有意义/强大的描述符总是更好,即使只有少数(当然越多越好!),而不是有很多无意义的描述符。
提案:为什么不计算内部数量(=每个图像对的特征匹配数量numel(matches)
)?
有了这个,它应该在同一个物体的图像之间提供比不同物体更多的内部,所以那些具有5个最内层的那些对应该是最相似的。
如果你只想区分一个杯子和一棵树它应该有效。如果您的分类任务变得越来越困难,并且您需要区分不同类型的树,则SIFT不是最佳使用算法。学习方法会带来更好的结果......但取决于你的任务。