获取矩阵元素的邻居 [英] Get the neighbors of a matrix element

查看:165
本文介绍了获取矩阵元素的邻居的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a matrix and for each element I want to get the index of its surrounding elements. All these results have to be stored into a matrix in the following way. Each row of the matrix corresponds to a matrix element and each of the columns of this matrix contain s the neighbor indexes. For example, for a 4x4 matrix we will get a 16x8 result array. Some of the matrix elements do not have 8 neighbors.

有一个例子,我认为它正在工作,我有什么办法可以避免for循环?:

There is an example, I think it is working, I there any way to avoid for loop?:

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))的左上邻居

Given the linear indices of a matrix M(n,m), you can convince yourself that the top left neighbor of element M(i,j) = M(i-1, j-1) = M(i-1 + n * (j-2))

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

In "linear index" space that means the offset of this element is

-n-1

我们在其他所有地方都这样做

Doing this for all other locations, we find

-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),则

Thus you can create a vector offset with the above values (replacing n with the first dimension). For example, if M is (5x4), then

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

然后创建所有索引:

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

bsxfun是在这些元素上执行此功能;一个元素具有单例尺寸,而另一个元素则没有,请相应地扩展"的简写形式.您可以对repmat进行相同的操作,但是会创建不必要的中间矩阵(有时可能非常大).

bsxfun is a cool shorthand for "do this function on these elements; where one element has a singleton dimension and the other doesn't, expand accordingly". You could do the same with repmat, but that creates unnecessary intermediate matrices (which can sometimes be very large).

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

That command will create a (8 x m*n) matrix of indices of all 8 neighbors, including ones that may not really be the neighbors... something you need to fix.

几种可能的方法:

  • 在开始之前填充矩阵
  • 不在乎包装,只去除掉边缘掉的元素
  • 为所有边缘"对象创建一个遮罩.

我更喜欢后者. 边缘"表示:

I prefer the latter. "Off the edge" means:

  • 上排
  • 在左列中左移
  • 下一行
  • 在右列中右移

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

In each of these four cases there are 3 indices that are 'invalid'. Their position in the above matrix can be determined as follows:

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;

现在,您拥有了所需的一切-所有索引和无效"索引.没有循环.

Now you have everything you need - all the indices, and the "invalid" ones. Without loops.

如果您有雄心壮志,可以将其变成单元格阵列,但是比使用完整的阵列+面罩要慢.例如,如果要查找某个值的所有邻居的平均值,则可以

If you were feeling ambitious you could turn this into a cell array but it will be slower than using the full array + mask. For example if you want to find the average of all the neighbors of a value, you can do

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

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

EDIT re-reading your question I see you wanted a M*N, 8 dimension. My code is transposed. I'm sure you can figure out how to adapt it...

属性 @Tin有益地建议对上述帖子进行许多出色的修改,但在审核过程中被拒绝.我不能完全消除这种不公正-但想在这里表示我的感谢.

ATTRIBUTION @Tin helpfully suggested many great edits to the above post, but they were rejected in the review process. I cannot totally undo that injustice - but would like to record my thanks here.

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

如果您有一个N维图像矩阵M,则可以找到邻居,如下所示:

If you have an N-dimensional image matrix M, you could find the neighbors as follows:

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

如果您想要一个半径一定的区域,可以这样做

If you want a region that is a certain radius in size, you could do

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情况下沿前面显示的线的边缘问题.

You can probably figure out how to deal with the problem of edges along the lines shown earlier for the 2D case.

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

Untested - please see if you notice any problems with the above.

这篇关于获取矩阵元素的邻居的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