Asked by nadia naji
on 10 Feb 2013

hi i use bwconncomp and regionprob with centroid feature to find centroid of binary image but i cant understand one thing? if i use centroid feature, it return one point or a structure of points? when i use this i have a structure of point that i think it is wrong do you have any idea?

Answer by Walter Roberson
on 10 Feb 2013

Accepted answer

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

Show 8 older comments

Image Analyst
on 11 Feb 2013

Please post your image. I don't like working "blind."

nadia naji
on 11 Feb 2013

thanks a lot it works by using double i really appreciate your help

Image Analyst
on 11 Feb 2013

How did you end up with a double? That's not normally the case. Usually you process the image to a point where you can threshold it and get a binary image. You said you had a binary image (logical) but now you say you have a double image. Something's weird.

Answer by Image Analyst
on 10 Feb 2013

Edited by 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);

nadia naji
on 10 Feb 2013

excuse me i cant understand some things i need to have one centroid for objects in image not structure of several centroid because i need to consider the movement of centroids in sequential frame? do you understand what i need? i need centroid of whole image please help me

Image Analyst
on 10 Feb 2013

Nadia, if this is in a loop over frames, just extract the centroids (x_centroids and y_centroids) from the structure. Make x_centroids and y_centroids arrays that depend on the frame. So if you have 300 frames, x_centroids is an array of 300 x centroids. Then you can do mean_x_centroid = mean(x_centroids). It becomes more complicated if there are different numbers of blobs in each frame - then it becomes essentially a tracking problem, which is more complicated because you have to account for blobs coming into the field of view and blobs leaving the field of view.

Related Content

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn moreOpportunities for recent engineering grads.

Apply Today
## 2 Comments

## nadia naji (view profile)

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/62938#comment_128521

i need to consider the behavior of centroid of binary image (with several object in that image ) in sequential frame of video and show them the number of object can be different in each frame. how can i do it? pls help me?

## Image Analyst (view profile)

Direct link to this comment:http://www.mathworks.com/matlabcentral/answers/62938#comment_128524

See my BlobsDemo tutorial : http://www.mathworks.com/matlabcentral/fileexchange/25157-image-segmentation-tutorial-blobsdemo, or see my demo program below.