用最近的正数索引值替换不需要的值的索引

3
这个问题与之前的问题(如何查找具有负值的索引并用最近的正值替换该值?)不同。之前的问题是将一个索引的不需要的值替换为同一行上最近的正索引的值。

这个问题是在整个矩阵中,将不需要的值替换为最近的正索引的值(不仅仅限于同一行)。

  • 如果在整个矩阵中有多个距离被观察索引最近的索引,则随机选择一个值(实际上并不重要)。

  • 我处理的是一个1003x1170的单矩阵。因此,最好的解决方案不会带来太多开销。(可选)

例如,如果需要去除负值:

[-255  4  6;
   -5 -4  5;
 -400  3  6;
   -6 -7 -8;
    3 -5  4]

变成

[4 4 6; 4 5 5; 3 3 6; 3 3 6; 3 4 4]

(答案不一定要像这样,因为它随机地取最近的值(向右/向左/向上/向下等,如果通过增加一些一致性使事情变得更容易,那也没问题。))

目的:我正在尝试做到这一点,以消除观察图像矩阵中噪声孔的大尺寸,而不会破坏图像的清晰度。

感谢您的支持!


考虑一个33的卷积核(就像图像滤波时一样),对于每个负像素,在33邻域中搜索并选择第一个正值。如果没有找到正值,则为该特殊像素考虑5*5邻域,以此类推尝试更大的卷积核,直到找到正值为止。这可能不是最快的算法! - MeiH
2个回答

4
以下代码将每个负数替换为最近的非负数。如果有几个非负数距离相同,那么使用线性顺序中的第一个

无循环

这将构建一个非常大的矩阵作为中间结果。由于内存限制,它可能无法处理大型输入。
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

之前:

matrix =
  -255     4     6
    -5    -4     5
  -400     3    16
    -6    -7    -8
    13    -5    14

之后:

matrix =
     4     4     6
     4     4     5
     3     3    16
    13     3    16
    13    13    14

使用循环

这种方法通过使用循环逐一处理负值,从而减少内存消耗。

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

1
是的,我没有考虑到那个。那么你需要一个循环。你可以循环遍历每个负值,并对它们执行我的代码所做的操作(现在不需要使用bsxfun)。如果需要帮助,请告诉我,我会编辑我的答案。 - Luis Mendo
是的,我需要更大矩阵的代码的编辑版本! - mrki102
我尝试了使用循环的那个,已经超过3分钟了,但输出还没有出来。我有一种感觉,可能是陷入了无限循环中。 - mrki102
你的矩阵很大,而循环通常比向量化代码慢(有时慢得多)。你可以在 for 行后面添加类似于 disp(round(k/numel(z_neg)*100)) 的内容,以查看百分比进度。 - Luis Mendo
1
我会尝试的。谢谢你的帮助:^) - mrki102
显示剩余2条评论

3

如果您拥有图像处理工具箱,可以使用bwdist的第二个输出来查找最近的正整数索引值。

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));

结果将是:
result =
   4   4   6
   3   4   5
   3   3   6
   3   3   6
   3   3   4

这里的结果是基于欧几里得距离计算的。你可以使用bwdist结合其他距离度量来产生不同的结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接