Select n elements in the matrix differently based on a specific value

I have a logical matrix A, and I would like to highlight all the elements to the left of each of my 1s values ​​given by fixed remote. Say my distance is 4, I would like (for example) to replace with a fixed value (saying 2) all 4 cells to the left of every 1 in A.

A= [0 0 0 0 0 1 0
   0 1 0 0 0 0 0
   0 0 0 0 0 0 0
   0 0 0 0 1 0 1]

B= [0 2 2 2 2 1 0
   2 1 0 0 0 0 0
   0 0 0 0 0 0 0
   2 2 2 2 2 2 1]

In B, this is what I would like to have, given also the rewriting (the last line in B) and the cases where to the left of my 1, not 4, there is a fixed search distance (second line).

+4
source share
4 answers

How about this great one-liner?

n = 3;
const = 5;
A = [0 0 0 0 0 1 0;
     0 1 0 0 0 0 0;
     0 0 0 0 0 0 0;
     0 0 0 0 1 0 1]

A(bsxfun(@ne,fliplr(filter(ones(1,1+n),1,fliplr(A),[],2)),A)) = const

leads to:

A =

     0     0     5     5     5     1     0
     5     1     0     0     0     0     0
     0     0     0     0     0     0     0
     0     5     5     5     5     5     1

Here are a few explanations:

Am = fliplr(A);                      %// mirrored input required
Bm = filter(ones(1,1+n),1,Am,[],2);  %// moving average filter for 2nd dimension
B = fliplr(Bm);                      %// back mirrored
mask = bsxfun(@ne,B,A)               %// mask for constants
A(mask) = const
+8
source

, :

w=4;                            % Window size
v=2;                            % Desired value

B = A;
for r=1:size(A,1)               % Go over all rows
  for c=2:size(A,2)             % Go over all columns
    if A(r,c)==1                % If we encounter a 1
       B(r,max(1,c-w):c-1)=v;   % Set the four spots before this point to your value (if possible)
    end
  end
end
+3
d = 4; %// distance
v = 2; %// value

A = fliplr(A).'; %'// flip matrix, and transpose to work along rows.
ind = logical( cumsum(A) ...
    - [ zeros(size(A,1)-d+2,size(A,2)); cumsum(A(1:end-d-1,:)) ] - A );
A(ind) = v;
A = fliplr(A.');

:

A =
     0     2     2     2     2     1     0
     2     1     0     0     0     0     0
     0     0     0     0     0     0     0
     2     2     2     2     2     2     1
+2

# 1 -, imdilate, -

A(imdilate(A,[ones(1,4) zeros(1,4+1)])==1)=2

# 1: , imdilate -

morph_strel = [ones(1,4) zeros(1,4+1)]

, n n , .

# 2: imdilate, A , 1 1 A -

imdilate_result = imdilate(A,morph_strel)

№ 3: 1 A 2 -

A(imdilate_result==1)=2

, : -

A(imdilate(A,[ones(1,window_length) zeros(1,window_length+1)])==1)=new_value

where window_lengthwill be 4, and new_valuewill be 2for the data.


Approach # 2 Use - bsxfun

%// Paramters
window_length = 4;
new_value = 2;

B = A' %//'
[r,c] = find(B)
extents = bsxfun(@plus,r,-window_length:-1)
valid_ind1 = extents>0
jump_factor = (c-1)*size(B,1)
extents_valid = extents.*valid_ind1
B(nonzeros(bsxfun(@plus,extents_valid,jump_factor).*valid_ind1))=new_value
B = B' %// B is the desired output
+2
source

Source: https://habr.com/ru/post/1542022/


All Articles