gpt4 book ai didi

matlab - 获取矩阵元素的邻居

转载 作者:行者123 更新时间:2023-12-03 07:30:48 25 4
gpt4 key购买 nike

我有一个矩阵,对于每个元素,我想获取其周围元素的索引。所有这些结果必须按以下方式存储到矩阵中。矩阵的每一行对应于一个矩阵元素,并且该矩阵的每一列包含 s 个邻居索引。例如,对于 4x4 矩阵,我们将得到一个 16x8 结果数组。某些矩阵元素没有 8 个邻居。

有一个例子,我认为它有效,我有什么方法可以避免 for 循环?:

ElementNeighbors = [];
for n = 1:numel(Matrix)
NeighborsMask = [ n-1 n+1 n+size(matrix,1) n-size(Matrix,1) n-size(Matrix,1)-1 n-size(Matrix,1)+1 ...
n+size(Matrix,1)-1 n+size(Matrix,1)+1 ];

ElementNeighbors = [ElementNeighbors ; NeighborsMask ];
end
ElementNeighbors (ElementNeighbors ==0|ElementNeighbors <0) = NaN;

最佳答案

给定矩阵 M(n,m) 的线性索引,您可以确信元素的左上角邻居 M(i,j) = M(i-1, j-1) = M (i-1 + n * (j-2))

在“线性索引”空间中,这意味着该元素的偏移量是

-n-1

对所有其他位置执行此操作,我们发现

-n-1 | -1 | n-1
-n | x | n => [-n-1, -n, -n+1, -1, +1, +n-1, +n, +n+1]
-n+1 | +1 | n+1

因此,您可以使用上述值创建向量偏移(将 n 替换为第一个维度)。例如,如果 M 为 (5x4),则

offset = [-6 -5 -4 -1 1 4 5 6];

然后您创建所有索引:

indices = bsxfun(@plus, (1:m*n), offset(:));

bsxfun 是“在这些元素上执行此功能;其中一个元素具有单一维度而另一个元素没有,相应地扩展”的一种很酷的简写。您可以对repmat执行相同的操作,但这会创建不必要的中间矩阵(有时可能非常大)。

该命令将创建一个 (8 x m*n) 矩阵,其中包含所有 8 个邻居的索引,包括那些可能不是真正邻居的矩阵...您需要修复的问题。

几种可能的方法:

  • 开始之前填充矩阵
  • 不关心包装,只需去掉边缘掉落的元素即可
  • 为所有“超出边缘”的部分创建一个 mask 。

我更喜欢后者。 “超出边缘”意味着:

  • 上升到顶行
  • 在左栏中向左移动
  • 从底行往下走
  • 在右列中向右移动

在这四种情况中,每一种都有 3 个“无效”索引。它们在上述矩阵中的位置可以确定如下:

mask = zeros(size(M));
mask(:,1) = 1;
left = find(mask == 1);
mask(:,end) = 2;
right = find(mask == 2);
mask(1,:) = 3;
top = find(mask == 3);
mask(end,:) = 4;
bottom = find(mask == 4);

edgeMask = ones(8,m*n);
edgeMask(1:3, top) = 0;
edgeMask([1 4 6], left) = 0;
edgeMask([3 5 8], right) = 0;
edgeMask(6:8, bottom) = 0;

现在您已拥有所需的一切 - 所有索引以及“无效”索引。没有循环。

如果您雄心勃勃,您可以将其转换为元胞数组,但它会比使用完整数组+掩码慢。例如,如果你想找到一个值的所有邻居的平均值,你可以这样做

meanNeighbor = reshape(sum(M(indices).*edgeMask, 1)./sum(edgeMask, 1), size(M));

编辑重新阅读您的问题,我发现您想要一个 M*N,8 维。我的代码已转置。我相信你能弄清楚如何适应它......

归因@Tin 对上述帖子提出了许多很好的修改建议,但在审核过程中被拒绝。我无法完全消除这种不公正 - 但想在此表达我的谢意。

扩展到不同区域和多个维度

如果你有一个 N 维图像矩阵 M,你可以按如下方式找到邻居:

temp = zeros(size(M));
temp(1:3,1:3,1:3) = 1;
temp(2,2,2) = 2;
offsets = find(temp==1) - find(temp==2);

如果你想要一个大小为一定半径的区域,你可以这样做

sz = size(M);
[xx yy zz] = meshgrid(1:sz(1), 1:sz(2), 1:sz(3));
center = round(sz/2);
rr = sqrt((xx - center(1)).^2 + (yy - center(2)).^2 + (zz - center(3)).^2);
offsets = find(rr < radius) - find(rr < 0.001);

您可能可以按照前面所示的 2D 情况找出如何处理边缘问题。

未经测试 - 请查看您是否发现上述问题。

关于matlab - 获取矩阵元素的邻居,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21462711/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com