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?
problem with centroid of binary image
6 次查看(过去 30 天)
显示 更早的评论
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?
2 个评论
Image Analyst
2013-2-10
编辑:Image Analyst
2013-2-10
See my BlobsDemo tutorial : http://www.mathworks.com/matlabcentral/fileexchange/25157-image-segmentation-tutorial-blobsdemo, or see my demo program below.
采纳的回答
Walter Roberson
2013-2-10
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 个评论
Image Analyst
2013-2-11
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.
更多回答(1 个)
Image Analyst
2013-2-10
编辑:Image Analyst
2013-2-10
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 个评论
Image Analyst
2013-2-10
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.
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!