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

Learn moreOpportunities for recent engineering grads.

Apply Today
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

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.

## 2 Comments

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?

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.