2012-09-07 76 views
2

我有幾個連接組件的一個二進制圖像,有些很大,有些很小(可能只有一個像素)。有了這個,我正在尋找一種方法,以有效的方式將每個連接的組件變成跳棋模式,而不是連接的斑點。從連接組件中製作跳棋的有效方法

到目前爲止,我已經提出了兩個方面,這可以嘗試,但它們可以產生錯誤,或者是相當效率不高:

  1. 我知道整個圖像,並可以使跳棋圖案面具刪除50%的像素。這是非常快的,但平均將刪除50%的面積只有一個像素的連接組件。

  2. 在MATLAB/Octave中使用bwlabel(),並且循環遍歷每個連接的組件,如果它超過1個像素,則只將掩碼應用於該組件(當循環到達它們時將考慮其他組件)。這可能是非常低效的。

任何可以使用的智能/內置解決方案?

Example

代碼,以生成數字

T = zeros(40,40); 
T(10:30,10:30) = 1; 

chessVec = repmat([1;0],20,1); 

T_wanted = (repmat([chessVec circshift(chessVec,1)],1,20).*T); 

figure(); 
subplot(1,2,1);imshow(T);title('Start shape') 
subplot(1,2,2);imshow(T_wanted);title('Wanted shape'); 

回答

7

沒有什麼比毯子滾花的效率。所有你需要做的是加回小的連接組件。

%# create a test image 
img = rand(100)>0.8; 
img = imclose(img,ones(5)); 
img = imerode(img,strel('disk',2)); 

enter image description here

%# get connected components 
%# use 4-connect to preserve 
%# the diagonal single-pixel lines later 
cc = bwconncomp(img,4) 

%# create checkerboard using one of Matlab's special matrix functions 
chk = invhilb(100,100) < 0; 

%# checker original image, add back small stuff 
img(chk) = 0; 

smallIdx = cellfun(@(x)x<2,cc.PixelIdxList); 
img([cc.PixelIdxList{smallIdx}]) = 1; 

enter image description here

+2

這是一個偉大的答案! – slayton

+0

+1優雅的解決方案和一個很好的答案! – Shai