remove negative cells in a matrix by averaging
Mostrar comentarios más antiguos
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 comentarios
Azzi Abdelmalek
el 8 de Abr. de 2013
For example the cell A(10,20): What is its adjacent cells?
Ali Faridkhou
el 8 de Abr. de 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)
Respuestas (2)
Youssef Khmou
el 8 de Abr. de 2013
Editada: Youssef Khmou
el 8 de Abr. de 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.
Categorías
Más información sobre Mathematics en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!