Bounding circle for objects in binary image?

7 views (last 30 days)
Can anyone suggest a way to draw bounding circles around labeled objects in a binary image?
I have some irregularly shaped objects. Rather than finding the centroids of the objects themselves, I would like to find the centroids of the smallest circle that will enclose the objects. Contact between the bounding circle and the object should be maximized.
Thanks, Heidi

Accepted Answer

Sean de Wolski
Sean de Wolski on 23 Jun 2011
Use the distance transform on the inverse of the image. The point that is the largest value on each object will be the centroid of the circle and its radius will be the value.
doc bwdist
  3 Comments
David Inglis
David Inglis on 27 Feb 2023
This doesn't seem to be working for me. I have a binary image, and can draw a good bounding rectangle using region props, but the location and radii from bsdist never encompass the blob and seem weighted towards the centre of mass. You can see the contours from bwdist and the circle located at the centre with a radii of the max value. Any thoughts? Code below image.
clear all
exp=imread("test image.jpg");
exp=imresize(exp,0.5); % reduce image size by 2 for compute speed
n=4; %size of open and close
yellow=yellowballMask(exp,4); % find yellow ball pieces
blue=BlueBallMask(exp,2); % find blue ball pieces
K1=or(yellow,blue); % merge the two into a binary image
se = strel('disk',12);
K2 = imclose(K1,se); % try to close the gaps between blue and yellow
K3=~K2; % invert image for bwdist
D1 = bwdist(K3);
[val ind] = max(D1(:)); % determine location and value of maximum from bwdist
[I_row, I_col] = ind2sub(size(D1),ind); %convert to row and column
s=regionprops(K2,'BoundingBox'); % create rectangular bounding box
subplot(1,2,2)
imcontour(D1)
viscircles([I_col I_row],val);
rectangle('Position',s.BoundingBox,'EdgeColor','b')
title('bwdist Contours');
subplot(1,2,1)
imshow(exp); hold on
title('original iamge');
viscircles([I_col I_row],val);
Image Analyst
Image Analyst on 27 Feb 2023
Edited: Image Analyst on 27 Feb 2023
@David Inglis see my answer below and use the min bounding circle function in this:
Or use bwboundaries to get the actual outline of the blob.
% Plot the borders of all the blobs in the overlay above the original grayscale image
% using the coordinates returned by bwboundaries().
% bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.
imshow(originalImage); % Optional : show the original image again. Or you can leave the binary image showing if you want.
% Here is where we actually get the boundaries for each blob.
boundaries = bwboundaries(mask);
% boundaries is a cell array - one cell for each blob.
% In each cell is an N-by-2 list of coordinates in a (row, column) format. Note: NOT (x,y).
% Column 1 is rows, or y. Column 2 is columns, or x.
numberOfBoundaries = size(boundaries, 1); % Count the boundaries so we can use it in our for loop
% Here is where we actually plot the boundaries of each blob in the overlay.
hold on; % Don't let boundaries blow away the displayed image.
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k}; % Get boundary for this specific blob.
x = thisBoundary(:,2); % Column 2 is the columns, which is x.
y = thisBoundary(:,1); % Column 1 is the rows, which is y.
plot(x, y, 'r-', 'LineWidth', 2); % Plot boundary in red.
end
hold off;
caption = sprintf('%d Outlines, from bwboundaries()', numberOfBoundaries);
fontSize = 15;
title(caption, 'FontSize', fontSize);
axis('on', 'image'); % Make sure image is not artificially stretched because of screen's aspect ratio.

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 27 Feb 2023
See the min bounding circle here:
Just pass the coordinates of your blob mask into it. You can get the x,y of the binary image like this, assuming you have just one blob in the mask
[y, x] = find(mask);

Community Treasure Hunt

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

Start Hunting!