Matlab中使用交叉相关进行3D模板匹配

4

这里是我尝试做的一个最小化示例:

创建3D矩阵

a(:,:,1)=[
    1 2 3 4 1;
    2 3 7 1 4;
    3 7 6 0 9;
    0 3 2 8 1;
    1 4 3 1 1]

a(:,:,2)=[
    1 7 3 4 2;
    2 9 2 3 1;
    1 4 7 7 0;
    1 2 3 4 1;
    0 9 3 3 9]

a(:,:,3)=[
    9 4 0 3 5;
    1 2 3 4 1;
    2 0 2 3 1;
    1 4 2 1 1;
    2 5 7 8 1]

a(:,:,4)=[
    2 3 5 2 0
    0 0 0 0 8
    5 2 7 9 8
    2 4 1 1 0
    6 3 8 7 9]

a(:,:,5)=[
    3 5 1 4 6;
    3 2 8 0 0;
    0 2 1 0 4;
    5 4 5 5 6;
    9 5 9 9 5]

创建3D模板
b(:,:,1)=[
    9 4 0;
    1 2 3;
    2 0 2]

b(:,:,2)=[
    2 3 5;
    0 0 0;
    5 2 7]

b(:,:,3)=[
    3 5 1;
    3 2 8;
    0 2 1]

计算交叉相关 (Matlab中的3D交叉相关)。我认为交叉相关与使用翻转模板的卷积相同。这个理解正确吗?

c=convn(a,b(end:-1:1,end:-1:1,end:-1:1));

查找最佳匹配的下标

[x y z] = ind2sub(size(c),find(c==max(c(:))));
x=x-(size(b, 1) - 1)/2
y=y-(size(b, 2) - 1)/2
z=z-(size(b, 3) - 1)/2

我读到过一个信息,说在最终坐标中必须减去模板大小的一半,但我不再拥有该页面的链接。然而,我认为如果不这样做,返回的坐标将不是模板中心的坐标,而是模板的一个角落。
根据我的示例,我期望得到:x=2y=2z=4。Matlab告诉我是x=4y=4z=4。但是,当更改模板时,...
b(:,:,1)=[
    9 2 3;  
    4 7 7;
    2 3 4]

b(:,:,2)=[
    2 3 4;
    0 2 3;
    4 2 1]

b(:,:,3)=[
    0 0 0;
    2 7 9;
    4 1 1]

我得到了正确的结果(x=3, y=3, z=3)

为了始终获得正确的结果,我需要做出什么改变?


你在哪里读到必须从最终坐标中减去一半的模板大小? 为什么(3,3,3)是正确的结果? - Trilarion
为什么你要将模板与反向的b(end:-1:1,end:-1:1,end:-1:1)进行卷积?为什么不使用1:end呢? - kkuilla
Trilarion:就像我写的那样:我不记得了。但是如果不这样做,你可能会得到模板角落的坐标而不是中心,但我认为它仍然可以工作。你觉得呢? - nightlyop
kkuilla:这是我之前发布的链接:https://dev59.com/Q2jWa4cB1Zd3GeqPnynO。我也看了https://www.youtube.com/watch?v=Ma0YONjMZLI,认为翻转可能是正确的。如果我错了,请纠正我。 - nightlyop
你为什么期望正确的结果是(x, y, z) = (2, 2, 4)呢?在我看来,你正在做正确的事情,最大相关性出现在(4, 4, 4)处,其值为354,而在2, 2, 4处得到的值为352。此外,你可以直接使用c = conv(..., 'same'),而不是从索引中减去。 - 3lectrologos
当在正确的位置叠加模板时,我期望结果位于模板中心。因此,最大相关性不应该在模板完全匹配的地方(即在(x, y, z) = (2, 2, 4)处)吗? - nightlyop
1个回答

2

您的代码没有错误

您的算法是正确的!但不幸的是,在您的情况下,交叉相关的最大值位于(4, 4, 4)而不是您期望的(2, 2, 4)

这是因为在矩阵A中寻找包含在矩阵B中的模式时,您找到了一个类似的模式,但在(4, 4, 4)处具有更高的“强度”。

如果您考虑图像中的模式识别,您的情况类似于尝试在具有很多强度变化的图像中查找圆形。(例如此问题:Image processing to size bubbles in octave)。在提出的答案之一中,您可以看到圆形在图像非常明亮的地方被发现:

enter image description here

我认为您在这里面临类似的问题。


你说得对。当我稍微改变矩阵'a'时,我得到了正确的结果。非常感谢!有没有可能自动检查结果?此外,我认为使用归一化交叉相关可能会得到更好的结果,但是如何在三维卷积中实现呢? - nightlyop
@vrleboss:我不确定那个问题与这里的问题有什么相似之处。那里的代码和你展示的图像是基于霍夫变换进行圆检测的,而不是像你所建议的使用交叉相关进行某种模板匹配。因此,这就像使用图像处理工具箱中的imfindcircles,而不是卷积/相关方法。 - Amro
@Amro 完全同意你的看法。我一直在尝试找到一个好的例子来说明 nightlyop 的问题,但你说得对,这个例子远非理想... 我会继续寻找并更新我的答案。 - vrleboss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接