Alex
Alex

Reputation: 43

Replace surrounding elements

In a matrix such as below

mapArray = [9,   8,   7,   800  
            8,   7,   6,   800
            21,  1,   3,   800
            800, 800, 800, 800];

Is it possible to alter the elements 'touching' values of 800 to a value (e.g. 700..)? This would leave it looking like this:

mapArray = [9,   8,   800,   800  
            8,   7,   800,   800
            800, 800, 800,   800
            800, 800, 800,   800];

Many thanks Alex

Upvotes: 4

Views: 70

Answers (4)

Rash
Rash

Reputation: 4336

mapArray = randi([795 805],[10 10]);
search_val = 800;
replace_val = 7;
a = padarray(mapArray==search_val,[1 1]);
b = logical(circshift(a,[0 -1])+circshift(a,[0 1])+...
    circshift(a,[1 0])+circshift(a,[-1 0]));
b(:,end)=[];b(:,1)=[];b(end,:)=[];b(1,:)=[];
newArray = mapArray;
newArray(b) = replace_val;

example,

mapArray =

799   803   797   801   805   802   797   798   801   795
795   799   798   798   803   799   798   805   797   797
804   797   804   803   800   803   800   799   801   803
805   799   795   797   799   800   797   797   802   795
800   796   795   802   799   798   804   804   797   805
800   796   796   797   798   805   797   805   796   803
798   805   802   799   800   804   797   799   798   800
804   805   803   801   800   801   796   796   798   801
799   801   802   803   803   801   797   797   799   797
796   795   799   795   803   801   799   799   800   800

newArray =

799   803   797   801   805   802   797   798   801   795
795   799   798   798     7   799     7   805   797   797
804   797   804     7   800     7   800     7   801   803
  7   799   795   797     7   800     7   797   802   795
  7     7   795   802   799     7   804   804   797   805
  7     7   796   797     7   805   797   805   796     7
  7   805   802     7     7     7   797   799     7   800
804   805   803     7     7     7   796   796   798     7
799   801   802   803     7   801   797   797     7     7
796   795   799   795   803   801   799     7     7     7

Upvotes: 0

Divakar
Divakar

Reputation: 221504

Performance oriented vectorized solution based on bsxfun -

search_val = 800;
replace_val = 700;

mapArray_ext = zeros(size(mapArray)+2);
mapArray_ext(2:end-1,2:end-1) = mapArray;

idx = find(mapArray_ext==search_val);
offset_idx = bsxfun(@plus,[-1:1]',[-1:1]*size(mapArray_ext,1)); %//'
mapArray_ext(bsxfun(@plus,idx,offset_idx(:)')) = replace_val; %//'
mapArray_ext(idx) = search_val;
mapArray = mapArray_ext(2:end-1,2:end-1);

Upvotes: 0

siliconwafer
siliconwafer

Reputation: 732

there's probably a better way, but this seems to work with your example.

mapArray = [9,   8,   7,   800
8,   7,   6,   800
21,  1,   3,   800
800, 800, 800, 800];

% find row, col indices of the search value
[r,c]=find(mapArray==800)

% compute indexes, plus and minus one
r2=[r-1;r+1;r+1;r-1;r-1 ; r+1 ; r;   r];
c2=[c+1;c-1;c+1;c-1; c  ;  c  ; c+1 ;c-1];

% new variable
mapArrayNew = mapArray;

% only use valid indices.
ixKeep = r2<=size(mapArray,1) & c2<=size(mapArray,2) & r2>0 & c2>0;

% replace
mapArrayNew(sub2ind(size(mapArray),r2(ixKeep),c2(ixKeep))) = 700;

Upvotes: 0

Jonas
Jonas

Reputation: 74930

With the image processing toolbox, this is quite straightforward (if you don't have the image processing toolbox, you can use conv2 instead of imdilate).

targetValue = 800;
targetDistribution = mapArray == targetValue;

valuesToReplaceLocation = imdilate(targetDistribution, [0 1 0;1 1 1;0 1 0]) & ~targetDistribution;

mapArray(valuesToReplaceLocation) = 700;

edit To pad the array, you can use the PADARRAY function from the image processing toolbox.

Upvotes: 3

Related Questions