3

我编写了代码来使用 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));

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

4

6 回答 6

10

假设您正在使用灰度图像,您应该将内部两个 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似乎可以防止这种情况发生

于 2012-11-18T22:43:47.957 回答
2

另外一个选项:

 f = @(x) mean(x(:));
 filtered_img = nlfilter(noisy_img,[3 3],f);
于 2012-11-18T22:56:31.370 回答
2
img = imread('img.bmp');
filtered = imfilter(double(img), ones(3) / 9, 'replicate');
imshow(uint8(filtered));
于 2012-11-19T00:09:48.163 回答
0

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

于 2017-05-11T14:29:18.650 回答
0

与问题相切:

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

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

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

于 2017-05-11T15:18:38.687 回答
-1
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));
于 2015-09-14T05:22:25.223 回答