问题
This question is different from the previous question (How to find indices with a negative value and replace the value with the nearest index's value that happens to be positive?). The previous question was to replace an index's unwanted value with its nearest positive index's value on the same row.
This question is to replace the unwanted value with its nearest positive index's value throughout the entire matrix (not only limited to the same row).
If there is more than one index that is the nearest to the observed index in the entire matrix, take the value randomly (it doesn't really matter tbh).
I am dealing with a 1003x1170 single matrix. So it would be best if the solution doesn't come with so much overhead. (optional)
For example, if the negative values are unwanted,
[-255 4 6;
-5 -4 5;
-400 3 6;
-6 -7 -8;
3 -5 4]
becomes
[4 4 6;
4 5 5;
3 3 6;
3 3 6;
3 4 4]
(The answer doesn't necessarily have to be like this since it takes the nearest value randomly (right/left/up/down whatever, if it makes things easier by adding some consistency, that is also fine.))
Purpose: I am trying to do this to remove the big size of the noise holes in the observed image matrix without killing the sharpness of the image.
Thank you for your supports!
回答1:
The following code replaces each negative number by the nearest non-negative number. If there are several non-negative numbers at the same minimum distance, the first one in linear order is used.
Without loop
This builds a very large matrix as intermediate result. It may not work for large inputs due to memory limitations.
matrix = [-255 4 6; -5 -4 5; -400 3 16; -6 -7 -8; 13 -5 14];
[r_use, c_use] = find(matrix>=0); % row and column indices of useful values
z_use = r_use+1j*c_use; % same as complex number
[r_neg, c_neg] = find(matrix<0); % row and column indices of negative values
z_neg = r_neg+1j*c_neg; % same as complex number
[~, ind_min] = min(abs(bsxfun(@minus, z_use, z_neg.')), [], 1); % compute distance
% between each useful value and each negative value. For each negative value,
% give index of nearest useful value. This index is referred to r_use, c_use
ind_use = sub2ind(size(matrix), r_use(ind_min), c_use(ind_min)); % linear indices
% of useful values that will replace the negative values
ind_neg = sub2ind(size(matrix), r_neg, c_neg); % linear indices of negative values
matrix(ind_neg) = matrix(ind_use); % replace
Before:
matrix =
-255 4 6
-5 -4 5
-400 3 16
-6 -7 -8
13 -5 14
After:
matrix =
4 4 6
4 4 5
3 3 16
13 3 16
13 13 14
With loop
This reduces memory consumption by working with the negative values one at a time, using a loop.
matrix = [-255 4 6; -5 -4 5; -400 3 16; -6 -7 -8; 13 -5 14];
[r_use, c_use] = find(matrix>=0); % row and column indices of useful values
z_use = r_use+1j*c_use; % same as complex number
[r_neg, c_neg] = find(matrix<0); % row and column indices of negative values
z_neg = r_neg+1j*c_neg; % same as complex number
for k = 1:numel(z_neg) % for each negative value
[~, ind_min_k] = min(abs(z_use-z_neg(k))); % compute distance between
% each useful value and this negative value. Give index of nearest
% useful value. This index is referred to r_use, c_use
ind_use_k = sub2ind(size(matrix), r_use(ind_min_k), c_use(ind_min_k));
% linear index of useful value that will replace this negative value
ind_neg_k = sub2ind(size(matrix), r_neg(k), c_neg(k)); % linear index
% of this negative value
matrix(ind_neg_k) = matrix(ind_use_k); % replace
end
回答2:
If you have the Image Processing Toolbox you can use the second output of bwdist to find the nearest positive index value.
matrix = [-255 4 6;
-5 -4 5;
-400 3 6;
-6 -7 -8;
3 -5 4];
bw = matrix >= 0;
[~, idx] = bwdist(bw);
result = matrix;
result(~bw) = result(idx(~bw));
The result will be:
result =
4 4 6
3 4 5
3 3 6
3 3 6
3 3 4
Here the result is computed based on euclidean distance. You can use bwdist
with other distance metrics to produce different results.
来源:https://stackoverflow.com/questions/59753924/replacing-indices-with-an-unwanted-value-with-their-the-nearest-indexs-value-th