how to extract boundaries of connected components and display one by one

Hellow Everyone.
I preprocessed my image and got connected components now i want to only extract boundaries of that connected components and want to display them one by one on screen and i also want to find out their centers and then distance from center to the end points of that connected components.
i used regionprops, bwboundaries and bwlabel but i cant do it, may be i m doing some kind of mistake please help me out of doing all these above mentioned tasks. it will be heighly appricated.

7 Comments

please help me out in finding the distance from center to end points/extreme points of an object/connected component (to obtain star skeleton).
the resluts i want is attached in image.
Have a read here and here. It will greatly improve your chances of getting an answer. Also, flags shouldn't be used for comments, see this page.
Image processing without the image tends to be difficult.
Rik Did you have any idea how i would solved my above mention problem. please help me out in finding the distance from center to end points/extreme points of an object/connected component (to obtain star skeleton).
Youd obviously did not read the advice in the thread I linked, so why should I bother spending time on your problem if you are going to ignore my advice.
Prove me wrong and I will try to help you.
i find the center of connected components like this
% Find centroid.
labeledImage = bwlabel(individualsilheouts);
measurements = regionprops(labeledImage, 'Centroid');
xCentroid = measurements.Centroid(1);
yCentroid = measurements.Centroid(2);
figure(objectidx1+1);subplot(1,2,1);
imshow(individualsilheouts);
hold on;
plot(xCentroid, yCentroid, 'r.', 'MarkerSize', 04, 'LineWidth', 1);
now i wish to calculate the distance from that center to 5 edge points (extreme points) and plot that distance by drawing line (attached image is the desired result)
Rik if you know how can i perform the above task then your help is realy appricated otherwise no more debate and just ignore this.
I'm fine with ignoring your question, but then I don't really get why you posted it in the first place. If everybody should ignore your post, why did you post it?
Anyway, since you have x and y values, you can use a function like pdist, or calculate all pair-wise differences in a loop. Since you didn't share any input data, I can't give you concrete advice.
Are the connected components the white blobs inside the black outline? If so, you really don't want the huge white surround going all the way out to the edge of the image do you?

Sign in to comment.

Answers (1)

