You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
Why am I getting different results when I ask to find the centroid of an image
2 views (last 30 days)
Show older comments
I have been using the following commands to find the centroid of a gray scale image derived from a color image in photoshop by changing the mode to gray scale:
grayImage = imread('2014-0825.jpg');
stats = regionprops(true(size(grayImage)), grayImage, 'WeightedCentroid');
centroid = stats.WeightedCentroid
previously I would get two numbers indicating the x and y pixels of the centroid Now using new images I get the results
centroid =
1.0e+03 *
1.2958 1.3177
What is this?
Answers (1)
Image Analyst
on 13 Nov 2015
You always (since R2008a) would get a 2 element array with the (x,y) or (column, row) of the weighted centroid. Nothing has changed. What two different results are you getting?
22 Comments
Image Analyst
on 13 Nov 2015
1.0e+03 *
1.2958 1.3177
is the same as [1295.8, 1317.7] - is that what you were confused about? Just how it's being formatted/displayed in the command window??? Try doing this
format long g
David Corwin
on 13 Nov 2015
I understand the decimal point change. what is 0e+03 and why is it that if I am using a different image but very similar image the program responds differently?
Image Analyst
on 13 Nov 2015
1.0e+03 is scientific notation for 1.0 times 10 to the 3 power, in other words 10^3 = 1000
David Corwin
on 13 Nov 2015
That makes sense but the program seems to have a mind of its own as to what notation it chooses.
A bigger problem is that the two dimensional centroid info is not only what I need. I need to find out where the center lies in the upper half and lower half relative to the whole image. To do this I have simply replaced one half of image (either top or bottom) by white pixels. This is somewhat cumbersome. What would be the matlab formula for an image of A by B pixels.
David Corwin
on 13 Nov 2015
I did not mean different results but the different expression of the same result. I take to different jpg images and out comes one result with a simple numerical result i.e. 1000 and the other image gives 1.0 1.0e+03
Image Analyst
on 13 Nov 2015
Edited: Image Analyst
on 13 Nov 2015
Don't let the value be spit out to the command window just by leaving off the semicolon. Use fprintf to write it out exactly as you want it:
fprintf('Centroid = (x, y) = (%.5f, %.5f)\n', centroid(1), centroid(2));
David Corwin
on 13 Nov 2015
Thank you very much for the help. Do you have any ideas about calculating the centroid of half the image?
Image Analyst
on 14 Nov 2015
Just maks a mask for half the image
grayImage = imread('2014-0825.jpg');
[rows, columns, numberOfColorchannels] = size(grayImage);
midRow = round(rows/2);
midCol = round(columns/2);
mask = false(rows, columns); % Initialize;
% Set upper half to true:
mask(1:midRow, :) = true;
stats = regionprops(mask, grayImage, 'WeightedCentroid');
centroidTopHalf = stats.WeightedCentroid
% Bottom half
mask = false(rows, columns); % Initialize;
% Set upper half to true:
mask(midRow+1:end, :) = true;
stats = regionprops(mask, grayImage, 'WeightedCentroid');
centroidBottomHalf = stats.WeightedCentroid
David Corwin
on 14 Nov 2015
When I set all the bottom half pixels to 255, i.e. the lower half is white, I get a different result than the above. What are you doing when you say "mask(1:midRow, :) = true;" ?
Image Analyst
on 14 Nov 2015
David, in that line I'm setting the entire top half of the mask to be true. What are the two results exactly? Give me the two (x,y) pairs so I can see why they are different, and show me how you computers the centroid (I already know how I did it.).
Here is a full blown demo with the centroids marked so you can see where they are in the top and bottom half:
% Compute the centroid of the top and bottom half of the image.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
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
%===============================================================================
% Read in a gray scale demo image.
folder = fileparts(which('moon.tif')); % Determine where demo folder is (works with all versions).
buttonText = menu('Use which demo image?', 'CameraMan', 'Moon', 'Eight', 'Coins', 'Pout');
if buttonText == 1
baseFileName = 'cameraman.tif';
elseif buttonText == 2
baseFileName = 'moon.tif';
elseif buttonText == 3
baseFileName = 'eight.tif';
elseif buttonText == 4
baseFileName = 'coins.png';
else
baseFileName = 'pout.tif';
end
% 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
% Read in image.
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.
imshow(grayImage, []);
axis on;
title('Original Grayscale Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Get rid of tool bar and pulldown menus that are along top of figure.
set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
midRow = round(rows/2);
midCol = round(columns/2);
% Put a line dividing the two
hold on;
line([1, columns], [midRow, midRow], 'Color', 'y', 'LineWidth', 2);
mask = false(rows, columns); % Initialize;
% Set upper half to true:
mask(1:midRow, :) = true;
stats = regionprops(mask, grayImage, 'WeightedCentroid');
centroidTopHalf = stats.WeightedCentroid
% Plot the centroid in the top half
plot(centroidTopHalf(1), centroidTopHalf(2), 'r+', 'MarkerSize', 30, 'LineWidth', 2);
message = sprintf('Centroid at (%.1f, %.1f)', centroidTopHalf(1), centroidTopHalf(2));
text(centroidTopHalf(1)+10, centroidTopHalf(2)-10, message, 'Color', 'r', 'FontSize', fontSize);
% Bottom half
mask = false(rows, columns); % Initialize;
% Set upper half to true:
mask(midRow+1:end, :) = true;
stats = regionprops(mask, grayImage, 'WeightedCentroid');
centroidBottomHalf = stats.WeightedCentroid
% Plot the centroid in the bottom half
hold on;
plot(centroidBottomHalf(1), centroidBottomHalf(2), 'r+', 'MarkerSize', 30, 'LineWidth', 2);
message = sprintf('Centroid at (%.1f, %.1f)', centroidBottomHalf(1), centroidBottomHalf(2));
text(centroidBottomHalf(1)+10, centroidBottomHalf(2)-10, message, 'Color', 'r', 'FontSize', fontSize);
David Corwin
on 14 Nov 2015
There are several observations: 1.) The image I am talking about is a matrix of x y values and numbers from 1-255. As such one can think of it as an object with varying density points. Is a weighted centroid the center of gravity of this object? 2.) so that you should understand where I am coming from, the project I am working on is an attempt to objectify the qualities of an image that induces a certain type of eye movement when it is perfectly balanced. But what is meant by "perfectly balanced"? For the last century it has been assumed that it means a weighted balance of color or tonal density, but no one has been able to prove it. Based on preliminary work from the determination of a weighted centroid (as I conceived it above), it appears that the eye/mind does not work that way. I will explain more after your response
Image Analyst
on 14 Nov 2015
For 1, yes, an image is a 2D array of varying density points. The weighted centroid is like the unweighted centroid but the unweighted centroid just looks at where the pixels are and does not care about their value (brightness). A weighted centroid is like a center of gravity but it's really not gravity if the images represent reflectivity rather than mass.
I'm not familiar with the "perfectly balanced" concept in the context of eye movements. I don't know what you'd have to do to an image to induce certain types of eye movements.
David Corwin
on 15 Nov 2015
The basic problem can be simply described as a what does a painter mean when he or she looks at a painting and decides that it looks finished or not. What is meant by good composition? There are a variety of answers over the last five hundred years but I am concerned with just the pure visual one irrespective of subject, etc as in an abstract painting. Weighted balance has been described as the key to this, and there have been a lot of papers that have tried to prove this. Curiously none of the psychologists involved were very sophisticated and either didn't use a mathematical method of determining the center of an image or an overly simplified image. As a result of this weighted centroid study, I can say that there appears to be no simple weighted point of balance. The key to it is a simple tonal balance of quadrants with various qualifications.
Could you provide me with a formula that gives the mean luminance of each quadrant as in just providing the L value of each point without attaching significance to its xy coordinants. I think that is what is done in photoshop when it gives the mean luminosity of a circumscribed area but it is cumbersome. In addition because it is a possibility, could you provide a formula treating each quadrant as a blob with a center of gravity so as to arrive at four COGs for each image and then following that the center of gravity of the four quadrants. I can't see how the eye sums up a picture this way, but one never knows. I suggest you look up smooth pursuit vision in wikipedia. I intend to prove that it is possible with a correctly balanced picture under specific conditions to do this with a picture. It is in general almost impossible for us to move our eyes using smooth pursuit without a moving object. I appreciate your help very much and will provide acknowledgements when this gets published.
Image Analyst
on 15 Nov 2015
See my attached blockproc demos. One of them shows how to compute the means in blocks of specified size. I think they're instructive so I've left everything in there. If they're too complicated and you need me to simplify it for you, let me know.
Transform your images from RGb to CIELAB with rgb2lab() function and use the L channel. Or use rgb2hsv() and use the V channel. Of course I hope you know that (like Photoshop) those are only "book formulas" and not a real calibration because basically you can get any RGB you want from your image just by changing your camera settings, such as exposure. So even though the LAB of your scene doesn't change, you can make the RGB change and thus the L channel in MATLAB, unless you do a sophisticated color calibration (like I do).
I'm not sure what weighted balance is in an artistic sense, but if it means that lighter pixels are "heavier" and move the centroid towards them, then WeightedCentroid may be what you want.
David Corwin
on 19 Jan 2016
Image analyst: if you want an appreciation of help, mail me at dcorwin@dcorwin.org. I did find the above too complicated. I am concerned with the computer images. For me every image is visually a different image. It would be nice to calculate the mean luminosity of each quadrant of a jpg image. for example image 500x500 pixels. mean luminosity 1-250x 1-250 = ULQ, 250-500 x 1-250 = URQ, etc.
Image Analyst
on 19 Jan 2016
Edited: Image Analyst
on 20 Jan 2016
I don't think you mean luminosity - I think you mean average gray level. To do that, split your image up into individual color channels if you want and then use mean2(). Or if you want the mean gray level of the gray level version of the image, use rgb2gray() followed by mean2()
grayImage = rgb2gray(rgbImage);
[rows, columns] = size(grayImage);
row1 = round(rows/2);
col1 = round(columns/2);
meanUpperLeft = mean2(grayImage(1:row1, 1:col1));
meanUpperRight = mean2(grayImage(1:row1, col1+1:end));
meanLowerLeft = mean2(grayImage(row1+1:end, 1:col1));
meanLowerRight = mean2(grayImage(row1+1:end, col1+1:end));
David Corwin
on 20 Jan 2016
Edited: Image Analyst
on 20 Jan 2016
When I enter:
RGB = imread('miro3.jpg')
grayImage = rgb2gray(RGB);
[rows, columns] = size(grayImage);
row1 = round(rows/2);
col1 = round(columns/2);
meanUpperLeft = mean2(1:row1, 1:col1);
meanUpperRight = mean2(1:row1, col1+1:end);
meanLowerLeft = mean2(row1+1:end, 1:col1);
meanLowerRight = mean2(row1+1:end, col1+1:end);
Matlab gives me rows of gray levels and I am forced to stop it
Image Analyst
on 20 Jan 2016
You forgot to put the semicolon after the imread() line so it's printing all the values to the command window. Put a semicolon there like I did.
David Corwin
on 20 Jan 2016
RGB = imread('miro3.jpg'); grayImage = rgb2gray(RGB); [rows, columns] = size(grayImage); row1 = round(rows/2); col1 = round(columns/2); meanUpperLeft = mean2(1:row1, 1:col1); meanUpperRight = mean2(1:row1, col1+1:end); meanLowerLeft = mean2(row1+1:end, 1:col1); meanLowerRight = mean2(row1+1:end, col1+1:end); Error using mean2 Too many input arguments.
Image Analyst
on 20 Jan 2016
Pass the image name into mean2():
grayImage = rgb2gray(rgbImage);
[rows, columns] = size(grayImage);
row1 = round(rows/2);
col1 = round(columns/2);
meanUpperLeft = mean2(grayImage(1:row1, 1:col1));
meanUpperRight = mean2(grayImage(1:row1, col1+1:end));
meanLowerLeft = mean2(grayImage(row1+1:end, 1:col1));
meanLowerRight = mean2(grayImage(row1+1:end, col1+1:end));
Image Analyst
on 21 Jan 2016
David's "Answer" moved here since it's not an answer to the original question:
Thanks that does it. answer comes out on the Workspace.
Image Analyst
on 21 Jan 2016
You're welcome David. Can you go ahead and mark the Answer as "Accepted" then? Thanks in advance.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)