One the measurements provided by regionprops is 'Centroid'. Here's an example of labeling binary objects, computing the centroid of each object, and plotting the centroid location on top of the image.
I = imread('text.png');
imshow(I)
L = bwlabel(I); s = regionprops(L, 'Centroid'); hold on for k = 1:numel(s) plot(s(k).Centroid(1), s(k).Centroid(2), 'r*') end hold off xlim([0 60]) ylim([0 60])
Last week, reader Daphne asked how to compute the intensity-weighted centroid. That is, if each labeled region corresponds to a region in a gray scale image, how do you compute the centroid weighted by the gray scale pixel values? The easiest way, I think, is to use the both the PixelIdxList and PixelList properties from regionprops. Let's try it with a simple synthetic image (download the image from here):
I = imread('spheres.png');
imshow(I)
Now let's threshold and label it:
bw = I < 255;
bw = imfill(bw, 'holes');
L = bwlabel(bw);
imshow(label2rgb(L, @jet, [.7 .7 .7]))
Next, get the PixelIdxList and PixelList for each labeled region:
s = regionprops(L, 'PixelIdxList', 'PixelList');
Each row of the PixelList for a region contains the x and y coordinates of a pixel in that region.
s(1).PixelList(1:4, :)
ans =
48 94
48 95
48 96
48 97
We can get the grayscale value of pixels in a region by indexing into I with PixelIdxList. By weighting those values with the x and y coordinates, we can compute the centroid.
idx = s(1).PixelIdxList; sum_region1 = sum(I(idx)); x = s(1).PixelList(:, 1); y = s(1).PixelList(:, 2); xbar = sum(x .* double(I(idx))) / sum_region1
xbar = 74.6128
ybar = sum(y .* double(I(idx))) / sum_region1
ybar = 92.5121
Let's do that in a loop and superimpose the centroid locations on the image.
imshow(I) hold on for k = 1:numel(s) idx = s(k).PixelIdxList; pixel_values = double(I(idx)); sum_pixel_values = sum(pixel_values); x = s(k).PixelList(:, 1); y = s(k).PixelList(:, 2); xbar = sum(x .* pixel_values) / sum_pixel_values; ybar = sum(y .* pixel_values) / sum_pixel_values; plot(xbar, ybar, '*') end hold off
Get
the MATLAB code
Published with MATLAB® 7.5



