Find the barycenter of luminance in an image

I need to find the weighted center of luminosity of barycenter in an image. (the weighted L center in Lab a b)

2 Comments

The image is an rgb image that is converted to an L*A*B* image. (I could just start with a gray scale image) For each pixel there is an L (value 1-100)multiplied by the distance to geometric center. The sum of all this should be the luminosity center or tonal center of the image or using tonal value as weight: the center of mass of the picture.

Sign in to comment.

 Accepted Answer

Image Analyst
Image Analyst on 29 Oct 2015
Edited: Image Analyst on 29 Oct 2015
Since R2008a (or maybe b) regionprops has had a "WeightedCentroid" property that you can ask for. So pass in the L channel and ask for that if you want the centroid weighted by the L value.
If you want it weighted by the distance, that's the inertia or moment. See https://en.wikipedia.org/wiki/Image_moment I don't think there's anything built in for that but you can ask for the PixelList which is the location of every pixel in the blob and you can easily calculate it yourself.

6 Comments

I am very slowly learning command syntax. for a gray scale image.jpg, how would you use the "WeightedCentroid" command? What is the difference with a simple centroid command?
What I want is for a given gray scale 'image.jpg', to obtain both the upper and lower quadrant balance (gray scale value x distance to geometric center) and a upper half/lower half balance. That is three symmetry values.
thank you very much for your help.
imageprops = regionprops(L, 'WeightedCentroid');
result = imageprops.WeightedCentroid;
Note: there is no such thing as a gray scale .jpg image. JPEG images are always RGB. They might be RGB with all three channels the same and so might appear grayscale, but they are are actually RGB.
So I enter
A = imread('figure2.jpg');
imageprops = regionprops(L, 'WeightedCentroid');
result = imageprops.WeightedCentroid;
and get
Undefined function or variable 'L'.
Thank you for your help, What is "L"
David: L is the labeled image. He just gave you a snippet, assuming you would know what to do. You have to call bwlabel on your binary image
L = bwlabel(binaryImage);
If you're still confused, then see my well commented Image Segmentation Tutorial in my File Exchange: http://www.mathworks.com/matlabcentral/fileexchange/?term=authorid%3A31862
And don't forget to see my spatial moment demo (my other answer here). I'm still not sure if you want spatial moments or radiometric moments - you're being very tight lipped about it for some reason.
I will look at your demo. I am sorry to be confusing but it is partially due to terminology. I want to obtain the tonal center of gravity for a variety of images. I have a theory concerning how to achieve perfect pictorial composition and its effects on eye movements. i.e. why pictures can have a powerful effect as pictures. This is only the first half necessary to study eye movements.
No, L is not the label matrix here. L is the luminance channel, in accordance with IA's earlier "So pass in the L channel and ask for that if you want the centroid weighted by the L value."
A = imread('figure2.jpg');
LAB = rgb2lab(A);
L = LAB(:,:,1);
imageprops = regionprops(L, 'WeightedCentroid');
result = imageprops.WeightedCentroid;
If you want the "top half" then pass in the top half,
imageprops = regionprops(L(1:end/2,:), 'WeightedCentroid');
upperCent = imageprops.WeightedCentroid;
imageprops = regionprops(L(ceil(end/2):end,:), 'WeightedCentroid');
lowerCent = imageprops.WeightedCentroid;

Sign in to comment.

More Answers (1)

David:
I wrote a demo for you to compute the first 5x5 central spatial moments, as given by the Wikipedia page https://en.wikipedia.org/wiki/Image_moment. See attached m-file. The key code is this:
% Sum up the powers of the gray levels, weighted by the distance from the centroids.
% Ref: https://en.wikipedia.org/wiki/Image_moment
highestMomentNumber = 5;
mu = zeros(highestMomentNumber, highestMomentNumber); % Allocate up to 5 moment (probably way overkill).
for q = 1 : size(mu, 2) % in the column, x direction.
for p = 1 : size(mu, 1) % in the row, y direction
for location = 1 : length(allX)
% For every pixel in this blob....
% Sum up for moment "mu sub pq" - i.e. the pqth moment.
thisGrayLevel = grayImage(allY(location), allX(location));
mu(p, q) = mu(p, q) + ...
(allX(location) - xCenter).^q * ...
(allY(location) - yCenter).^p * ...
double(thisGrayLevel);
end
end
end
See file for a complete demo.

6 Comments

So for an image 540x750 uint8
I substitute 750 for length(allX)
and 540 for length(allY) but what is xCenter, yCenter
A = imread('figure2.jpg');
highestMomentNumber = 5;
mu = zeros(highestMomentNumber, highestMomentNumber);
for q = 1 : size(mu, 2) % in the column, x direction.
for p = 1 : size(mu, 1) % in the row, y direction
for location = 1 : length(750)
% For every pixel in this blob....
thisGrayLevel = A (540), (750);
mu(p, q) = mu(p, q) + ...
(750(location) - xCenter).^q * ...
(540(location) - yCenter).^p * ...
double(thisGrayLevel);
end
end
end
No, David, that's not right. Don't change my code like that - the number of pixels in allX is the number of pixels in each blob, not the number of columns in your entire image. They're completely different things!
I must confess I do not understand a thing. Why does a simple image with one variable luminance have to be broken down into multiple blobs to my the center
It doesn't. We thought (mistakenly) you had some region(s) identified, which is the most common situation. If your region is the entire image, then you can just do this:
grayImage = imread('cameraman.tif');
stats = regionprops(true(size(grayImage)), grayImage, 'WeightedCentroid');
centroid = stats.WeightedCentroid
Thank you very much for the solution. However, I can see the reason for the confusion.
take a rectangular image with each pixel having a tonal value. The picture is being suspended on the wall at its geometric center. In this situation light values exert a conceptual upward force while dark values exert a downward force
Now the upper left and right quadrants have a weight relative to the center which can cause the picture to spin.
Likewise, with the lower left and right quadrants
The center of gravity does not tell me the relative balance of the upper right and left quadrants. The center of gravity of each quadrant would place equal value on what would be interior pixels that should have relatively no value
It seems to me that I need an upper half center of balance relative to the vertical median such that values closer to the upper right and left edges have a greater weight relative to the geometric center
In a more sophisticated setup, this type of situation is found in airplanes
I hope I am explaining the problem clearly. Ultimately this will be part of a paper I am hoping to publish and I would be happy to give you credit.
Thanks for all your help. I figured out the solution to the above by simply placing 1 or 255 in what ever part of the image I do not want to be included.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!