【问题标题】:3x3 Average filter in matlabmatlab中的3x3平均滤波器
【发布时间】:2017-05-11 23:18:38
【问题描述】:

我编写了代码来使用 3x3 平均滤波器来平滑图像,但是输出很奇怪,几乎全是黑色的。这是我的代码。

function [filtered_img] = average_filter(noisy_img)
    [m,n] = size(noisy_img);
    filtered_img = zeros(m,n);
    for i = 1:m-2
        for j = 1:n-2
            sum = 0;
            for k = i:i+2
                for l = j:j+2
                    sum = sum+noisy_img(k,l);
                end
            end
            filtered_img(i+1,j+1) = sum/9.0;
        end
    end
end

我调用函数如下:

img=imread('img.bmp');
filtered = average_filter(img);
imshow(uint8(filtered));

到目前为止,我在代码逻辑中看不到任何错误,如果有人能发现问题,我将不胜感激。

【问题讨论】:

    标签: matlab image-processing


    【解决方案1】:

    假设您使用的是灰度图像,您应该将内部的两个 for 循环替换为:

    filtered_img(i+1,j+1) = mean2(noisy_img(i:i+2,j:j+2));
    

    有什么改变吗?

    编辑:不要忘记将其重新转换为 uint8!

    filtered_img = uint8(filtered_img);
    

    编辑 2:它在您的代码中不起作用的原因是因为 sum 在 255 处饱和,即 uint8 的上限。 mean 似乎阻止了这种情况的发生

    【讨论】:

    • 它确实有效,但我不明白为什么。我的代码出了什么问题?
    • sum的上限是255,所以需要事先设置成double
    • 我的错,您需要将噪声值加倍。 uint8 似乎覆盖了 doule
    • @turingcomplete 很棒,但知道 Matlab 用户应该尽可能避免使用for loops,因为它往往效率较低。
    • 您也可以使用 mean2() 代替 mean(mean())。如您所知,std2 也存在并且工作方式类似。
    【解决方案2】:

    另一种选择:

     f = @(x) mean(x(:));
     filtered_img = nlfilter(noisy_img,[3 3],f);
    

    【讨论】:

      【解决方案3】:
      img = imread('img.bmp');
      filtered = imfilter(double(img), ones(3) / 9, 'replicate');
      imshow(uint8(filtered));
      

      【讨论】:

        【解决方案4】:

        在图像和大小为 3x3 的滤波器之间实现乘积运算之和的邻域运算,该滤波器应该是平均滤波器。 然后使用相同的函数/代码来计算拉普拉斯算子(二阶导数,prewitt 和 sobel 运算(一阶导数)。 使用一个简单的 10*10 矩阵来执行这些操作 需要matlab代码

        【讨论】:

          【解决方案5】:

          切题:

          特别是对于 5x5 或更大的窗口,您可以考虑先在一个方向上平均,然后在另一个方向上平均,这样可以节省一些操作。因此,点 3 将是 (P1+P2+P3+P4+P5)。点 4 将是 (P2+P3+P4+P5+P6)。最后除以5。因此,点 4 可以计算为 P3new + P6 - P2。等等第5点等等。在其他方向重复相同的过程。 确保先除,再求和。

          我需要为此计时,但我相信它对于较大的窗口可能会运行得更快一些。每行是连续的,这可能看起来不是最好的,但是你有很多行可以并行工作,所以这应该不是问题。

          如果你有整数,这个第一个除法,然后求和也可以防止饱和,所以即使在 3x3 的情况下你也可以使用这种方法,因为用 3 除以 2 比除以 9 的错误更少(虽然更慢)。但请注意你总是会低估最终的价值,所以你不妨添加一些偏差(比如步骤之间的所有值+1)。

          【讨论】:

            【解决方案6】:
            img=imread('camraman.tif');
            nsy-img=imnoise(img,'salt&pepper',0.2);
            imshow('nsy-img');
            h=ones(3,3)/9;
            avg=conv2(img,h,'same');
            imshow(Unit8(avg));
            

            【讨论】:

            • 欢迎来到 Stack Overflow!虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-11-03
            • 1970-01-01
            • 2023-03-24
            • 2015-07-30
            • 1970-01-01
            • 2015-07-12
            相关资源
            最近更新 更多