[Matlab]實現對圖像的均值濾波
軟件環境 matlab R2017a
搜了不少關於使用濾波器的文章,都是直接調用現有函數,我在這裏簡單實現了均值濾波器
問題背景:實現複雜明暗條件下的圖像二值化
例如要把這張圖片二值化,用於後續識別 | 使用全局的閾值劃分,可能會得到以下結果 | 一個更極端的例子 |
---|---|---|
顯然,我們希望得到如下結果
要得出這樣的結果就需要對暗處進行補償、降低過曝處亮度,因此有了濾波器的方案
理論基礎
均值濾波器相關理論
- 基本原理是把數字圖像或數字序列中一點的值用該點的一個鄰域中各點的均值代替,讓周圍的像素值接近的真實值,從而消除孤立的噪聲點
- 方法是用某種結構的二維滑動窗口,將板內像素均值設爲中心點的值
方案實施
- 舉一個使用3*3的正方形窗口的例子,中心點取整個窗口中所有點的均值,實際常用圖片寬度的1/16作爲窗口半徑
關於邊界點的均值,提供3種處理方法供參考
- 可以將矩陣向外擴充一圈,其值可以由某種算法產生(例如全填0或者是通過當前邊界已有的值計算出)
- 可以只計算窗口內有值的像素
- 不改變(如下圖)
-
對第一張灰度圖片全部做如此運算後可以得到一個帶有各區域明暗信息的圖片
-
如果我們對它取反,這個圖片就成爲了一個亮度補償數據,與原圖片相加,可以得到
至此,我們的目的基本達到了,後續只需做簡單處理可得到對比度更高的圖像
matlab代碼
clear;clc;
I = im2double(rgb2gray(imread('C:\Users\Bob Xiao\Desktop\3.png')));
% I(1,1)
[rows, cols] = size(I);
add = floor(cols/16);
windowSize = add*2+1;
newImg = padarray(I, [add,add]); %填充邊界之後的圖片
bgImg = zeros(rows,cols);
for i=add+1:add+rows
for j=add+1:add+cols
myWin = newImg(i-add:i+add,j-add:j+add);
bgImg(i-add,j-add) = AvgWin(myWin);
end
end
pImg = I + bgImg;
figure(1);
subplot(2,2,1);
imshow(I);
subplot(2,2,2);
imshow(newImg);
subplot(2,2,3);
imshow(bgImg);
subplot(2,2,4);
imshow(pImg);
function [M] = AvgWin(IN)
% 傳入一個矩陣,求均值
avg = mean(mean(IN));
M = avg;
end
寫在後面:這個算法的時間複雜度非常高,達O(mnp2),(其基本操作:求窗口均值,內部的時間複雜度爲O(n^2)),因而不適合實際應用。
Note:另有積分圖方法,只需遍歷一次圖片,時間複雜度僅爲O(mn)。