現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
how to connect coordinate points?
1 回表示 (過去 30 日間)
古いコメントを表示
Sayak
2012 年 10 月 4 日
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);
採用された回答
Matt Kindig
2012 年 10 月 4 日
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 件のコメント
Sayak
2012 年 10 月 4 日
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?
Matt Kindig
2012 年 10 月 4 日
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
2012 年 10 月 5 日
編集済み: Sayak
2012 年 10 月 5 日
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
2012 年 10 月 6 日
No, this is definitely NOT the correct approach. It will absolutely fail for many images. See my latest comment.
その他の回答 (1 件)
Image Analyst
2012 年 10 月 4 日
編集済み: Image Analyst
2012 年 10 月 5 日
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 件のコメント
Sayak
2012 年 10 月 5 日
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
2012 年 10 月 5 日
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
2012 年 10 月 6 日
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
2012 年 10 月 6 日
編集済み: Image Analyst
2012 年 10 月 6 日
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
2012 年 10 月 7 日
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?
Image Analyst
2012 年 10 月 7 日
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;
Image Analyst
2012 年 10 月 7 日
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
2012 年 10 月 8 日
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
2012 年 10 月 8 日
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
2012 年 10 月 10 日
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?
Sayak
2012 年 10 月 11 日
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
2012 年 10 月 11 日
You need to call regionprops. See my image segmentation demo in my File Exchange.
Sayak
2012 年 10 月 12 日
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
2012 年 10 月 12 日
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
2012 年 10 月 13 日
編集済み: Image Analyst
2012 年 10 月 14 日
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
2012 年 10 月 14 日
Another thing, should I need to use YUV color space for better clarity of object detection?
Image Analyst
2012 年 10 月 14 日
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
2012 年 10 月 15 日
OK. Then what steps should I follow just to separate the objects in an image from one another?
Image Analyst
2012 年 10 月 15 日
In general, watershed segmentation. See Steve Eddins's demo: http://blogs.mathworks.com/steve/2006/06/02/cell-segmentation/
Sayak
2012 年 10 月 17 日
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?
参考
カテゴリ
Help Center および File Exchange で Image Segmentation and Analysis についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
アジア太平洋地域
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)