# problem with centroid of binary image

12 views (last 30 days)

Show older comments

##### 2 Comments

Image Analyst
on 10 Feb 2013

Edited: Image Analyst
on 10 Feb 2013

### Accepted Answer

Walter Roberson
on 10 Feb 2013

Note that if your "binary array" is a numeric datatype, with 0's and 1's, rather than a logical array (false and true's), then regionprops will treat the numeric array as if it is a labeled array that happens to contain only one label. To avoid that, call bwlabel() to separate out the blobls.

labelarray = bwlabel(not_really_binary_Image));

measurements = regionprops(labelarray, 'Centroid');

then measurements will be a struct array with the field 'Centroid' for each blob. Each of the 'Centroid' fields will be a vector whose length matches the dimension of the image (usually 2).

##### 11 Comments

Image Analyst
on 11 Feb 2013

### More Answers (1)

Image Analyst
on 10 Feb 2013

Edited: Image Analyst
on 10 Feb 2013

regionprops returns a structure array. Each element in the array is a structure with all the measurements for that one blob. Centroid or WeightedCentroid might be one of those measurements, if you asked regionprops to calculate it. It will be a 2 element array. For example, for blob #k,

measurements = regionprops(binaryImage, 'Centriod');

theCentroid = measurements(k).Centroid; % for blob #k only

Perhaps this demo will help:

% Demo to have the user freehand draw an irregular shape over

% a gray scale image, have it extract only that part to a new image,

% and to calculate the mean intensity value of the image within that shape.

% Also calculates the perimeter, centroid, and center of mass (weighted centroid).

% Change the current folder to the folder of this m-file.

if(~isdeployed)

cd(fileparts(which(mfilename)));

end

clc; % Clear command window.

clear; % Delete all variables.

close all; % Close all figure windows except those created by imtool.

imtool close all; % Close all figure windows created by imtool.

workspace; % Make sure the workspace panel is showing.

fontSize = 16;

% Read in a standard MATLAB gray scale demo image.

folder = fullfile(matlabroot, '\toolbox\images\imdemos');

baseFileName = 'cameraman.tif';

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

fullFileName = baseFileName; % No path this time.

if ~exist(fullFileName, '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

grayImage = imread(fullFileName);

imshow(grayImage, []);

axis on;

title('Original Grayscale Image', 'FontSize', fontSize);

set(gcf, 'Position', get(0,'Screensize')); % Maximize figure.

message = sprintf('Left click and hold to begin drawing.\nSimply lift the mouse button to finish');

uiwait(msgbox(message));

hFH = imfreehand();

% Create a binary image ("mask") from the ROI object.

binaryImage = hFH.createMask();

xy = hFH.getPosition;

% Now make it smaller so we can show more images.

subplot(2, 3, 1);

imshow(grayImage, []);

axis on;

drawnow;

title('Original Grayscale Image', 'FontSize', fontSize);

% Display the freehand mask.

subplot(2, 3, 2);

imshow(binaryImage);

axis on;

title('Binary mask of the region', 'FontSize', fontSize);

% Label the binary image and computer the centroid and center of mass.

labeledImage = bwlabel(binaryImage);

measurements = regionprops(binaryImage, grayImage, ...

'area', 'Centroid', 'WeightedCentroid', 'Perimeter');

area = measurements.Area

centroid = measurements.Centroid

centerOfMass = measurements.WeightedCentroid

perimeter = measurements.Perimeter

% Calculate the area, in pixels, that they drew.

numberOfPixels1 = sum(binaryImage(:))

% Another way to calculate it that takes fractional pixels into account.

numberOfPixels2 = bwarea(binaryImage)

% Get coordinates of the boundary of the freehand drawn region.

structBoundaries = bwboundaries(binaryImage);

xy=structBoundaries{1}; % Get n by 2 array of x,y coordinates.

x = xy(:, 2); % Columns.

y = xy(:, 1); % Rows.

subplot(2, 3, 1); % Plot over original image.

hold on; % Don't blow away the image.

plot(x, y, 'LineWidth', 2);

drawnow; % Force it to draw immediately.

% Burn line into image by setting it to 255 wherever the mask is true.

burnedImage = grayImage;

burnedImage(binaryImage) = 255;

% Display the image with the mask "burned in."

subplot(2, 3, 3);

imshow(burnedImage);

axis on;

caption = sprintf('New image with\nmask burned into image');

title(caption, 'FontSize', fontSize);

% Mask the image and display it.

% Will keep only the part of the image that's inside the mask, zero outside mask.

blackMaskedImage = grayImage;

blackMaskedImage(~binaryImage) = 0;

subplot(2, 3, 4);

imshow(blackMaskedImage);

axis on;

title('Masked Outside Region', 'FontSize', fontSize);

% Calculate the mean

meanGL = mean(blackMaskedImage(binaryImage));

% Put up crosses at the centriod and center of mass

hold on;

plot(centroid(1), centroid(2), 'r+', 'MarkerSize', 30, 'LineWidth', 2);

plot(centerOfMass(1), centerOfMass(2), 'g+', 'MarkerSize', 20, 'LineWidth', 2);

% Now do the same but blacken inside the region.

insideMasked = grayImage;

insideMasked(binaryImage) = 0;

subplot(2, 3, 5);

imshow(insideMasked);

axis on;

title('Masked Inside Region', 'FontSize', fontSize);

% Now crop the image.

leftColumn = min(x);

rightColumn = max(x);

topLine = min(y);

bottomLine = max(y);

width = rightColumn - leftColumn + 1;

height = bottomLine - topLine + 1;

croppedImage = imcrop(blackMaskedImage, [leftColumn, topLine, width, height]);

% Display cropped image.

subplot(2, 3, 6);

imshow(croppedImage);

axis on;

title('Cropped Image', 'FontSize', fontSize);

% Put up crosses at the centriod and center of mass

hold on;

plot(centroid(1)-leftColumn, centroid(2)-topLine, 'r+', 'MarkerSize', 30, 'LineWidth', 2);

plot(centerOfMass(1)-leftColumn, centerOfMass(2)-topLine, 'g+', 'MarkerSize', 20, 'LineWidth', 2);

% Report results.

message = sprintf('Mean value within drawn area = %.3f\nNumber of pixels = %d\nArea in pixels = %.2f\nperimeter = %.2f\nCentroid at (x,y) = (%.1f, %.1f)\nCenter of Mass at (x,y) = (%.1f, %.1f)\nRed crosshairs at centroid.\nGreen crosshairs at center of mass.', ...

meanGL, numberOfPixels1, numberOfPixels2, perimeter, ...

centroid(1), centroid(2), centerOfMass(1), centerOfMass(2));

msgbox(message);

##### 2 Comments

Image Analyst
on 10 Feb 2013

### See Also

### Categories

### Products

### Community Treasure Hunt

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

Start Hunting!