2012-11-18 105 views
3

我已經使用3x3平均濾波器編寫了平滑圖像的代碼,但輸出很奇怪,幾乎全是黑色。這是我的代碼。3x3在matlab中的平均值過濾器

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

我看不到代碼邏輯什麼錯,到目前爲止,我會很感激,如果有人能發現問題。

回答

9

假設你有grayscal圖像時,應更換內部的兩個與循環:

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似乎防止這種情況發生

+0

事實確實如此,但我不明白爲什麼。我的代碼出了什麼問題? – turingcomplete

+0

我還記得之前我想在圖像上總結一些值,並且它在使用嵌套循環時不能像嵌套一樣工作,但是當我使用預定義函數時它工作得很好。有什麼理由呢? – turingcomplete

+1

總和的上限是255,所以你需要事先將它設置爲雙倍 – Rasman

2

另一種選擇:

f = @(x) mean(x(:)); 
filtered_img = nlfilter(noisy_img,[3 3],f); 
1
img = imread('img.bmp'); 
filtered = imfilter(double(img), ones(3)/9, 'replicate'); 
imshow(uint8(filtered)); 
-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)); 
+2

歡迎來到Stack Overflow!儘管這段代碼可以解決這個問題,但[包括解釋](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)確實有助於提高帖子的質量。請記住,您將來會爲讀者回答問題,而這些人可能不知道您的代碼建議的原因。 –

0

實現圖像和尺寸3×3的過濾器產品之間的操作和居委會工作時,過濾器應平均過濾。 然後使用相同的函數/代碼來計算拉普拉斯(第二階導數,Prewitt算子和索貝爾操作(一階導數)。 使用簡單的10×10矩陣來執行這些操作 需要matlab代碼

0

切圓的問題:

特別是對於5x5或更大的窗口,您可以考慮首先在一個方向上取平均值,然後在另一個方向上取平均值,然後保存一些操作,因此,指向3將是(P1 + P2 + P3 + P4 + P5)。在4處將是(P2 + P3 + P4 + P5 + P6),最後除以5,因此,點4可以計算爲P3new + P6 - P2等等,對於點5等等,重複相同的程序在其他方向。 請務必先分開總和。

我需要這個時間,但我相信它可以工作更快的大窗口。每行的順序可能看起來並不是最好的,但是你有許多行可以並行工作,所以它不應該是一個問題。

如果你有整數,第一次除法和總和也可以防止飽和,所以即使在3x3的情況下也可以使用這種方法,因爲兩次除以3減去錯誤(雖然較慢)你總是會低估最終價值,所以你可能會加上一些偏見(比如在步驟之間的所有值+1)。