Find centroid of binary image
Show older comments
I want to know find centroid area in picture output show X,Y axis
Sample
centroid x 60 centroid y 40

Answers (2)
Guillaume
on 29 Jan 2017
stats = regionprops(yourimage);
centroid = stats.centroid;
Or calculate it yourself according to its definition, the mean of the pixel coordinates:
[y, x] = ndgrid(1:size(yourimage, 1), 1:size(yourimage, 2));
centroid = mean([x(logical(yourimage)), y(logical(yourimage))]);
12 Comments
A. Faruk
on 23 Apr 2019
How can I do this in SIMULINK? Is there any special block to find the centroid of a binary image? I want to show the centroid on the video.
Walter Roberson
on 25 Apr 2019
Bradley Rogers
on 16 May 2024
first worked, 2nd didnt >> centroid = mean([y(logical(im)), x(logical(im))]);
The logical indices contain a true value outside of the array
bounds.
Your image has more than one page. In other words, it's either a multichannel (e.g. RGB) image, or it's a volumetric image of some sort. If it's RGB, use im2gray() or some other method to reduce it to grayscale. If it's volumetric, that's another story.
I would also argue that using logical() for this task is a bad idea -- or at least it can be. This is something that I explicitly mention in the synopsis for MIMT imcast(). If the image isn't a clean, perfectly binarized image already, logical() will produce unexpected results which are conceptually inconsistent across input classes. If you want to use a binary image for logical addressing, reduce it to a logical mask using some deliberate approach (e.g. imbinarize(), or simple thresholding) instead of trusting that changing the class will coincidentally binarize it as you intend.
Consider the given image.
% this used to be a binary image
% but it's been damaged by lossy compression
inpict = imread('image.jpeg'); % uint8, single-channel
imshow(inpict,'border','tight')
xlim([700 1000])
ylim([175 675])
% two different ways to reduce the numeric image to logical
% this emphasizes all the artifacts, effectively dilating the image
maskA = logical(inpict); % select everything except exactly zero
imshow(maskA,'border','tight')
xlim([700 1000])
ylim([175 675])
% this is more appropriate, but the threshold value depends on the numeric class
maskB = inpict >= 128; % split the available dynamic range
imshow(maskB,'border','tight')
xlim([700 1000])
ylim([175 675])
Bradley Rogers
on 18 May 2024
Id appreciate help, Im learning and want to figure out how to take an image with 3 dots, and find the Centroid of each? I want to get the location of the Centroid of each dot? Thanks!

Something like so:
% get the image and reduce it to one channel
inpict = imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1697931/image.bmp');
inpict = im2gray(inpict);
% binarize the image
% make sure that the output polarity is such that
% you have white objects on a black background
mask = ~imbinarize(inpict);
% get centroids
S = regionprops(mask,'centroid');
C = vertcat(S.Centroid); % [x y]
% plot the centers over the image for illustration
imshow(mask,'border','tight'); hold on
plot(C(:,1),C(:,2),'mx','markersize',30,'linewidth',3)
Bradley Rogers
on 19 May 2024
Yes! Thank you so much, this is an awesome start. I notice the values:
C =
49.0128 34.5114
419.0128 233.5114
581.0128 243.5114
These appear to absolutely match the 3 dot locations; But why are the fraction values only .0128 or .5114 ? These are simply random dots made in Paint. I would like to know the dot origin and thought it was a pixel ID# of the image in a whole number? If it calculates fraction precision great.
How do we discriminate the blobs based on minimum size? If an image has 1-5 blobs of interest how can we set the min, max blob recognition size?
Thanks again!!
Image Analyst
on 19 May 2024
@Bradley Rogers your 3 spots have exactly, perfectly the same shape so it makes sense that the centroid will be at the same fractional location no matter where it's located. Just think about it and I think you'll realize it. If they were different shapes then the fractional parts would be different.
To answer your question about filtering/extracting blobs meeting certain criteria, see my Image Segmentation Tutorial in my File Exchange:
It's a generic, general purpose demo of how to threshold an image to find blobs, and then measure things about the blobs, and extract certain blobs based on their areas or diameters.
Bradley Rogers
on 19 May 2024
Edited: Bradley Rogers
on 19 May 2024
Yes! That makes perfect sense, I resized one, and sure enough, and nice examples am looking at those. Would be really nice to see this put into C# or to visualize the process. Saved this as a Function, it wouldnt plot so it just outputs the centroids.
Image Analyst
on 19 May 2024
% Have user browse for a file, from a specified "starting folder."
% For convenience in browsing, set a starting folder from which to browse.
startingFolder = pwd; % or 'C:\wherever';
if ~isfolder(startingFolder)
% If that folder doesn't exist, just start in the current folder.
startingFolder = pwd;
end
% Get the name of the file that the user wants to use.
defaultFileName = fullfile(startingFolder, '*.*');
[baseFileName, folder] = uigetfile(defaultFileName, 'Select a file');
if baseFileName == 0
% User clicked the Cancel button.
return;
end
fullFileName = fullfile(folder, baseFileName)
Bradley Rogers
on 19 May 2024
Got codegeneration and tried to make a C++ file, Centroid cant be converted over?
DGM
on 20 May 2024
I'm going to have to tap out once it comes to code generation stuff. I'm not familiar with what will build. I haven't really touched it, and I'm running old enough stuff that it would be moot even if I had.
Walter Roberson
on 29 Jan 2017
2 votes
regionprops() and ask for Centroid
Categories
Find more on Image Processing Toolbox in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


