Steve on Image Processing

August 31st, 2007

Intensity-weighted centroids

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

63 Responses to “Intensity-weighted centroids”

  1. Daphne replied on :

    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

  2. Steve replied on :

    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:

    imshow(I, [])
    

    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.

  3. suwanna replied on :

    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

  4. Steve replied on :

    Suwanna—You might try using the function graythresh.

  5. Chaitanya replied on :

    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.

  6. Steve replied on :

    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).

  7. suwanna replied on :

    Hello Steve
    Thanks very much .
    i will try to read it.
    Regards
    suwanna

  8. Tariq replied on :

    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.

  9. Steve replied on :

    Tariq—You might want to try a morphological closing step (imclose) prior to calling bwareaopen.

  10. Vipul Gupta replied on :

    Thanks Steve. It works great.

  11. k chaitanya replied on :

    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.

  12. Steve replied on :

    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.

  13. k chaitaya replied on :

    THANK YOU
    STEVE

  14. Ana replied on :

    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?

  15. Steve replied on :

    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.

  16. sylvia replied on :

    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..

  17. Lakshmi replied on :

    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

  18. Steve replied on :

    Sylvia—This post contains code and explanations for computing centroids.

  19. Steve replied on :

    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.

  20. Lakshmi replied on :

    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

  21. sylvia replied on :

    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.

  22. Steve replied on :

    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.

  23. Shahnawaz Hussain replied on :

    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.

  24. Mj replied on :

    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?

  25. Steve replied on :

    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.

  26. Steve replied on :

    Mj—MajorAxisLength and MinorAxisLength give you no information about the location of an object in an image.

  27. Mj replied on :

    Then what are the properties (other than centroid) that could give me information about the location of an object in an image?

  28. Steve replied on :

    Mj—See the documentation for regionprops.

  29. Shahnawaz replied on :

    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

  30. Steve replied on :

    Shahnawaz—Extract the x and y coordinates of what? And what is an image of X and Y coordinates?

  31. Shahnawaz replied on :

    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

  32. Steve replied on :

    Shahnawaz—You just repeated your question. I still don’t understand it.

  33. Shahnawaz replied on :

    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.

  34. Steve replied on :

    Shahnawaz—Try meshgrid.

  35. Suzie replied on :

    Dear steve

    How can I find MaxIntensity,MeanIntensity from regionprops for grayscale image?

  36. Steve replied on :

    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.

  37. Josh replied on :

    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

  38. Steve replied on :

    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.

  39. patil rajendra V. replied on :

    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

  40. Steve replied on :

    Patil—Use regionprops.

  41. shah replied on :

    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)

  42. shah replied on :

    Dear Steve

    How can I display the xy coordinates on the binary objects ????

  43. Steve replied on :

    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.

  44. shaz replied on :

    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 ???

  45. Steve replied on :

    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.

  46. DP replied on :

    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

  47. Steve replied on :

    DP—Use regionprops to compute the centroids, and then use hypot to compute the distances between the centroids.

  48. DP replied on :

    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

  49. DP replied on :

    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)

  50. Steve replied on :

    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.

  51. DP replied on :

    Thanks steve.

  52. Yuanming replied on :

    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

  53. Steve replied on :

    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.

  54. shahn replied on :

    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]

  55. Steve replied on :

    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?

  56. shahn replied on :

    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

  57. shahn replied on :

    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 ???

  58. Steve replied on :

    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?

  59. Charlie replied on :

    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?

  60. Steve replied on :

    Charlie—The following line computes the x- and y-coordinates and respective area for each connected component:

    s = regionprops(L, 'PixelList', 'Area');
    

    Note that some letters (for example, “i”) may have more than one connected component.

  61. shahn replied on :

    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

  62. Steve replied on :

    Shahn—My November 17, 2006 post shows you how to do it.

  63. murat replied on :

    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

Leave a Reply

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>

If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).


Steve Eddins manages the Image & Geospatial development team at The MathWorks and coauthored Digital Image Processing Using MATLAB. He writes here about image processing concepts, algorithm implementations, and MATLAB.

  • murat: Hi Steve, I have an rgb image of a kind of cream and it contains some small black particles (black dots). In...
  • Steve: Ernest—Look at setting the FaceColor property. The code for setting that is shown on the page you asked...
  • Ernest Miller: Hi Steve, Understood. However, can you explain how to change the colors? Thanks, Ernest
  • Jan: Hi Steve Very useful code, yet what if I parts of my rotated+translated object are outside the original...
  • Steve: MoHDa—It might be possible. You’ll need to use one of the options that produces closed edge...
  • MoHDa: I have one question about the ROIPOLY: I have an image with stripes, I use the “edge” command for...
  • Steve: Shahn—My November 17, 2006 post shows you how to do it.
  • Steve: Kay-Uwe—Thanks for following up. I am planning to make it easier to use test directories in a package....
  • shahn: Hello Steve Instead of superimposing a star on the image to show the centroide. How would you superimpose a...
  • Kay-Uwe: Having TestSuite.fromPackag e() would be nice to have, but so far using simple “test” subdirs...

These postings are the author's and don't necessarily represent the opinions of The MathWorks.