定义:
A(i, j) = 1 是十字的中点,如果元素
A(i-1, j) = 1
A(i+1, j) = 1
A(i, j+1) = 1
A(i, j-1) = 1。
这些元素和中点一起形成矩阵 A 中的十字,其中 A 至少是一个 3×3 矩阵,并且i, jε ℕ\{0}。
假设上图是 8×8 矩阵 A,以自然数 1, 2, 3 ... 作为元素。根据这个定义,矩阵共有 3 个交叉点。十字的中点位于 A(2,2)、A(5, 4) 和 A(5, 5) 上。
我想要做的是编写一个函数来查找矩阵 A 中的交叉数。我有一个想法,但我不确定它是最佳的。这是它的伪代码:
ITERATE FROM row 2 TO row 7
ITERATE FROM column 1 TO column 8
IF current element contains 1
INCREMENT xcount by 1
IF xcount >= 3
CHECK IF counted 1:s is part of a cross
ELSE IF xcount IS NOT 0
SET xcount to 0
这个想法是迭代从第 2 行到第 7 行的每一列。如果我在同一行上找到 3 个连续的 1:s,我会立即检查 1:s 是否属于交叉。这应该可行,但想象一下有一个非常大的矩阵 A - 在这种情况下这段代码的效率有多高?难道这个问题不能用向量表示法来解决吗?
非常感谢任何答案。提前致谢!
目前还没有接近 matlab,但这就是我要做的。假设A
是二进制的(只有 0'a 和 1's):
crs=[0 1 0 ; 1 1 1 ; 0 1 0]; % a minimal "cross" filter
C=conv2(A,crs./sum(crs(:)),'same'); % convolve A with it
[x y]=find(C>0.9); % find x,y positions of the crosses by looking
% for peak values of C
所以你基本上与“最小”(标准化)交叉进行卷积(crs
)并使用寻找峰值max
. x
and y
是你的交叉位置的坐标。不需要使用 for 循环,只需内置(并且相当快)2d 卷积,以及max
功能。
阈值条件C>0.9
,只是为了说明需要有一个按强度加权的阈值crs
。在这种情况下我已经标准化crs
在卷积线(crs/sum(crs(:))
) so if A
是一个二进制矩阵,如示例中所示,您会发现最小归一化交叉的卷积将留下交叉所在像素的值1
,而其他像素将小于 1 (这就是我任意选择 0.9 的原因)。所以你可以将阈值替换为C==1
,如果它始终是二进制文件。
另一种可视化十字位置的方法就是看C.*(C==1)
。这将生成一个大小为的矩阵A
with 1
只有十字架所在的地方...
EDIT:
为了获得最大速度,您可以考虑将其写为单行,例如:
[x y]=find(conv2(A,[0 1 0 ; 1 1 1 ; 0 1 0]./5,'same')==1);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)