Centroid detection for irregular shape objects

I am trying to find the centroid of irregular shaped objects from a binary image. For some objects, no centroid is detected and for some, more than one centroid is detected. I am using regionprops with bwconncomp(8-neighbourhood). Some objects have holes in them whereas others are filled.Please advice on how to proceed?

Answers (3)

That sounds really bizarre. Please attach your binary image so I can try it. There can be a few reasons why you might think that some objects have two centroids, for example if you have a disc surrounded by a C - both centroids would lie in the disc. And so you might think the C had no centroid while the disc had two centroids. Be aware that the centroid of a region does not necessarily lie within the region, like in the example of a C-shaped region.

6 Comments

nitin, which of the 85 blobs has it's centroid in the wrong location? Run this code and tell me the number of the blob that has none or 2 or more centroids:
clc;
close all;
workspace; % Make sure the workspace panel with all the variables is showing.
format longg;
format compact;
fontSize = 20;
% Check that user has the Image Processing Toolbox installed.
hasIPT = license('test', 'image_toolbox');
if ~hasIPT
% User does not have the toolbox installed.
message = sprintf('Sorry, but you do not seem to have the Image Processing Toolbox.\nDo you want to try to continue anyway?');
reply = questdlg(message, 'Toolbox missing', 'Yes', 'No', 'Yes');
if strcmpi(reply, 'No')
% User said No, so exit.
return;
end
end
%==========================================================================
baseFileName = '1.jpg';
folder = 'C:\Temp';
% 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.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, '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(1, 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')
% Threshold the image.
binaryImage = grayImage > 128;
% Label each blob with 8-connectivity, so we can make measurements of it
[labeledImage, numberOfBlobs] = bwlabel(binaryImage, 8);
% Apply a variety of pseudo-colors to the regions.
coloredLabelsImage = label2rgb (labeledImage, 'hsv', 'k', 'shuffle');
% Display the pseudo-colored image.
subplot(1,2, 2);
imshow(coloredLabelsImage);
caption = sprintf('%d Labeled Regions', numberOfBlobs);
title(caption, 'FontSize', fontSize);
% Get all the blob properties.
blobMeasurements = regionprops(labeledImage, 'Centroid');
numberOfBlobs = size(blobMeasurements, 1);
% Loop though showing all the blobs and their centroids
promptMessage = sprintf('Do you want to look at each blob centroid,\nor Cancel?');
titleBarCaption = 'Continue?';
button = questdlg(promptMessage, titleBarCaption, 'Continue', 'Cancel', 'Continue');
if strcmpi(button, 'Cancel')
return;
end
subplot(1,1,1);
for k = 1 : numberOfBlobs
binaryImage = labeledImage == k;
imshow(binaryImage);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
drawnow;
x = blobMeasurements(k).Centroid(1);
y = blobMeasurements(k).Centroid(2);
hold on;
plot(x, y, 'r+', 'MarkerSize', 30, 'LineWidth', 2);
promptMessage = sprintf('That is blob #%d of %d.\nDo you want to Continue,\nor Cancel?',...
k, numberOfBlobs);
caption = sprintf('That is blob #%d of %d.', k, numberOfBlobs);
title(caption, 'FontSize', fontSize);
titleBarCaption = 'Continue?';
button = questdlg(promptMessage, titleBarCaption, 'Continue', 'Cancel', 'Continue');
if strcmpi(button, 'Cancel')
break;
end
end
Of course your segmentation looks all messed up because I don't think blob 1 (the green one) should be virtually the entire background.
Thanks a lot Image analyst for writing the code and helping me.
I ran the code and found that there are more than one centroids for circles which are not complete(for ex: yellow, purple circles). As you can see, these centroids are present towards the edge of incomplete circles.
For completely black objects(completely black edges and centres, not hollow like circles), no centroid was identified.It is important for me to get the centroids right because I need to do point neighbour analysis with this data using two types of objects(circles and completely black objects).
I have also attached the same image before thesholding in case you want to try it. Please suggest if there is any other method besides "regionprops" to find the centroid. In case nothing works, can I manually mark centroids. Please advice.
Give me a blob number. I show you all the blobs one by one. What is the number of the blobs that have no centroids or two centroids? If there aren't any, then it's not a bug with regionprops but a problem in your segmentation algorithm.
The code that you sent me for blob numbers does not show detected blobs superimposed on the original image. Thats why it is hard for me to pick a number. There are many as you can see in the colored image that you sent me.
Well the answer is that each blob that you identified has one and exactly one centroid. Not two. Not three or four. One.
The real problem is that your segmentation is all messed up. It sort of looks like you did an edge filter, then dilated it and thresholded it, or something like that. Whatever you did, the binary image it produces (in your "Answer" below) is all messed up. I mean, you've identified virtually the whole background as one big foreground blob! Moreover, the solid black particles do not appear correctly in the segmentation. What did you do? Actually I don't know if it's even worth fixing or if it would be best to just start over with a brand new, but effective, algorithm. Anyway, attach your segmentation code so I can look at it and instruct you why it didn't work.
Actually, I was trying to isolate completely black objects from circular objects(black edges and white centres) by using Fovea Pro in photoshop 1. Manual threshold at 1.0 (to isolate completely black objects) This step eats up some parts of the edge of circular objects 2. Automatic threshold using Johanneson method(to isolate both type of objects from background) 3. Absolute difference of above two image followed by inversion. 4. Open EDM 1 iteration(open the left over edge of completely black object) followed by close EDM 2 iterations(close circular objects)
I followed your advice and processed automatic segmented image(binary image containing both type of objects, see attached). The centroids are marked on it. Still the centroids have not been detected for some objects and for some, more than one. Please advice. Thanks a lot for help.

Sign in to comment.

nitin arora
nitin arora on 17 Mar 2015
Edited: Image Analyst on 17 Mar 2015
Thanks for the quick reply. Please find the image attached. This is a really dirty and noisy system. So, I am not expecting perfection. I noticed that for completely black objects(no holes), no centroid was detected. Please advice. I need to fully automate the image analysis protocol. So, manual correction of objects is not desirable.
i want to find centroid of the detected object in a image ..How to do that ?

Asked:

on 16 Mar 2015

Answered:

on 1 Dec 2017

Community Treasure Hunt

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

Start Hunting!