我试图从两个图像中进行特征提取的编码,这两个图像实际上是相似的。我试图从两个图像中提取交叉点,并计算从一个交叉点到所有其他点的距离。对所有点和两个图像迭代此过程。
然后我比较了两个图像中点之间的距离但是我发现即使对于不同的图像我也得到相同的距离并且无法区分它们。
这种方法有什么方法可以改进代码,还是有其他方法可以找到相似性。
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 skel 1 skel2
答案 0 :(得分:0)
我认为你的代码不是问题。相反,似乎您的要素描述符不够强大,或者您的比较方法不够强大,或者两者的组合。这为我们提供了探索问题解决方案的几种选择。
您正在构建一个由骨架交叉点之间的距离组成的图像特征。这是一种不寻常的方法,非常有趣。它让我想起了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个类似距离。使用' peppers.png'和' pears.png'用Matlab分发测试图像,我发现一个图像中有2000多个交叉点,另一个图像中有260个交点。有这么多点,重叠> 20个相似距离是微不足道的。在图像中,交点的数量要小得多。您可以仔细调整相似距离的阈值,但我认为这个指标可能过于简单化了。
在机器学习中,比较两个特征向量的简单方法是向量相似性或距离。您可以探索多种距离指标。常见的包括
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
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
如果这些不起作用,您可能需要训练分类器以找到更复杂的功能来区分相似和不相似的图像。