Replacing indices with an unwanted value with their the nearest index's value that happens to be positive

一笑奈何 提交于 2020-01-24 09:31:49

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!