Filling objects that share a border

Hi,
I have a question about filling in objects that share a border with the perimeter of an image.
Consider a case such as the one shown at: http://i43.tinypic.com/2nq9ua.jpg. If I run the imfill function to fill in the holes, I don’t get the five objects that touch the border of the image filled (I have pointed out the specific areas I am talking about, in this image: http://i41.tinypic.com/5afeo4.jpg).
Is there any strategy I could follow to fill holes in those areas that are outlined using the arrows?
Thanks in advance!

 Accepted Answer

Image Analyst
Image Analyst on 4 Sep 2013
Edited: Image Analyst on 5 Sep 2013
  1. Binarize and Invert the image: binaryImage = grayImage <128
  2. Call imfill(binaryImage, 'holes')
  3. call regionprops(binaryImage, 'BoundingBox') asking for bounding box
  4. Look at the 4 sides of all the bounding boxes looking for any objects that share any bounding box side coordinate.
Give it a shot.

3 Comments

OK, no response so I'm guessing that you couldn't do it, so I did it for you. Try this code (be sure to change the folder and filename):
clc; % Clear the command window.
clearvars
close all;
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
% Read in a standard MATLAB gray scale demo image.
folder = 'C:\Users\Alexius\Documents';
baseFileName = '2nq9ua.jpg';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% File doesn't exist -- didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[rows, columns, numberOfColorBands] = size(grayImage);
if numberOfColorBands > 1
% It's not really gray scale like we expected - it's color.
% Convert it to gray scale by taking only the green channel.
grayImage = grayImage(:, :, 2); % Take green channel.
end
% Display the original gray scale image.
subplot(2, 2, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Give a name to the title bar.
set(gcf,'name','Demo by ImageAnalyst','numbertitle','off')
% Binarize and Invert the image:
binaryImage = grayImage < 128;
% Display the image.
subplot(2, 2, 2);
imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize);
% Call imfill(binaryImage, 'holes')
binaryImage = imfill(binaryImage, 'holes');
% Display the image.
subplot(2, 2, 3);
imshow(binaryImage, []);
title('Filled Binary Image', 'FontSize', fontSize);
% Get areas
labeledImage = bwlabel(binaryImage);
measurements = regionprops(labeledImage, 'Area')
% Sort based on areas
[sortedAreas, sortIndexes] = sort([measurements.Area], 'Descend')
% Get rid of largest one, which is the background.
% Extract only those blobs that meet our criteria, and
% eliminate those blobs that don't meet our criteria.
% Note how we use ismember() to do this.
keeperBlobsImage = ismember(labeledImage, sortIndexes(2:end));
% Display what we retained.
% Display the image.
subplot(2, 2, 4);
imshow(keeperBlobsImage, []);
title('Border blobs', 'FontSize', fontSize);
% Get bounding boxes of the border blobs. Need to relabel again.
[labeledImage, numberOfBlobs] = bwlabel(keeperBlobsImage);
measurements = regionprops(labeledImage, 'BoundingBox', 'Centroid')
% Loop over blobs, labeling them with text.
hold on;
for b1 = 1 : numberOfBlobs
x = measurements(b1).Centroid(1);
y = measurements(b1).Centroid(2);
text(x, y, num2str(b1));
end
% Loop over blobs, comparing each blob to the other blobs
for b1 = 1 : numberOfBlobs
boundingBox1 = measurements(b1).BoundingBox;
x1 = [boundingBox1(1), boundingBox1(1) + boundingBox1(3)]
y1 = [boundingBox1(2), boundingBox1(2) + boundingBox1(4)]
for b2 = 1 : numberOfBlobs
if b2 == b1
continue;
end
boundingBox2 = measurements(b2).BoundingBox;
x2 = [boundingBox2(1), boundingBox2(1) + boundingBox2(3)]
y2 = [boundingBox2(2), boundingBox2(2) + boundingBox2(4)]
% See if they share the top border
if y1(1) == y2(1)
message = sprintf('Blob %d shares the top border with blob #%d', b1, b2);
uiwait(msgbox(message));
end
% See if they share the bottom border
if y1(2) == y2(2)
message = sprintf('Blob %d shares the bottom border with blob #%d', b1, b2);
uiwait(msgbox(message));
end
% See if they share the left border
if x1(1) == x2(1)
message = sprintf('Blob %d shares the left border with blob #%d', b1, b2);
uiwait(msgbox(message));
end
% See if they share the right border
if x1(2) == x2(2)
message = sprintf('Blob %d shares the right border with blob #%d', b1, b2);
uiwait(msgbox(message));
end
end
end
msgbox('Done with demo. Thanks ImageAnalyst!');
thank you Image Analyst for the answer. I've tried the code, and get error..
Error in imfill (line 132)
mask = padarray(mask, ones(1,ndims(mask)), -Inf, 'both');
Error in padarray (line 51)
binaryImage = imfill(binaryImage, 'holes');
can you help me, I’m quite new to IPT.
I'm sorry. I forgot to change the folder and filename. Now the code works. Thank you Image Analyst. :D

Sign in to comment.

Categories

Find more on Deep Learning Toolbox in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!