how to connect coordinate points?

I have used bwlabel to label the connected components of a picture.Then I have used find() to have the coordinates for the pixels in object 1 and saved it in [r c].
Now is there any way to use those co-ordinate and draw them again to reconstruct the object?
My code is something like that::
img = imread('global1.jpg');
b_img = im2bw(img);
[m,n] = bwlabel(b_img,4);
[r c] = find(m==1);

 Respuesta aceptada

Matt Kindig
Matt Kindig el 4 de Oct. de 2012
Hi Sayak,
I'm a little bit unclear on what you are trying to do, but I think you want to use bwboundaries. That will give you the coordinates on the border of the image, which you can then use to reconstruct the object.
doc bwboundaries
doc bwtraceboundary

4 comentarios

Sayak
Sayak el 4 de Oct. de 2012
First thanks for your reply. See the picture given above which contains a silhouette of a man and a woman. Now when I use bwlabel it returns vectors of indices for the pixels that make up a specific object.
In my case [r,c] = find(bwlabel(b_img)==2) results in an array of coordinate points based on the array [r,c]. now what I want to do is to isolate the picture of girl from the boy. And my approach was to use bwlabel(b_img) == 1 [for male] or bwlabel(b_img) == 2 [for female]. And use the coordinate points and to isolate them.
Is my approach is right? What should I do for better result?
The output of bwlabel gives you a label matrix, which identifies each distinct region. You can then use your approach to isolate the male and female images. That is,
L = bwlabel(b_img,4);
male = (L==1); %these might be reversed, i.e. male=1, female=2
female = (L==2);
Sayak
Sayak el 5 de Oct. de 2012
Editada: Sayak el 5 de Oct. de 2012
Yes I have done that. Now to distinguish male and female I have used the following approach.
1) Taking an array full of 0's, having a size equal to the original image and named this array as 'mask'.
2) Storing the values of Male (by doing male = find(L==1);) in [r c].
3) For each values of male array, I have changed the value of the array mask to 1. Thus it will only show the pixel positions of male in the mask.
4)Typecast mask to logical/uint8 and do a imshow() thus only to show the male-part of the original image.
Problem : As the main image is of 90 x 91 and the mask is also 90 x 91. But the male array is of 6021 x 2. So whenever I am checking the values of mask and male it produces 'array out of bound exception'.
I do not know how to get rid of that problem. What should I do?
My code so far::
img = imread('C:\Users\Sayak\Documents\MATLAB\mat_pic\global1.jpg');
%img = imresize(img,0.5);
b_img = im2bw(img);
[glo_r,glo_c,glo_p] = size(b_img);
%edge(b_img);
for i = 1 : glo_r
for j = 1 : glo_c
mask(i,j) = 0;
end
end
[m,n] = bwlabeln(b_img,4);
[r1 c1] = find(m==1);
rc = [r1 c1];
for i = 1 : glo_r
for j = 1 : glo_c
if(mask(i,j) ~= rc(i,j))
mask(i,j) = 1;
end
end
end
imshow(logical(mask)); % is it correct approach ?
Image Analyst
Image Analyst el 6 de Oct. de 2012
No, this is definitely NOT the correct approach. It will absolutely fail for many images. See my latest comment.

Iniciar sesión para comentar.

Más respuestas (1)

Image Analyst
Image Analyst el 4 de Oct. de 2012
Editada: Image Analyst el 5 de Oct. de 2012
The usual Mathworks-recommended way is to use ismember():
keeperBlobsImage = ismember(labeledImage, blobNumberToKeep);
where blobNumberToKeep can be either a single number of a vector of numbers that you want to keep. See my BlobsDemo for a demo http://www.mathworks.com/matlabcentral/fileexchange/?term=authorid%3A31862 - I extract out two types of coins from the standard MATLAB demo image.

22 comentarios

