【问题标题】:How to use distance to extract features and compare images: : matlab如何使用距离来提取特征和比较图像::matlab
【发布时间】:2015-05-11 05:40:20
【问题描述】:

我试图编写代码以从这两个实际上相似的图像中提取特征。我试图从两个图像中提取交点并计算从一个交点到所有其他点的距离。这个过程在所有点和两个图像中都进行了迭代。

然后我比较了两幅图像中点之间的距离但我发现即使是不同的图像也会得到相同的距离并且无法区分它们。

这种方法有什么方法可以改进代码还是有其他方法可以找到相似度。

I = bwmorph(I,'skel',Inf);
II = bwmorph(II,'skel',Inf);
[i,j] = ind2sub(size(I),find(bwmorph(bwmorph(I,'thin',Inf),'branchpoint') == 1));
[i1,j1] = ind2sub(size(II),find(bwmorph(bwmorph(II,'thin',Inf),'branchpoint') == 1));
figure,imshow(I); hold on; plot(j,i,'rx');
figure,imshow(II); hold on; plot(j1,i1,'rx')
m=size(i,1);
n=size(j,1);
m1=size(i1,1);
n1=size(j1,1);
for x=1:m
   for y=1:n
       d1(y,x)=round(sqrt((i(y,1)-i(x,1)).^2+(j(y,1)-j(x,1)).^2));
   end
end
for x1=1:m1
    for y1=1:n1
       dd1(y1,x1)=round(sqrt((i1(y1,1)-i1(x1,1)).^2+(j1(y1,1)-j1(x1,1)).^2));
    end
end
size(d1);
k1=reshape(d1,1,m*n);
k=sort(k1);
k=unique(k);

size(dd1);
k2=reshape(dd1,1,m1*n1);
k2=sort(k2);
k2=unique(k2);

z = intersect(k,k2)
length(z);
if length(z)>20
    disp('similar images');
else
    disp('dissimilar images');
end

这是我尝试提取特征的代码的一部分。 输入1 输入2 骷髅 1 skel2

【问题讨论】:

  • 您正在对距离进行排序,而不是按照它们出现的顺序使用它们。这可能是问题所在。尝试比较差异而不进行排序。
  • @optimist 我在没有排序的情况下编写了代码,但仍然无法匹配图像。有时匹配距离的数量更多地出现在不同的图像中。关于排序,我不是专家,但出于好奇询问排序将如何影响结果,因为我猜排序是为了按特定顺序排列矩阵中的元素。
  • 您可以发布没有红色 x 的原始图片吗?
  • @Cecilia 我已经添加了输入图像和处理后的图像。

标签: matlab image-processing


【解决方案1】:

我认为您的代码不是问题。相反,似乎要么你的特征描述符不够强大,要么你的比较方法不够强大,或者两者兼而有之。这为我们提供了几种探索问题解决方案的选择。

特征描述符

您正在构建由骨架交点之间的距离组成的图像特征。这是一种不寻常的方法,也是一种非常有趣的方法。它让我想起了巅峰星座,这是 Shazam 用于音频指纹歌曲的一项功能。如果您有兴趣探索更复杂的技术,请查看 Avery Li-Chun Wang 的 "An Industrial Strength Audio Search Algorithm"。我相信您可以将他们的特征描述符调整到您的应用程序中。

但是,如果您想要更简单的解决方案,还有其他一些选择。您当前的描述符使用unique 来查找骨架交点之间的一组唯一距离。看看下面的直线和等边三角形的图像,它们都有 5 个单位线长。如果我们使用顶点之间的唯一距离来制作特征,那么两幅图像具有相同的特征,但我们也可以统计直方图中每个长度的行数。

直方图保留了更多图像结构作为特征的一部分。使用直方图可能有助于更好地区分相似和不同的情况。

这里有一些使用 Matlab 演示图像 pears.png 和 peppers.png 的直方图功能演示代码。我在从您提供的图像中提取骨架时遇到了困难,但您应该能够轻松地将此代码调整到您的应用程序中。

