【问题标题】:How to set matrix element to mean of surrounding elements?如何将矩阵元素设置为周围元素的平均值?
【发布时间】:2026-02-17 13:40:01
【问题描述】:

我有一个矩阵X,它表示受噪声影响的图像。我还有一个布尔矩阵M,它表示哪些像素受噪声影响。我想要做的是将每个“损坏”像素设置为其八个相邻像素的平均值。

保证损坏的像素总是被未损坏的像素包围,并且图像边界上的任何像素都没有损坏。我可以使用什么函数来编写它的矢量化版本?

【问题讨论】:

  • 也许你需要中位数,而不是意思?使用medfilt2
  • 这个问题的答案 -- *.com/questions/1637000/… -- 你会很感兴趣。
  • @Eddy_Em 看起来medfilt2 做了我想做的事,只是我只想对特定像素而不是整个图像执行该操作。
  • 然后简单地为需要的区域制作掩码,然后将掩码乘以矩阵,您将得到第一个矩阵。否定掩码并乘以原始矩阵:您将获得第二个矩阵。将medfilt2 添加到您的第一个矩阵并将结果添加到第二个,您将得到您想要的。

标签: matlab matrix octave


【解决方案1】:

对于您的情况,这应该执行得相当快

fixed = conv2 (image, [1 1 1; 1 0 1; 1 1 1]/8, "same")
# mask is a logical matrix for the corrupted pixels
image(mask) = fixed(mask)

说明:均值滤波是用conv2 函数完成的。为了计算一个像素及其邻居的平均值,使用的内核是ones (3) / 9,这意味着每个像素值的 1/9 用于计算新值。由于您不想计算中心像素的平均值,因此将其值设为 0(在内核中),将其他值设为 1/8。

【讨论】:

  • @PaulManta 因为您似乎正在处理 RGB 图像,您可以使用 convn 而不是 conv2。你必须调整内核,但原理是一样的。 kernel = zeros(3,3,3); kernel(:,:,2) = 1/8; kernel(2,2,2) = 0
  • 只是一个小类型:'same' 而不是“same” :D 只是说,因为可能有人不明白 :)
  • @tim 这不是错字。这些问题也用 Octave 标记,双引号字符串是有效的语法。
  • 快速提问,如果我想让一个相邻元素的影响力是其他元素的两倍,比如 fixed = conv2(image,[1 2 1, 1 0 1, 1 1 1]/9),结果似乎不是邻居值的平均值。我在做什么/解释错了?也许我想要的可以简单地完成:A(:).*B(:)./sum(sum(B))?
【解决方案2】:

这可能不是最有效的解决方案,但应该可以。

N = size(M, 1);
target_ind = find(M);
offset = [-N-1, -N, -N+1, -1, 0, 1, N-1, N, N+1];

area_ind = bsxfun(@plus, offset, target_ind);
X(target_ind) = median(X(area_ind), 2);

由于保证所有损坏的像素都被像素包围,我们可以很容易地计算每个损坏像素的邻居的线性索引。这里我假设X 是灰度图像。

如果I 有多个通道,那么我们可以遍历每个通道并添加一个偏移量 target_indarea_ind 每次:

for i = 1:size(X, 3)
    chan_offset = (i - 1)*size(X, 1)*size(X, 2) % Add the number of elements in previous channels to get indices in the current channel
    X(target_ind + chan_offset) = median(X(area_ind + chan_offset), 2);
end

【讨论】:

  • 我了解它是如何工作的,但我在将其调整为 RGB 图像时遇到了一个小问题。显然我需要应用这个过程三次,每个通道一次。我尝试做X(:, :, 1)(target_ind) = ...,但这给了我一个错误:() must be followed by . or close the index chain。我该如何解决这个问题?
  • @PaulManta 我已经编辑了我的答案以添加一种方法来处理具有多个通道的图像。