Hi Steve,
Thanks for the input. This works nicely and pretty quickly. However, it does require a binary image - i.e., a threshold value is needed. This is not so straightforward with an image that has less than perfect/clean background.
Will try to incorporate this, perhaps with the brightest pixel cutoff I had mentioned in my previous comment. That is, only blobs with a pixel > thresh will be considered at all.
A more general question, my original images just appear as nothing (plain gray) with imshow, but are beautiful with imagesc. Why is that ?
I can email a sample figure if you like.
Daphne
Daphne—The binary image is just a way to represent the set of pixels associated with each region. If you don’t know which pixels belong to each object, then I can’t think of a way to calculate the centroids. It’s like being asked to compute a definite integral without being told the limits of integration.
imshow assumes certain black-to-white dynamic ranges for gray scale images. For example, if the input image is uint8, then 0 is displayed as black and 255 is displayed as white. If the input image is uint16, then 65535 is displayed as white. For double and single images, 1 is displayed as white. imagesc, on the other hand, displayes the image in image-dependent fashion. The minimum pixel is displayed using the first colormap color, and the maximum pixel is displayed using the last colormap color. To get a similar effect using imshow, use this syntax:
See the imshow doc for an explanation. You might also want to look at my “All about pixel colors” posts between January and April 2006.
Hello Steve,
I wonder how i can find the proper threshold value of the picture.Could you please tell me how the theshold come and how i can get the proper threshold value ?
please explian to me.
I am new here and i’ve just started to study about Image Processing,so i do not know much about it but i want to learn about it.
Regards
suwanna
Suwanna—You might try using the function graythresh.
Hi Steve,
thanks for the nice solution to the gravity-center question. Just a minor issue: I noticed I cannot get the following line to work:
>> bw=I > bw = im2bw(I,0.9);
>> bw=1-bw;
sorry the line-breaks were messed up in the last post- feel free to delete it.
Regards,
Chaitanya.
Chaitanya—Where did that code come from? It doesn’t resemble any code in this post. Your first line has a syntax error (two equals signs).
Hello Steve
Thanks very much .
i will try to read it.
Regards
suwanna
Hi Steve,
Great tutorial. I wanted to ask you - the objects that I am trying to find the centroid of are not perfect spheres - is there anyway to manipulate a roughly spherical object into being represented as one. I’ve already applied a threshold to isolate the objects of interest, and i’ve also reduced noise by removing small objects [bw = bwareaopen(bw,30);]. However, due to the nature of the areas left, your code returns multiple centroids.
So in a nutshell is there anyway of approximating crude blobs as spheres?
Many thanks in advance.
Tariq—You might want to try a morphological closing step (imclose) prior to calling bwareaopen.
Thanks Steve. It works great.
Hi Steve
i doing project on “automatic signature verification system” .for that i am reading IEEE papers.in some papers authors are takeing “signature centroid” as feature.using above method i computed “Intensity-weighted centroids”.it is giving so many centroid points.but in IEEE papers they are showing only one centroid point.please tell me the difference between “signature centroid “, and “Intensity-weighted centroids”.
is their any difference between them.
K—The intensity-weighted centroids is giving you one centroid per connected component. You’ll need to preprocess the signature block to turn it into a single component. For the unweighted centroid, which is probably what you want, take the mean of the row coordinates and the mean of the columns coordinates for all the pixels belonging to the signature.
THANK YOU
STEVE
Hello Steve,
I tried your method with an image with regularly spaced spheres, but the centroids were not marked in an orderly manner (for example, centroids are not marked columnwise from left to right of image). If the spheres were arranged regularly in rows and columns, how can we ensure that the values in ‘xbar’ and ‘ybar’ are in an orderly manner?
Ana—The connected-components labeling functions (bwlabel and bwlabeln) do scan the image in columnwise order, from left to right. The particular object ordering that results, though, depends on where the scan first encountered a pixel belonging to each object. For example, an object below another object will get labeled first if the lower object sticks out even a tiny bit to the left. You can use functions such as sort and sortrows to rearrange the measurements however you wish.
hello sir,
i want to find centroid for my ultrasound breast image so as to find out the seed points to grow a region of interest..
Actually in the ultrasound image all lesion parts lye on the centre of the image only.
i calculated the feature values and got the seed points..
but some seed points are lying on the outside of the region of interest also..
so i thought of calculating the centroid and then find out the seed points in that particular area..
is my thought of doing this is write r not sir…
please give suggestions and send the centroid coding.
thank u..
Hi Steve,
I am working on hand written characters.
I am trying to import a 35*35 image and wanted to find the centroid of the character not for the whole image but according to the character aligment and its pixel intensity I wanted to calculate the cenroid based on the x-coordinate and y-coordinate distance using the formula:
Hence, Cx =(∑ xi) /N and Cy = (∑ yi)/N
for all 1 to N pixels. Since, Centroid (Cx, Cy) of a character is :
For a given character the summation of product of each pixels x-coordinate distance and its intensity value, divided by total no. of character pixels (N) gives x-coordinate of the centroid.
How to find the x-coordinate distance from a pixel and like-wise the y-cordinate distance?
Steve, Can you please let me know abt this…as this would be a great help to me.
Thanks in Advance,
Lakshmi
Sylvia—This post contains code and explanations for computing centroids.
Lakshmi—The centroid calculation involves the x-coordinate and y-coordinate of the pixel, not the distance from the pixel. This post shows how to do the calculation.
Thank you Steve.
My question was to find the pixel’s distance from x-axis.
I used
a=imread(’img.bmp’)
[y,x]=find(a)
and got the ans for tht!
Thanks once again
Thank u Steve..
Now i am working in ultrasound breast image.. my aim is to segment the leion area.. for this i used region growing technique.. i have found out seed point using texture features and grown the region by fixing the threshold(global thresholding).. but it works for only 2 images.. for the other images, other areas including the lesion area is segmented out..what i can i do for this type of problem. please clear my doubt and send me the coding to segment my lesion area alone.. waiting for your reply steve.. thank u.
Sylvia—I’m sorry, but image segmentation usually involves application- or data-set-specific algorithm development. It’s not something I can do for you or send you code for.
Dear Steve
I want to achieve the same results as Daphne, except in my case, I am using a real life actual image of crystal lattices showing many atoms in rows and columns. Your synthetic image was good quality; but on my image I can’t use the simple thresholding you used, in my image the atoms are all of different intensities, thus I have used multi-level thresholding using the grayslice function. Can one achieve the same results and obtain the centroide for each atom.
Hello Steve,
How could we use the MajorAxis and MinorAxis length to determine the location of an object in an image? I know that using the Centroid we could easily determine the location by using the x and y coordinates of the centroid.
But how could that be done using Major and Minor axis?
Shahnawaz—You will need to find a way to solve the segmentation problem somehow. If you can’t identify which pixels belong to each atom, then I don’t see how you can compute the centroids.
Mj—MajorAxisLength and MinorAxisLength give you no information about the location of an object in an image.
Then what are the properties (other than centroid) that could give me information about the location of an object in an image?
Mj—See the documentation for regionprops.
Dear Steve
How can I extract all the x and y coordinates in any image; then create separate images of Y and Y coordinates. I can at present extract certain X and Y coordinates but not all of them automatically.
Regards Shahnawaz
Shahnawaz—Extract the x and y coordinates of what? And what is an image of X and Y coordinates?
Dear Steve
Apologize for the lack of clarity, I meant extracting all the X and Y pixel coordinates from any image automatically; and create a pictorial representation (image) of all the X and Y pixel coordinates seperately. At present I can extract only certain pixel coordinates not all of them at once.
Regards Shahnawaz
Shahnawaz—You just repeated your question. I still don’t understand it.
Dear Steve
Sorry about this I understand but have not got it across well. I believe (imtool) in matlab does something similar but only one location and pixel value at a time using the mouse;
I want to do it as a global operation and extract all the coordinate locations and pixel values in my case for each atom; I think it should work for any image. I want to store x and y location information separately as an image of location values one for x and one for y. I hope this makes more sense.
P.S Can you delete the two which did not make sense.
I have managed to extract some of them x and y coordinates and pixel values I am dealing with a graylevel image.
Shahnawaz—Try meshgrid.
Dear steve
How can I find MaxIntensity,MeanIntensity from regionprops for grayscale image?
Suzie—MaxIntensity and MeanIntensity measurements are provided by regionprops in the latest release, R2008a. If you have an earlier version, see the techniques used in this post.
Steve, I have used regionprops to find centroids of objects in binary images for a class, and I am inquiring as to the algorithm used to do this because we have to explain all methods used. Is it safe to assume that groups of white pixels are found based on sharing common sides (no corner contact, that would result in 2 objects) then the common formula for finding the centroid is applied to each white pixel object? I have found reference to this on other sites but was wondering if you could offer me more insight to the algorithm this function uses.
Thanks again,
Josh
Josh—Presumably, you used bwlabel before you called regionprops. bwlabel computes connected components. By default, it uses “8-connectivity,” meaning that pixels connected at the corners are assumed to belong to the same object. You can also get bwlabel to use “4-connectivity,” meaning that pixels connected only at the corners belong to different objects. The reference page for bwlabel describes the algorithm used and gives a reference. And yes, regionprops uses the “common formula” for the centroid. You could look at the ComputeCentroid subfunction of regionprops to see the actual implementation.
hello sir
I want to calculate the centroid of edges/ Lines. I am working on image segmentation Project. I have obtained edge map of image by using Phase Congruency(Peter Kovesi). After getting binary image of edge map. I have used bwlabel to label each edge/ line in the image. Now I want to find the centroid of each edge. Then want to use K means clustering for clustering long edges. I am facing problem in finding the centroid of edge/ Line. How it could be done?
Thanks in advance
Patil Rajendra
Patil—Use regionprops.
Dear Steve
How can I display all the x coordinates per row and y coordinates per row individually if I have many objects in a binary image in rows and columns using pixellist ???
regards shah
I have tried something like this below were ZW is a binary image.All I get is one x row and one y row
% Computing X Y Coordinates
LABEL= bwlabel(ZW)
figure, imshow(LABEL)
LABEL2=regionprops(LABEL,’PixelList’)
x = LABEL2(1).PixelList(:, 1)
y = LABEL2(2).PixelList(:, 2)
Dear Steve
How can I display the xy coordinates on the binary objects ????
Shah—Your code for extracting x and y coordinates looks correct. If LABEL2(1).PixelList has only one row, that means the first object labeled has only one pixel.
Dear Steve,
I have found a bug in region groups operators, in my binary image I have many objects which represent atomic rows and columns etc. It turns out the first data value does not represent the first top left row object. It seems the first data value represents the 6th atom in the row which is object 1 and the first object in the row is represents the 1oth object. Surely this is a design fault in the function. Is there a way to overcome this so the first measurement value represents the first top left hand atom ?? Has this bug been fixed ???
Shaz—The behavior you describe is not a bug. There is no single correct way to order labeled objects. The Image Processing Toolbox function bwlabel searches along columns first because this is the way MATLAB orders elements in memory. See my post on bwlabel search order. If you want a different labeling order, you can postprocess the output of bwlabel, and I describe how to do this in my post on relabeling a label matrix.
Hi steve;
i have two binary images, one is measured and another is computed. in both images there are several small structure (i.e. rice grains). i want to measure 2D distance between each rice grains in each image with respect to the other, (i. e. the distance between measured and computed).
could you please give me some ideas?
Thank you.
DP
DP—Use regionprops to compute the centroids, and then use hypot to compute the distances between the centroids.
Hi Steve,
Thanks for your email. i already apply regionprops and hypot function according to your example demo, but i have 81 centroids in computed binary image and 81 centroids on measured binary image, i added these 2 images and now, i want to find the distance between nearest neighbour between each computed and measured centroids on image. my image size is 256×256 and pixel size is 0.388mm x0.388mm. is this still possible to measure the distance between nearest-neighbour between centroids?
sincerely yours,DP
Hi steve,
could you please look at the last few line of the code, am i doing the correct for loop? i am not getting expected answer for centroid distance.
Thankz.
DP
I1 = imread(’PP5_recon_01.tif’);
info1 = imfinfo(’PP5_recon_01.tif’)
info1.XResolution;
info1.YResolution;
info1.ResolutionUnit;
L = bwlabel(I1);
s = regionprops(L, ‘Centroid’)
I2 = imread(’PP5_Measured_0_0.tif’);
info2 = imfinfo(’PP5_Measured_0_0.tif’)
info2.XResolution;
info2.YResolution;
info2.ResolutionUnit;
L1 = bwlabel(I2);
s1 = regionprops(L1, ‘Centroid’)
for k = 1:77 % number of centroids
delta_x(k) = s(k).Centroid(1) - s1(k).Centroid(1);
delta_y(k)= s(k).Centroid(2) - s1(k).Centroid(2);
end;
pixel_distance = hypot(delta_x, delta_y)
DP—Debugging user code is a bit beyond the scope of this blog, but I did notice one possible issue. If objects in the two images have different sizes and extents, then there’s no guarantee that bwlabel will label them in the same order. You’ll have to write additional code that somehow matches up corresponding objects in the two images. Also, I don’t really understand your question in comment #48.
Thanks steve.
Dea Steve,
You’ve introduced the intensity weighted centroid, what about squared intensity weighted centroid? Do you know any comparison between these two? Say, for example, which gives a better location under what condition? Thanks
Yuanming—Squared-intensity weighted centroid can be computed using the same basic procedure given in this post. You get to decide whether that measurement is meaningful and useful to you. :-) Just from a few moments thought (pun intended), I imagine it would bias the measured location toward the location of the highest-valued pixel.
hello Steve,
I am trying to create an intensity plot from an atomic image. The image contains silicon and a higher silicon germanium concentration, which means that part produces more intensity. Currently I have tried to remove the backhround image from the atomic image by using imsubtract and strel ?? Would that have an affect on the resultant intensity plot ???
[I deleted the code for space reasons. The code looked like a copy of the nonuniform illumination compensation demo in the Image Processing Toolbox. -Steve]
Shahn—If you subtract one signal from another, then it will of course affect the resulting plot. Or did I misunderstand the intent of your question?
The background intensity ofcourse would affect the resultant histogram intensity plot, thus it would not tally with the real elemental concentrations in the image. By removing the background intensity image I am assuming one would be left with the actual element concentrations in the atomic image. Thus any imhist plot would give precise concentration measurements.
Do the functions imsubtract and strel have an affect on the resulting intensity and subsequently chanage the atomic image composition. ??????
I am finding some discrepencies in my imhist plot of the atomic image with the background removed???
Regards
You have above in your example how to find the x and y coordinates of your binary objects using pixellist ??? what if you had 100 columns and 100 rows what would be the best procedure to extract the x and y coordinates ???
Shahn—Comment 56: I do not understand enough about your application and data to give you a good answer, or really to even understand your question. Image subtraction and dilation/erosion would of course change the image intensity. What purpose is there in an image processing operation that has no effect on pixel values?
Comment 57: I would still use PixelList. Why not?
How much more coding would be required to the first example to output the x and y cordinates and the respective area for each letter?
Charlie—The following line computes the x- and y-coordinates and respective area for each connected component:
Note that some letters (for example, “i”) may have more than one connected component.
Hello Steve
Instead of superimposing a star on the image to show the centroide. How would you superimpose a numerical value of the centroide on the binary object ??? In my work this is more useful.
Regards Shahnawaz
Shahn—My November 17, 2006 post shows you how to do it.
Hi Steve,
I have an rgb image of a kind of cream and it contains some small black particles (black dots). In colormap I can see that black particles composed of 10-15 pixels (according to its size) and in grayscale usually they have a pixel value smaller than 100 (in 0-255). So first I want to label all particles in the image which have a average pixel value under 100, count them (how many dots in my image) and finally measure the approximate diameter of these dots. Thank you in advance Steve..
regards
Murat—Use rgb2gray, then threshold using the MATLAB < operator, and then label the objects using bwlabel. Use regionprops to compute measurements that might be useful in estimating the diameter (bounding box, area, perimeter, ellipse parameters).
I found this post useful for finding the intensity-weighted centroid of a gray scale image. However, I need to go one step further… is there a way to compute the intensity-weighted orientation of an object (or region) in a gray scale image?
Thanks,
Travis
Travis—What is your definition of intensity-weighted orientation? For “flat” (nonweighted) regions, regionprops defines object orientation as the orientation of the major axis of an ellipse that has the same second-order moments as the region. It’s not obvious to me how to extend this definition to a nonflat region.
I believe I found a solution… By using the gray scale pixel values for intensity, the calculations for uxx, uyy, and uxy are weighted. These parameters are then used to calculate orientation the same way regionprops does for binary images.
The part of the code in regionprops for the non-weighted case is:
I changed this to:
Where xbar and ybar are the intensity-weighted centroids (now available as an output from regionprops as “WeightedCentroid”) and sum_region is the sum of the gray level area. Hopefully my approach is correct… it seems to make sense on some test images.
It would be nice to have regionprops expanded to include more properties for grayscale images. Thanks for the input.
Travis—Your method sounds promising. Are there any specific grayscale properties you are particularly interested in? Thanks for your suggestions.
Just that intensity-weighted second moment (orientation)… for now! Thanks.
I have some separated blobs to detect. Each one should have a Gaussian shape. Usually the bwlabel works well but sometimes two blobs are found as 1 object when they should really be two objects.
What do you think to do about this? Could I detect that one feature has 2 peaks?
Thanks Matt
Matt—You might try looking at the marker-controlled watershed segmentation demo.