Try this:
% Demo to find centroid of blobs and draw a line from the centroid to the farthest boundary point.
% By Image Analyst
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 = 22;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'Screenshot (125).png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
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
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage);
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Use weighted sum of ALL channels to create a gray scale image.
grayImage = rgb2gray(grayImage);
% ALTERNATE METHOD: Convert it to gray scale by taking only the green channel,
% which in a typical snapshot will be the least noisy channel.
% grayImage = grayImage(:, :, 2); % Take green channel.
end
% Display the image.
subplot(2, 2, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
hFig = gcf;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
%--------------------------------------------------------------------------------------------------------
% SEGMENTATION OF IMAGE
% Get a binary image
binaryImage = imbinarize(grayImage);
% Get rid of huge white frame surrounding the image the user posted.
binaryImage = imclearborder(binaryImage);
subplot(2, 2, 2);
imshow(binaryImage, []);
impixelinfo;
title('Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
%--------------------------------------------------------------------------------------------------------
% CONNECTED COMPONENTS LABELING
se = strel('disk', 1, 0);
% Label each blob with 8-connectivity, so we can make measurements of it
[labeledImage, numberOfBlobs] = bwlabel(binaryImage, 4);
subplot(2, 2, 3);
imshow(labeledImage, []);
impixelinfo;
title('Labeled Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
% Apply a variety of pseudo-colors to the regions.
coloredLabelsImage = label2rgb (labeledImage, 'hsv', 'k', 'shuffle');
% Display the pseudo-colored image.
subplot(2, 2, 4);
imshow(coloredLabelsImage);
title('Pseudocolored Labeled Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
%--------------------------------------------------------------------------------------------------------
% MEASUREMENT OF CENTROIDS.
props = regionprops(labeledImage, 'Centroid');
xy = vertcat(props.Centroid);
xCentroid = xy(:, 1);
yCentroid = xy(:, 2);
%--------------------------------------------------------------------------------------------------------
% MEASUREMENT OF BOUNDARIES
boundaries = bwboundaries(binaryImage, 4);
hold on;
for k = 1 : length(boundaries)
thisBoundary = boundaries{k};
x = thisBoundary(:, 2);
y = thisBoundary(:, 1);
plot(xCentroid(k), yCentroid(k), 'r*');
% Find distances
distances = sqrt((xCentroid(k) - x) .^ 2 + (yCentroid(k) - y) .^ 2);
% Find out which boundary point is the farthest from the centroid.
[maxDistance, indexOfMax] = max(distances);
xFar = x(indexOfMax);
yFar = y(indexOfMax);
% Draw a line between them.
line([xCentroid(k), xFar], [yCentroid(k), yFar], 'Color', 'y', 'LineWidth', 2);
end
See the yellow lines going from each blob's centroid to the farthest point on the boundary.

9 Comments

@Image Analyst first of all thanx alote for your precious reply.
actually the image i attached was not the input image, that was the desired image that i want. my input image was this Screenshot (131).png (attached). i found the center of each connected components as i showed in my attached image.
Problem: i want to extract each connected component one by one and draw a line from center to five (5) extreme points and also plot that distances. The result i want are attached in image Screenshot (125).png and Screenshot (132).png
i used your above provided code but that only draw the one line and in some connected components it doesn't draw even a single line.lke i showed in attached images 127,128,129,130
so far i made this code but doesn't work as i desired. plz help me out your help is realy appricated
bw=bwlabel(closezn);
CC1 = bwconncomp(bw); %// Find connected components.
L51 = labelmatrix(CC1);
%to display all the silheouts
for objectidx1 = 1:CC1.NumObjects
individualsilheouts = bsxfun(@times, closezn, L51 == objectidx1); %requires R2016b or later. earlier versions: maskedimage = bsxfun(@times, A, L == objectidx);
boundaries = bwboundaries(individualsilheouts);
numberOfBoundaries = size(boundaries, 1);
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k};
%plot(thisBoundary(:,2), thisBoundary(:,1), 'r', 'LineWidth', 1);
end
x = thisBoundary(:, 2);
y = thisBoundary(:, 1);
% Find centroid.
labeledImage = bwlabel(individualsilheouts);
measurements = regionprops(labeledImage, 'Centroid');
xCentroid = measurements.Centroid(1);
yCentroid = measurements.Centroid(2);
figure(objectidx1+1);subplot(1,2,1);
imshow(individualsilheouts);
hold on;
plot(xCentroid, yCentroid, 'r.', 'MarkerSize', 04, 'LineWidth', 1);
% Find distances.
distances = sqrt((x-xCentroid).^2 + (y-yCentroid).^2);
subplot(1, 2, 2);
plot(distances, 'b-', 'LineWidth', 1);
grid on;
title('Distances', 'FontSize', 10);
% Find farthest endpoints.
[peakDistances, peakIndexes] = findpeaks(distances, 'MinPeakProminence', 5);
% Plot peaks
hold on;
for k = 1 : length(peakIndexes)
thisIndex = peakIndexes(k);
line([thisIndex, thisIndex], [0, distances(thisIndex)], 'Color', 'g', 'LineWidth', 1);
distances3 = sqrt((x(thisIndex)-xCentroid).^2 + (y(thisIndex)-yCentroid).^2);
subplot(1, 2, 1);
plot([xCentroid, x(thisIndex)], [yCentroid, y(thisIndex)], 'r-', 'LineWidth', 1);
%line([thisIndex, thisIndex], [0, distances(thisIndex)], 'Color', 'g', 'LineWidth', 1);
end
That doesn't look too robust. I suggest you look at openpose instead. Google it.
image Analyst i want you to help me in finding the extreme points of connected components how do i find the five extreme points of connected components and then their distance from center plz help me out if you know how to do that.
For the most general type of blob, it could be difficult and I'm not taking on private consulting contracts now. So that's why I told you to look at openpose where very smart people have spent years solving the problem. If you don't want to do that then about all I can suggest is that you look at my shape recognition demos. One of them uses findpeaks() to determine the polygon.
Image Analyst i read one of your answer on a question asked by some member actually that Question is similar to mine one. on answering that question you asked him to use bwboundaries and then convhell(). I used both of them but i still need your help in fixing that code. plz help me out in fixing that code to solve my problem as well. thanx
waiting for your response plz
He asked how to get the extremum points and using convhull() will return those. However there is a problem with that. For example, you could have an arm of a star that is too short to be on the convex hull. Or you could have multiple points that are completely adjacent to each other. In that case, you'd probably just want the middle point. If you had 20 points and wanted the 5 extrema then it might identify all 5 that are in an adjacent part and not give you the other 4 that are widely spaced from those. So there are some problems with that method. The findpeaks() method is more robust than that. But findpeaks() is tricky - just look at the diagram with all the different kinds of peaks you find. You have to tweak all those parameters to get the kinds of peaks that you want. I'd do no better at that than you. Plus, once you have found valid peaks, you have to find the "best" 5 (if you want only 5). And that could be a whole other set of rules. It's a lot of work. Work that the openpose people have probably already worked through.
hi Image Analyst thanx for your help and support i somehow mange to find the 4 extreme ponts now the only point remains is left leg point
actually i need your help in "how to find the white pixel that has minimum x and minmum y cordinates." i want to point out the position of that pixel that is represented by minimum x and minimum y cordinate. what i want to say is explained in attach figure.plz give a suggestion how i code this to achive my goal or how i will have to run the loop for desired goal.
plz help me out image analyst.
That's not well defined. You might have a pixel that is the lowest in y but not left-most in x. Perhaps you'd just like to find out the (x,y) of pixel that is closest to the lower left corner of the image.
[y, x] = find(binaryImage); % Make sure you get the order right. It's [y, x], NOT [x,y].
[rows, columns] = size(binaryImage)
distances = sqrt((x - 1).^2 + (y - rows).^2);
[minDistance, indexOfMin] = min(distances)
xLowerLeft = x(indexOfMin)
yLowerLeft = y(indexOfMin)

Sign in to comment.

Categories

Asked:

on 3 Jun 2020

Commented:

on 25 Jun 2020

Community Treasure Hunt

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

Start Hunting!