Sayak
Sayak el 5 de Oct. de 2012
Actually in the above link it shows a whole lot of work that you have done. I am unable to find the coin-problem. If its possible can you provide me the perfect associated link?
Image Analyst
Image Analyst el 5 de Oct. de 2012
Sorry - that was the answers profile. I've corrected it to my File Exchange. Look for "Image Segmentation Tutorial - BlobsDemo". http://www.mathworks.com/matlabcentral/fileexchange/?term=authorid%3A31862
Sayak
Sayak el 6 de Oct. de 2012
Its a super work. But being a beginner I feel it somehow tough to understand. I have done something to distinguish connected components. My code is working fine with manual array. But when I am working with the picture, it is not showing the male and female images differently.
My Code::
BW = [1 1 1 0 0 0 0 0
1 1 1 0 1 1 0 0
1 1 1 0 1 1 0 0
1 1 1 0 0 0 1 0
1 1 1 0 0 0 1 0
1 1 1 0 0 0 1 0
1 1 1 0 0 1 1 0
1 1 1 0 0 0 0 0];
BW = im2bw(BW);
figure, imshow(BW);
[gr,gc,gp] = size(BW);
mask = zeros(gr,gc);
[L n]= bwlabel(BW,4);
[r c] = find(L==1);
rc = [r c];
% temp(gr,gc);
[a,b]=size(rc);
for i = 1 : gr
for j = 1 : gc
m = 1; while(m<=a)
if(i==rc(m,1) && j==rc(m,2))
mask(i,j) = 1;
end
m = m + 1;
end
end
end
figure, imshow(uint8(mask)); % mask contains the rows and columns of objects returned by find()
This works fine unless I am providing the picture (link above) to BW.
Image Analyst
Image Analyst el 6 de Oct. de 2012
Editada: Image Analyst el 6 de Oct. de 2012
No, that's the inefficient, complicated, non-MATLAB way of doing it. You can do all that with just one line:
blob1 = ismember(L, 1);
instead of using mask, zeros(), find(), im2bw(), the "for" loop, the "while" loop, the "if" statement, etc. All that is totally unnecessary and just makes it way more complicated than it needs to be.
Here, here's a full-blown demo, using your image of 3 blobs, where I extract each of the 3 blobs one at a time. Note that if you label with 8 connectivity instead of 4 connectivity, you'd have just 2 blobs since it would consider blobs touching at the pixel corners to be part of the same blob, while 4 connectivity considers them as separate blobs.
BW = [...
1 1 1 0 0 0 0 0
1 1 1 0 1 1 0 0
1 1 1 0 1 1 0 0
1 1 1 0 0 0 1 0
1 1 1 0 0 0 1 0
1 1 1 0 0 0 1 0
1 1 1 0 0 1 1 0
1 1 1 0 0 0 0 0];
subplot(2, 3,1);
imshow(BW, 'InitialMagnification', 800);
title('Original Binary Image', 'FontSize', 20);
% Label the image with 4 connectivity
[L n]= bwlabel(BW, 4);
% Note: 8 connectivity would get you two blobs.
% Display the three blobs.
subplot(2, 3, 2);
imshow(L, [], 'InitialMagnification', 800);
title('Labeled Image', 'FontSize', 20);
coloredLabels = label2rgb (L, 'hsv', 'k', 'shuffle'); % pseudo random color labels
subplot(2, 3, 3);
imshow(coloredLabels, []);
title('Labeled Image, with colored labels.', 'FontSize', 16);
%======== KEY PART BELOW =======================
% Extract the two blobs.
blob1 = ismember(L, 1);
blob2 = ismember(L, 2);
blob3 = ismember(L, 3);
%======== KEY PART ABOVE =======================
% Display the blobs.
subplot(2, 3, 4);
imshow(blob1, 'InitialMagnification', 800);
title('Blob 1', 'FontSize', 20);
subplot(2, 3, 5);
imshow(blob2, 'InitialMagnification', 800);
title('Blob 2', 'FontSize', 20);
subplot(2, 3, 6);
imshow(blob3, 'InitialMagnification', 800);
title('Blob 3', 'FontSize', 20);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
Thanks for the comment about BlobsDemo. I thought it was easy for beginners since I had more comments than lines of code. Since it's designed for beginners, I'll have to take a look at it to see how it can be made even more instructive.
Sayak
Sayak el 7 de Oct. de 2012
Ok, I understand now. But consider this picture ::
It can clearly visible that male and female are not connected. Now, even if I use blob, still I am unable to differentiate the male from the female. May be in that case what I need is to use only those connected components who's size are big than some threshold value. Taking your advice if I do this,
[L n]= bwlabel(BW, 4);
for (i = 1 : n)
blob(i) = ismember(L, i);
end
then it again would be a non-robust approach as I do not need every connected component for the differentiation of male from female. So what should I do here and why is the blob approach is unable to find those male and female separately?
No, you can't do that. ismember returns an entire image, where as blob(i) can take only a single number, not a whole array of numbers. I'm not sure why you say that you can't get the two shapes. You can. Just do this:
shape1 = ismember(L, 1); % Left hand side shape = man.
shape2 = ismember(L, 2); % Right hand side shape = woman.
Those are integer/grayscale/labeled images. If you want binary images, you can just compare to zero.
binaryShape1 = ismember(L, 1) > 0;
binaryShape2 = ismember(L, 2) > 0;
OK, in case my latest comment is still not enough, I downloaded your image and applied my code to it. Here I extract each shape:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
format longg;
format compact;
fontSize = 14;
% Read in a standard MATLAB gray scale demo image.
folder = 'C:\Users\Mark\Documents\Temporary';
% Read in a standard MATLAB color demo image.
baseFileName = 'man_woman.jpg';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
% 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.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbImage = imread(fullFileName);
grayImage = rgbImage(:,:,2); % Get green channel as a gray scale image.
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows columns numberOfColorBands] = size(rgbImage);
% Display the original color image.
subplot(2, 3, 1);
imshow(grayImage, []);
title('Original Gray Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Binarize it.
binaryImage = grayImage < 128;
subplot(2, 3, 2);
imshow(binaryImage);
title('Original Binary Image', 'FontSize', 20);
% Label the image with 4 connectivity
[L n]= bwlabel(binaryImage, 4);
% Note: 8 connectivity would get you two blobs.
% Display the three blobs.
subplot(2, 3, 3);
imshow(L, [], 'InitialMagnification', 800);
title('Labeled Image', 'FontSize', 20);
coloredLabels = label2rgb (L, 'hsv', 'k', 'shuffle'); % pseudo random color labels
subplot(2, 3, 4);
imshow(coloredLabels, []);
title('Labeled Image, with colored labels.', 'FontSize', 16);
%======== KEY PART BELOW =======================
% Extract the two blobs.
blob1 = ismember(L, 1);
blob2 = ismember(L, 2);
%======== KEY PART ABOVE =======================
% Display the blobs.
subplot(2, 3, 5);
imshow(blob1, 'InitialMagnification', 800);
title('Blob 1', 'FontSize', 20);
subplot(2, 3, 6);
imshow(blob2, 'InitialMagnification', 800);
title('Blob 2', 'FontSize', 20);
Sayak
Sayak el 8 de Oct. de 2012
First thank you. Now, I understood the functionality of that function. Using blob works fine here. But in the case where the picture is somehow complicated (i.e. where some background is present and different objects are actually connected), how to use ismember() function to distinguish them?
Another, if I use bwboundaries() and distinguish different area of a connected component, then based on that, can I crop that particuler area?
Sayak
Sayak el 8 de Oct. de 2012
OK, I am able to crop the picture depending upon BoundingBox. Based upon bounding box can you guide me how to distinguish a human totally?
Sayak
Sayak el 10 de Oct. de 2012
I guess to do this one need to do a background subtraction at the very first step. Any other choices to distinguish a human totally?
Image Analyst
Image Analyst el 10 de Oct. de 2012
No background subtraction is needed, just thresholding.
Sayak
Sayak el 11 de Oct. de 2012
I tried this following code hence to extract the connected 'big component' but in vein.
I = imread('1.jpg');
level = graythresh(I);
BW = im2bw(I, level);
figure;imshow(BW)
BW = im2bw(rgb2gray(I), 0.25);
figure;
imshow(BW);
BW1 = BW;
CC = bwconncomp(BW);
numPixels = cellfun(@numel,CC.PixelIdxList);
[biggest,idx] = max(numPixels);
BW(CC.PixelIdxList{idx}) = 0;
figure, imshow(BW);
figure, imshow(BW1);
Ir = imsubtract(BW1,BW);
figure;
imshow(Ir)
So, what should I do in case where I need to detect foreground elements? What changes should I make in my code above?
Image Analyst
Image Analyst el 11 de Oct. de 2012
You need to call regionprops. See my image segmentation demo in my File Exchange.
Sayak
Sayak el 12 de Oct. de 2012
Ok, I have understood the segmentation that you have done. And its based upon area and intensity. I have tried it but the fact is that whenever I am trying to crop the image based upon Bounding Box area, its not giving the desirable output (not detecting a human and crop him/her properly). I have done the following (following your way from the segmentation demo)
read image
- binary conversion
- labeling the image
- regionprops
- finding blobArea
- finding allowableAreaIndexes
- keeperIndexes using ismember()
- for 1 to n number of blobs
- measure boudningBox and keep it in thisBlobsBoundingBox
- imcrop(keeperBlobsImage, thisBlobsBoundingBox);
- subplot them.
But the problem is it does not showing different objects within the rectangular bounding box. How to do that?
Image Analyst
Image Analyst el 12 de Oct. de 2012
This is completely different than a 2 gray level silhouette - this is a full color photograph. Please give the code you used to take that photo and arrive at the binary image of the three people.
Sayak
Sayak el 13 de Oct. de 2012
Editada: Image Analyst el 14 de Oct. de 2012
I have read the picture then changed it to gray-scale and at last I am able to segment the picture based on the binary mask.But the problem is the blob-approach is not working here. Here is the code.
%--------------------------------------------------------------
clc;
clear mem;
clear all;
% Take the input Image
originalImage=imread('C:\Users\Sayak\Documents\MATLAB\mat_pic\human.jpg');
subplot(2,2,1); imshow(originalImage); title('originalImage');
%Change Color space
hsvColorspace=rgb2hsv(originalImage);
subplot(2,2,2); imshow(hsvColorspace); title('hsvColorspace');
% Gray Scale Conversion with respect to blue
GrayScaleImage=hsvColorspace(:,:,1);
%GrayScaleImage = bwareaopen(GrayScaleImage,100);
[rows columns planes]=size(GrayScaleImage);
%Creating Binary Mask
BinaryMask= GrayScaleImage > 0.5;
subplot(2,2,3);
imshow(BinaryMask);
title('BinaryMask');
h = waitbar(0,'Please wait...');
% Pre-allocating mask
segmentationMask=[];
for i=1:rows
for j=1:columns
if BinaryMask(i,j) == 1
segmentationMask(i,j,1)=originalImage(i,j,1);
segmentationMask(i,j,2)=originalImage(i,j,2);
segmentationMask(i,j,3)=originalImage(i,j,3);
else
segmentationMask(i,j,1)=0;
segmentationMask(i,j,2)=0;
segmentationMask(i,j,3)=0;
end
end
waitbar(i/rows,h)
end
segmentedImage=uint8(segmentationMask);
subplot(2,2,4);
imshow(segmentedImage);
title('segmentedImage');
%--------------------------------------------------------
Now how to apply the blob-approach to distinguish the people from the image?
Sayak
Sayak el 14 de Oct. de 2012
Another thing, should I need to use YUV color space for better clarity of object detection?
Image Analyst
Image Analyst el 14 de Oct. de 2012
No, sorry but that algorithm is way way too primitive to extract out the silhouettes of the people. You can't just find all the reddish pixels in the image and expect that you'll get each person, including their closing, which is not red and overlaps. YUV color space will be no better than hsv colorspace.
Sayak
Sayak el 15 de Oct. de 2012
OK. Then what steps should I follow just to separate the objects in an image from one another?
Image Analyst
Image Analyst el 15 de Oct. de 2012
In general, watershed segmentation. See Steve Eddins's demo: http://blogs.mathworks.com/steve/2006/06/02/cell-segmentation/
Sayak
Sayak el 17 de Oct. de 2012
I saw it. But it is totally different from what my picture is. Using watershed (following Steve's demo) does not seem to be working on my picture. In this context what should I do?
Image Analyst
Image Analyst el 17 de Oct. de 2012
Research the literature for people who have done similar things.

Iniciar sesión para comentar.

Preguntada:

el 4 de Oct. de 2012

Community Treasure Hunt

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

Start Hunting!

Translated by