2015-02-10 139 views
0

我想在具有給定3x3掩碼的2D二值圖像上使用medfilt2 function在Matlab中使用3x3掩碼的中值濾波器二進制圖像

不幸的是,medfilt2不會將掩碼作爲參數。

如何以其他方式將median filter圖像與3x3蒙版相混淆?

例如:

binary_image = [0 0 0 0 0 0 0 0; 
       0 1 0 1 0 1 1 0; 
       0 1 1 1 1 1 1 0; 
       0 1 0 1 1 1 0 0; 
       0 0 0 1 1 0 1 0; 
       0 1 1 1 0 1 1 0; 
       0 1 0 1 1 1 1 0; 
       0 0 0 0 0 0 0 0]; 

mask = [1 0 1; 
     0 1 1 ; 
     1 1 1]; 
+0

你可以自己實現一箇中值過濾器並添加掩碼功能嗎?它不應該太難。 – eigenchris 2015-02-10 19:00:48

+0

那麼你想計算只有那些在'mask'中有效的值的中位數? – rayryeng 2015-02-10 19:07:57

+0

yes rayryeng。 eigenchris,我正在尋找matlab中的內置方法 – James 2015-02-10 19:12:07

回答

2

簡短的回答是你可以使用nlfilter你可以指定在你的圖像中的像素鄰域做了什麼。具體來說,你會打電話nlfilter像這樣:

B = nlfilter(A, [m n], fun); 

A將是一個圖像,[m n]會指定你正在考慮的像素鄰(m x n)的大小,fun是應用於每個鄰里功能。輸入是m x n補丁,輸出應該是單個值。假設masklogical,你的圖像存儲在im,所有你需要做的是:

out = nlfilter(im, size(mask), @(x) median(x(mask))); 

x(mask)訪問那些鄰里內有效的位置,然後將適用median這些值來檢索每個社區在有效地點的中間值。

但是,nlfilter已知很慢。我建議你看看我的帖子:Matlab Median Filter Code

這可以非常快速地從第一原理計算出median過濾器。我會讓你閱讀這篇文章,瞭解我做了什麼。但是,爲了達到您的目的,您需要做的修改是去除im2col輸出中與掩碼中的無效值相對應的那些行。因此,做這樣的事情:

N = size(mask,1); %// Size of mask - Assume that # of rows = # of columns 
im_pad = padarray(im, [floor(N/2) floor(N/2)]); 
im_col = im2col(im_pad, [N N], 'sliding'); 

%// Get locations in mask that don't count towards getting median 
invalid_rows = ~(mask(:)); 

%// Remove from column neighbourhood matrix 
im_col(invalid_rows,:) = []; 

%// Determine new median index 
val = floor((N*N - sum(invalid_rows))/2) + 1; 

%// apply algorithm as normal 
sorted_cols = sort(im_col, 1, 'ascend'); 
med_vector = sorted_cols(val, :); 
out = col2im(med_vector, [N N], size(im_pad), 'sliding'); 

invalid_rows解開面具成一列,就像什麼im2col確實爲每個像素附近,然後我們反轉面具,以確定不應該向計數的位置最終中位數。另外,val確定新的索引,我們需要從哪裏獲取中值,從我們開始移除未分析鄰域中的像素開始。


如果輸入是二進制圖像,那麼eigenchris對您的回答應該非常快,比我寫的要快得多。但是,如果這適用於灰度圖像,那麼我寫的將起作用。這適用於二進制和灰度圖像。

+1

不錯的快速中值濾波器實現。 :) – eigenchris 2015-02-10 19:32:44

1

如果你只處理二進制圖像時,可以通過與conv2()功能進行卷積解決這個問題。

邏輯是,由於在掩碼中有7個有效像素,如果卷積結果中的像素值大於或等於4,我們知道中位數爲1。否則,中位數必須是0

一般來說,如果你的掩碼中有n有效像素,我們可以通過將卷積矩陣的結果除以n得到掩蔽的中值。

n = sum(sum(mask));     % number of valid pixels in the mask 
maskFlipped = fliplr(flipud(mask)); % flip mask so it faces the right way 
convResult = conv2(binary_image,maskFlipped,'same'); 
maskedMedianFilterResult = round(convResult/n); 
+1

很棒的回答。你也可以使用'maskFlipped = mask(end:-1:1,end:-1:1);'來實現翻轉。這樣,我們可以避免使用兩個嵌套的函數調用。 +1 btw。 – rayryeng 2015-02-10 19:32:26

相關問題