remove negative cells in a matrix by averaging

3 views (last 30 days)
Hello,
I have a matrix 700*700*1 in which there are some negative numbers. these negative numbers have no physical interpretation for my work and are caused by an error that has to be fixed. I need to convert these negative numbers into positive ones by putting them equal to the average of their adjacent cells (8 adjacent cells). I will really appreciate it if someone can help me in this regard.
Best regards
  3 Comments
Ali Faridkhou
Ali Faridkhou on 8 Apr 2013
Dear Azzi those would be like this
A(9,19) A(9,20) A(9,21) A(10,19) A(10,21) A(11,19) A(11,20) A(11,21)
Thank you
Cedric
Cedric on 8 Apr 2013
Edited: Cedric on 8 Apr 2013
Is it possible that the average over neighbors is negative due to some clustering of negative values? What is the density of negative values, or roughly how many negative values do you have in this array?
If your matrix is A, you can visualize negative values by evaluating
spy(A < 0)
which also indicates the number of non-zero elements, or you can count them with
sum(A(:) < 0)

Sign in to comment.

Answers (2)

Youssef  Khmou
Youssef Khmou on 8 Apr 2013
Edited: Youssef Khmou on 8 Apr 2013
hi, you can try :
% Given your matrix A :
1)
A=randn(10);
A(A<0)=A(A<0)*-1
2) Or use your idea :
for x=2:size(A,1)-1
for y=2:size(A,2)-1
if A(x,y)<0
A(x,y)=A(x-1,y-1)+A(x-1,y)+A(x-1,y+1)+A(x,y-1)+A(x,y+1)+...
A(x+1,y-1)+A(x+1,y)+A(x+1,y+1);
A(x,y)=A(x,y)/8;
end
end
end
But the first solution is Very efficient, because this second one does not treat the boundaries

Cedric
Cedric on 8 Apr 2013
Edited: Cedric on 8 Apr 2013
See my comment below your question and note that none of the solutions below solves the problem of managing cases where the average over neighbors is negative.
1. If you have a large amount of negative values:
..you can build a global array of averages over neighbors using CONV2, and use its value to replace negative values in A:
k = [1, 1, 1; 1, 0, 1; 1, 1, 1] ;
M = conv2(A, k, 'same') ./ conv2(ones(size(A)), k, 'same') ;
A(A < 0) = M(A < 0) ;
2. If you have only a few negative values:
.. you can loop over them and compute the average "manually":
[r,c] = find(A < 0) ;
for k = 1 : numel(r)
rId = r(k) + [1, 1, 1, 0, 0, -1, -1, -1] ;
cId = c(k) + [1, 0, -1, 1, -1, 1, 0, -1] ;
isOk = rId > 0 & rId <= size(A,1) & cId > 0 & cId <= size(A,2) ;
ind = sub2ind(size(A), rId(isOk), cId(isOk)) ;
A(r(k),c(k)) = mean(A(ind)) ;
end
Note 1: you could partially solve the issue of negative means by setting all remaining negative elements of A to 0 after executing either solution above.
A(A<0) = 0 ;
PS: I've not fully tested these solutions, so there a still a bit of work on your side.

Categories

Find more on Mathematics in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!