2012-09-07 33 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