我编写了使用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));
到目前为止,我在代码逻辑中看不到任何错误,如果有人能发现问题,我会很感激。
答案 0 :(得分:9)
假设你正在使用灰度图像,你应该用以下内容替换内部的两个for循环:
filtered_img(i+1,j+1) = mean2(noisy_img(i:i+2,j:j+2));
它会改变什么吗?
编辑:别忘了将它重新转换为uint8 !!
filtered_img = uint8(filtered_img);
编辑2:它在代码中不起作用的原因是因为sum
在55处饱和,这是uint8的上限。 mean
似乎阻止了这种情况的发生
答案 1 :(得分:2)
另一种选择:
f = @(x) mean(x(:));
filtered_img = nlfilter(noisy_img,[3 3],f);
答案 2 :(得分:2)
img = imread('img.bmp');
filtered = imfilter(double(img), ones(3) / 9, 'replicate');
imshow(uint8(filtered));
答案 3 :(得分:0)
切向问题:
特别是对于5x5或更大的窗口,您可以考虑先在一个方向上进行平均,然后在另一个方向进行平均,然后保存一些操作。因此,3点将是(P1 + P2 + P3 + P4 + P5)。 4点的点是(P2 + P3 + P4 + P5 + P6)。最后除以5。因此,4点可以计算为P3new + P6-P2。对于第5点等等。在其他方向重复相同的步骤。 确保先划分,然后求和。
我需要时间,但我相信它对于更大的窗口可以更快一点。它是每行顺序,可能看起来不是最好的,但你有很多行可以并行工作,所以它应该不是问题。
这个第一个除法,然后总和也可以防止饱和,如果你有整数,所以你甚至可以在3x3的情况下使用这种方法,因为它比错误(虽然更慢)两次除以3而不是一次除以9。但请注意你总是会低估最终价值,所以你不妨添加一些偏见(比如说步骤之间的所有值+1)。