我有一个矩阵,其中值-1是随机分布的(参见图像中的黄色单元格)。矩阵的其余部分填充0(蓝色单元格)。
我现在需要从左侧,右侧,顶部或底部填充与-1相邻的单元格1.如果几个单元格的-1彼此相邻,则不应覆盖这些-1。
我尝试过两个嵌套的for循环,但它对索引非常棘手。我将不胜感激任何帮助。
答案 0 :(得分:4)
我正在借用Vahe Tshitoyan's answer中的示例矩阵生成:
A = zeros(10,10);
A(randi(100,1,20))=-1;
colormap(parula(3)); % set colormap: blue, yellow, bluish green
image(-A*2+1); % -A*2+1 is just a trick to get the desired colors
axis square
你可以
conv2
)将1
写入围绕等于-1
的单元格的单元格中。-1
覆盖到原始单元格中。即,
mask = [0 1 0; 1 0 1; 0 1 0]; % define neighbouthood mask
B = double(conv2(-A, mask, 'same') > 0); % step 1
B(A==-1) = -1; % step 2
figure
colormap(parula(3));
image(-B*2+1+3*(B==1)); % similar trick to that used before
axis square
示例原始矩阵(A
)和结果矩阵(B
):
答案 1 :(得分:3)
您可以使用circshift
功能。
% generating the matrix
A = zeros(10,10);
A(randi(100,1,20))=-1;
figure(1);imagesc(A, [-1 1]);
% neighbours + no circular boundary condition
downshifted = circshift(A, 1, 1);downshifted(1,:)=0;
upshifted = circshift(A, -1, 1);upshifted(end,:)=0;
leftshifted = circshift(A, -1, 2);leftshifted(:,end)=0;
rightshifted = circshift(A, 1, 2);rightshifted(:,1)=0;
% combining neighbours and removing where A~=0
neighbours = (downshifted|upshifted|leftshifted|rightshifted)&~A;
% final matrix
B = A+neighbours;
figure(2);imagesc(B, [-1 1]);
要注意的一点是circshift
的圆形边界条件。这就是我手动设置downshifted(1,:)=0;
等的原因。当然,除非你真的想要圆形边界条件。这就是我得到的
在我看来,还有更有效的方法。
对于每个给定像素,四个最近邻居的线性指数由
的偏移给出offsets = [-n, -1, +1, +n];
其中n
是行数。因此,您可以使用
minusOneInd = find(A==-1); % the linear indices of -1s
indices = unique(bsxfun(@plus, minusOneInd, offsets)); % all neighbours
然而,由于边缘和索引耗尽,这会导致一些麻烦。解决此问题的一种方法是用0填充初始矩阵,然后在操作完成后删除填充。如果A
是您的初始矩阵,则可以按如下方式编写满足您所需要的完整代码。
Ap = padarray(A,[1 1]); % to get rid of the edge effects
n = size(Ap, 1);
offsets = [-n, +1, -1, +n]; % index offsets of four neighbours
minusOneInd = find(Ap==-1); % finding the indices of -1s
indices = unique(bsxfun(@plus, minusOneInd, offsets)); % neighbours
% now, remove out of range indices and indices where A is -1
indices(indices<1|indices>numel(Ap)|ismember(indices, minusOneInd))=[];
Ap(ind2sub(size(Ap),indices)) = 1; % assigning the ones
B = Ap(2:end-1,2:end-1); % this is what we want
答案 2 :(得分:0)
@Vahe Tshitoyan使用 circshift 的答案似乎很好,而我使用进行循环:
M = zeros(10);
M(randi(100, [1,20])) = -1;
siz = size(M);
[I, J] = ind2sub(siz, find(M == -1)); % row, column indice of those -1
for i = 1:numel(I)
if I(i)>1 && M(I(i)-1, J(i))~=-1, M(I(i)-1, J(i)) = 1; end % above
if I(i)<siz(1) && M(I(i)+1, J(i))~=-1, M(I(i)+1, J(i)) = 1; end % below
if J(i)>1 && M(I(i), J(i)-1)~=-1, M(I(i), J(i)-1) = 1; end % left
if J(i)<siz(2) && M(I(i), J(i)+1)~=-1, M(I(i), J(i)+1) = 1; end % right
end