Extract outermost contour from a set of contours.

I have an N X 2 matrix with the x,y co-ordinate values of the edges. I plot these co-ordinates (plotted in red displayed below in "Input Plot")
I want to extract the outermost contour (enclosing the largest area). How can this be done?
I have attached the N X 2 matrix with all x, y values (of input plot). I have also attached a .fig file of the input plot.
Regards.

2 commentaires

Geoff Hayes
Geoff Hayes le 20 Déc 2014
Sanya - you didn't attach the data and figure. Once you have chosen the file, you must press the Attach File button.
oops. sorry. I have attached the files here: https://www.dropbox.com/sh/npibrtphxlvsm1t/AAC4mO8rM2fgYnJ8wC-S1kNca?dl=0

Connectez-vous pour commenter.

 Réponse acceptée

I think using contour is the wrong approach, but I could be wrong. You don't even want all the contours -- you just want the outer boundary . What I would do is to threshold your image, then call imfill() to make the binary image solid, and then call bwareaopen() to get rid of the small noisy exterior regions. Then call bwboundaries to get a list of the outer perimeter's (x,y) coordinates.
binaryImage = grayImage > thresholdValue; % Threshold/binarize the image.
binaryImage = imfill(binaryImage, 'holes'); % Fill holes.
binaryImage = bwareaopen(binaryImage, 2000); % Remove small blobs.
boundaries = bwboundaries(binaryImage); % Get list of (x,y) coordinates of outer perimeter.
Attach your image if you want more help.

10 commentaires

I don't want to lose the information of these co-ordinates. Using morphological operations like bwareaopen, the co-ordinate values where the contour is detected, will change. Right? I have attached the files I mentioned. Please let me know if more information is required.
No. Why do you think that? Why would any of the operations I listed change any coordinates? They won't.
And why don't you show me the original image - that from which you derived the contours?
Thanks for your reply.
This is the image I have attached. To find contours, I am using Active contour without edge by Su Dongcai. The variable contour contains the co-ordinates.
To know a little more of what I'm upto, please see this.
Btw, these points are referred to as contours, right?
What do you want to measure? The outside if the wheel? It seems like it based on your image up at the top of this page. If so, it's like I thought - you wouldn't want to get contours. You'd simply threshold that image and fill holes and call bwboundaries() like I originally suggested. If you don't want the actual outer boundary but want some smoothed version, you can use activecontour() (chan-vese algorithm like your File Exchange) - it's a built in function now. See my attached activecontour demo, though I really think that that is not the way to go and suggest my original suggestion of bwboundaries() instead.
If there some reason why you don't want to use the much simpler and more accurate bwboundaries() method?
Thanks for the demo. I wasn't aware about Chan-Vese algorithm being a built in function. Anyway, I want to find the points which are co-planar on the surface of rim. I believe the output of contour would give me this.
What do you mean by co-planar? It won't do that in terms of range (3-D distance from the camera) because you don't have a range image - you have an optical gray scale image. Contour gives you an isoline at certain gray levels. Just like thresholding except the thresholding method I recommend is a lot simpler and more straightforward . I really see no reason (so far) why you insist on a more complicated method of getting basically the same thing.
Well, alright, thanks a lot! I will use this for now and would get back here maybe if I come across any accuracy related issues.
Using the code below:
BW = im2bw(img);
binaryImage = BW;
binaryImage = imfill(binaryImage, 'holes'); % Fill holes.
binaryImage = bwareaopen(binaryImage, 2000); % Remove small blobs.
figure, imshow(binaryImage);
boundaries = bwboundaries(binaryImage); % Get list of (x,y) coordinates of outer perimeter.
figure, imshow(img);
X_Y = boundaries{1,1};
hold on;
plot (X_Y(:,1),X_Y(:,2), 'r');
grid
axis equal
( input image : https://www.dropbox.com/s/q26ebvthbmnlh54/LEFT_REF.bmp?dl=0
output plot: attached)
These are the doubts I have:
  1. The plot has an offset (it doesn't overlap with my original image (maybe I'm missing out on a small line in my code to plot))
  2. The co-ordinates of the plot (the red line shown on plot according to my code above) has its co-ordinates stored in boundaries (right?). These co-ordinates are all integers. Why is this? The plot of outer perimeter (red line) has thickness lesser than 1 pixel (so sub-pixel accuracy, right?). What modification can I do to get co-ordinates values with sub-pixel accuracy?
Very common mistake. All the time people mix up row,column with x,y. Remember row is y, NOT x. bwboundaries gives row, column, not x,y. The first row is row, which is x, and the second column is column which is x. So try this:
plot (X_Y(:, 2), X_Y(:,1), 'r');
Right! Thank you.
How about my second point? To obtain co-ordinates in subpixels? The plot has sub-pixel accuracy right? (Since the thickness of the line is less than 1 pixel)
No it doesn't. If you're going to deal with the image, like make measurements from it, you need to deal with pixels. Of course you can always upsize your image with imresize() to create more pixels.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Contour Plots dans Centre d'aide et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by