remove negative cells in a matrix by averaging
Ältere Kommentare anzeigen
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 Kommentare
Azzi Abdelmalek
am 8 Apr. 2013
For example the cell A(10,20): What is its adjacent cells?
Ali Faridkhou
am 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)
Antworten (2)
Youssef Khmou
am 8 Apr. 2013
Bearbeitet: Youssef Khmou
am 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
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.
Kategorien
Mehr zu Creating and Concatenating Matrices finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!