File Exchange Pick of the Week

Our best user submissions

Downsampling polygons

Jiro's pick this week is Polygon simplification by Peter Bone.

Continuing from one of my recent posts on "Connecting points with smooth curves", I came across this new entry by Peter that would work nicely with the hobbysplines function in tracing objects.

Here's how I would use it. Let's start with the original amoeba image.

im = imread('amoeba.png');
imshow(im)

I'll convert this grayscale image to black and white, and use a function called bwboundaries from the Image Processing Toolbox to automatically trace out the boundaries.

im2 = im2bw(im);
boundaries = bwboundaries(~im2, 'noholes')
boundaries = 
    [1696x2 double]
    [  30x2 double]
    [  33x2 double]
    [ 111x2 double]
    [  31x2 double]
    [  34x2 double]

Notice that bwboundaries returned a cell array of points for each boundary it found. In this case, it found 6 boundaries. For this discussion, I'll just focus on the largest boundary, i.e. the boundary with the most number of points. I can see that it is the first element. Question for everyone: how would I programmatically find the largest boundary? There are multiple ways of doing it, from basic MATLAB programming to advanced image processing. Post your response below.

largest = boundaries{1};
hold on
plot(largest(:,2),largest(:,1),'r','LineWidth',2)
hold off

Now, suppose that I don't care for the details (e.g. the individual hairs) and would like to get just the general shape of the amoeba. I can do some filtering or smoothing of the data, or simply down-sample the boundary points. Peter's reduce_poly reduces the points by automatically removing the "least important" points. For example, I can ask for 100 points.

numpts = 100;
largest2 = reduce_poly(largest', numpts)';

imshow(im)
hold on
plot(largest2(:,2),largest2(:,1),'r','LineWidth',2)
hold off

That's better, but it's still too many points for my taste. I can modify numpts and rerun the block of code. Or, I can increment a value and run the section interactively.

I'll go with numpts = 20 for this case.

numpts = 20;
largest2 = reduce_poly(largest', numpts)';

imshow(im)
hold on
plot(largest2(:,2),largest2(:,1),'r','LineWidth',2)
hold off

Now, I'll use Will's hobbysplines to connect the points with smooth splines.

% Convert the boundary points to the format required by hobbysplines
pts = fliplr(largest2(1:end-1,:));

imshow(im)
hobbysplines(num2cell(pts,2), ...
    'linestyle',{'linewidth',2}, ...
    'color','red');

Comments

Let us know what you think here or leave a comment for Peter.




Published with MATLAB® R2013b

|
  • print

Comments

To leave a comment, please click here to sign in to your MathWorks Account or create a new one.