I1 = = im2bw(imread('peppers.png'));
I2 = = im2bw(imread('pears.png'));
I1_skel = bwmorph(I1,'skel',Inf);
I2_skel = bwmorph(I2,'skel',Inf);
[i1,j1] = ind2sub(size(I1_skel),find(bwmorph(bwmorph(I1_skel,'thin',Inf),'branchpoint') == 1));
[i2,j2] = ind2sub(size(I2_skel),find(bwmorph(bwmorph(I2_skel,'thin',Inf),'branchpoint') == 1));

%You used a for loop to find the distance between each pair of
%intersections. There is a function for this. 
d1 = round(pdist2([i1, j1], [i1, j1]));
d2 = round(pdist2([i2, j2], [i2, j2]));

%Choose a number of bins for the histogram. 
%This will be the length of the feature. 
%More bins will preserve more structure. 
%Fewer bins will help generalize between similar but not identical images.
num_bins = 100; 

%Instead of using `unique` to remove repetitions use `histcounts` in R2014b 
%feature1 = histcounts(d1(:), num_bins);
%feature2 = histcounts(d2(:), num_bins);

%Use `hist` for pre R2014b Matlab versions
feature1 = hist(d1(:), num_bins);
feature2 = hist(d2(:), num_bins);

%Normalize the features
feature1 = feature1 ./ norm(feature1);
feature2 = feature2 ./ norm(feature2);

figure; bar([feature1; feature2]'); 
title('Features'); legend({'Feature 1', 'Feature 2'}); 
xlim([0, num_bins]);

以下是每张图像中检测到的交点

以下是生成的功能。您可以看到图像之间的明显差异。

功能比较

要考虑的第二部分是您如何比较您的功能。目前,您只是在寻找 >20 个相似的距离。使用 Matlab 分发的“peppers.png”和“pears.png”测试图像,我在一张图像中找到了 2000 多个交点,在另一张图像中找到了 260 个。有这么多的点,重叠超过 20 个相似距离是微不足道的。在您的图像中,交叉点的数量要少得多。您可以仔细调整相似距离的阈值,但我认为这个指标可能过于简单化。

在机器学习中,比较两个特征向量的一种简单方法是向量相似度或距离。您可以探索多种距离指标。常见的有

  1. 余弦距离

score_cosine = feature1 * feature2'; %Cosine distance between vectors

%Set a threshold for cosine similarity [0, 1] where 1 is identical and 0 is perpendicular
cosine_threshold = .9;
disp('Cosine Compare')
disp(score_cosine)
if score_cosine > cosine_threshold
    disp('similar images');
else
    disp('dissimilar images');
end
  1. 欧几里得距离

score_euclidean = pdist2(feature1, feature2);

%Set a threshold for euclidean similarity where smaller is more similar
euclidean_threshold = 0.1;
disp('Euclidean Compare')
disp(score_euclidean)
if score_euclidean < euclidean_threshold
    disp('similar images');
else
    disp('dissimilar images');
end

如果这些都不起作用,您可能需要训练分类器以找到更复杂的函数来区分相似和不同的图像。

【讨论】:

  • 感谢@Cecilia 的尝试。我在我的图像上尝试了你的代码版本。将阈值保持在 90% 对我来说效果不佳。所有相似的图像都被识别为不同的图像。所以我将阈值更改为 0.5。此时,所有不相似的图像都被识别为相似图像。 n 所以我选择了 0.6、0.55。结果是一样的。我在这篇文章中添加了我的图片。这是因为生成的交叉点而发生的。第一张和第三张图片相似
  • @ANUSHADEVI 我又试了一次,但我认为您最终可能需要一个分类器。我自己无法找到一个好的门槛。我添加了更多细节,以便您自己探索所有途径。
  • 非常感谢您提供这些信息。我肯定会深入研究这些信息。但是你能帮我在这些骨架化图像中找到解决方案吗?我也问过这个问题,但没有得到任何有利的答案。我在骨架化时发现了一些不必要的分支。我怎样才能摆脱它们。我想在深入提取之前我需要清理它。非常感谢..stackoverflow.com/questions/30166166/….
猜你喜欢
  • 2015-04-06
  • 1970-01-01
  • 2015-05-24
  • 1970-01-01
  • 2020-10-16
  • 1970-01-01
  • 1970-01-01
  • 2015-09-20
  • 1970-01-01
相关资源
最近更新 更多