在矩阵中查找所有零元素的相邻元素

6

在Matlab中,我有一个由非负数构成的矩阵A,如下所示:

A=[0 2 3 5 4 7 8   1 8 2 7 5 2 9   0 1 2 4 8 0 5   2 4 8 6 0 5 8   1 1 2 5 8 3 6];

我想找到除零元素外的所有零元素的邻居。这意味着我想在向量v中存储A(1, 1)、A(2, 5)、A(3, 1)、A(3, 6)、A(4, 5)和A(5, 1)的邻居,如果其中一个邻居为零,则不存储它。

通过元素(i, j)的邻居,我指的是距离(i, j)一个元素远的元素,即A(i, j+1)、A(i, j-1)、A(i-1, j)、A(i-1, j-1)、A(i-1, j+1)、A(i+1, j)、A(i+1, j-1)和A(i+1, j+1)。每个元素(i, j)都有7个邻居。

我不存储重复的元素。这意味着,如果例如A(1, 1)=0并且A(1,3)=0并且A(1,2)=1,那么我只会存储A(1, 2)一次。

在我的先前的示例中,向量v将是以下内容:

v=[2 1 8 1 2 4 5 2 9 8 5 5 8 4 6 5 8 3];

如何在Matlab中不使用循环来完成这个操作?

这是我用于正方形矩阵的代码: cl_ 是矩阵中零元素的数量。ix_ 是零元素的行索引,iy_ 是零元素的列索引。

for i_=1:length(cl_)
    ixn1_(1:2)=ix_(i_);
    ixn2_(1:3)=ix_(i_)-1;
    ixn3_(1:3)=ix_(i_)+1;
    iyn1_=iy_(i_)-1;
    iyn2_=iy_(i_)+1;
    iyn3_(1:3)=[iy_(i_)-1, iy_(i_), iy_(i_)+1];
    ixn_{i_}=[ixn1_, ixn2_, ixn3_];
    iyn_{i_}=[iyn1_, iyn2_, repmat(iyn3_, 1, 2)];
end
% find the neighbors

@LuisMendo 我已经更新了我的问题。 - npisinp
3个回答

5
如果您不关心值的顺序:
mask = A==0;
neighborMask = xor(conv2(double(mask),ones(3),'same')>0,mask);
v = A(neighborMask)

3
如果您想保持您在问题中所述的顺序,可能是这样的 - 代码
%%// Given data
A=[0 2 3 5 4 7 8
   1 8 2 7 5 2 9
   0 1 2 4 8 0 5
   2 4 8 6 0 5 8
   1 1 2 5 8 3 6];

%%// Find indices that have value zero
[indx,indy] = find(A==0);

%%// OP seems to be travelling row-wise, so sort the indices column-wise
[indx,y1] = sort(indx);
indy = indy(y1);

%%// Get the 8 neighboring row and column offsets  
row1 = bsxfun(@plus,indx,[-1 -1 -1 0 0 1 1 1]);
col1 = bsxfun(@plus,indy,[-1 0 1 -1 1 -1 0 1]);

%%// Get the valid positions
valid_pos = row1>0 & row1<=size(A,1) & col1>0 & col1<=size(A,2);

%%// Get valid row and column numbers and then valid indices
ind1 = (valid_pos.*col1-1).*size(A,1) + valid_pos.*row1;

%%// Get valid linear indices
ind1 = reshape(ind1',1,numel(ind1)); %%//'
ind1 = ind1(ind1>0);

%%// Find the unique indices without sorting
[~, idxs, ~] = unique(ind1, 'first');
ind1 = ind1(sort(idxs));

%%// Get matrix values from indices and remove the zeros themselves
OUT = A(ind1);
OUT(OUT==0) = [];

输出

OUT =

     2     1     8     1     2     4     5     2     9     8     5     5     8     4     6     5     8     3

2
首先,我假设你已经知道“查找”命令:例如 topbot=find(abs(zz)==H); 查找 zz 中等于 H 的所有元素,并将它们存储在一个名为 "topbot" 的长向量中。
唯一不幸的是,它将矩阵位置存储为单个数字,因此 (3,1) 存储为 3,等等。因此,如果您想要行和列,公式是 column = ceiling((number-1)/numrows)row = number mod numrows(不,语法不正确,但您可以理解)。 (编辑:哎呀,数学太难了,错误无处不在)
之后,应该只需删除重复项并确保不获取负行或列。
最后,矩阵值可以通过单个索引调用,因此如果 A 是一个 8x8 的矩阵,A(15) 与调用 A(7,2) 相同。

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