Reputation: 43
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
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
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
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
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