获取 5 个最相似的图像
Get the 5 most similar images
我想比较哪 5 张图像与输入图像最相似。
为此,我想使用 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
从代码中可以看出,我原以为我会使用均值作为相似度的度量,但我得到的结果并不令人满意(例如,它告诉我杯子的输入图像更相似到一棵树而不是另一个杯子)。
根据您的看法,具有更多相同描述符但相似度低或相似度较低但相似度更高的描述符更好吗?
我有 5 个不同类别(杯子、树、人、桌子和汽车)的 50 张图像,给定一个图像作为输入,程序将 return 5 个最相似的图像,最好属于同一类别。
我可以使用什么度量来代替均值来获得更精确的分类?
谢谢!
根据您的代码,您测量图像 (Ia
) 和所有其他图像 (Ib
) 之间的相似度。因此,您将 Ia
的 SIFT 描述符与所有 Ib
的 SIFT 描述符进行比较 - 这会为您提供每个图像对 (matches
) 的特征匹配列表以及每个特征的欧氏距离对 (scores
).
现在使用图像对的所有 scores
的平均值作为相似性的度量并不是一种非常稳健的方法,因为只有一个特征匹配的图像对可能(偶然地)导致更好的 "similarity" 而不是具有许多特征的图像对 - 我想这对你的任务来说是一个不切实际的解决方案。
关于你的问题,有 meaningful/robust 个描述符总是比有很多无意义的描述符更好,即使只有几个(当然越多越好!)。
建议:为什么不只计算内点数(= 每个图像对的特征匹配数,numel(matches)
)?
有了这个,同一个物体的图像之间应该比不同物体的图像更多的内点,所以那些有 5 个最内点的对应该是最相似的。
如果您只是想区分杯子和树,应该可以。如果您的分类任务变得越来越困难并且您需要区分不同类型的树,那么 SIFT 不是最好的算法。学习方法会带来更好的结果...但取决于您的任务。
我想比较哪 5 张图像与输入图像最相似。
为此,我想使用 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
从代码中可以看出,我原以为我会使用均值作为相似度的度量,但我得到的结果并不令人满意(例如,它告诉我杯子的输入图像更相似到一棵树而不是另一个杯子)。
根据您的看法,具有更多相同描述符但相似度低或相似度较低但相似度更高的描述符更好吗? 我有 5 个不同类别(杯子、树、人、桌子和汽车)的 50 张图像,给定一个图像作为输入,程序将 return 5 个最相似的图像,最好属于同一类别。
我可以使用什么度量来代替均值来获得更精确的分类? 谢谢!
根据您的代码,您测量图像 (Ia
) 和所有其他图像 (Ib
) 之间的相似度。因此,您将 Ia
的 SIFT 描述符与所有 Ib
的 SIFT 描述符进行比较 - 这会为您提供每个图像对 (matches
) 的特征匹配列表以及每个特征的欧氏距离对 (scores
).
现在使用图像对的所有 scores
的平均值作为相似性的度量并不是一种非常稳健的方法,因为只有一个特征匹配的图像对可能(偶然地)导致更好的 "similarity" 而不是具有许多特征的图像对 - 我想这对你的任务来说是一个不切实际的解决方案。
关于你的问题,有 meaningful/robust 个描述符总是比有很多无意义的描述符更好,即使只有几个(当然越多越好!)。
建议:为什么不只计算内点数(= 每个图像对的特征匹配数,numel(matches)
)?
有了这个,同一个物体的图像之间应该比不同物体的图像更多的内点,所以那些有 5 个最内点的对应该是最相似的。
如果您只是想区分杯子和树,应该可以。如果您的分类任务变得越来越困难并且您需要区分不同类型的树,那么 SIFT 不是最好的算法。学习方法会带来更好的结果...但取决于您的任务。