An efficient way to create checkers from connected components
I have a binary image of several related components, some large and some small (maybe only 1 pixel). With this, I am looking for a way to make each connected component into a checkers pattern rather than its associated blocks in an efficient way.
So far I have come up with two ways that this could be tried, but they can either create errors or be rather ineffective:
-
I know the whole image and can make a checkers pattern mask to remove 50% of the pixels. This is very fast, but on average it removes 50% of the connected components, which is only one pixel in the area.
-
Use
bwlabel()
in MATLAB / Octave and skip every connected component, only applying a mask to that component if it is greater than 1 pixel (leaving other components to be considered when the loop hits them) This can be very inefficient.
Any smart / embedded solutions that can be used?
The code for creating the shape
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');
source to share
Nothing beats the effect of checking on a blanket. All you have to do is add back the small connected components.
%# create a test image
img = rand(100)>0.8;
img = imclose(img,ones(5));
img = imerode(img,strel('disk',2));
%# get connected components
%# use 4-connect to preserve
%# the diagonal single-pixel lines later
cc = bwconncomp(img,4)
%# create checkerboard using one of Matlab 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;
source to share