Sorting a 2d matrix according to the distance between each successive point.
8 views (last 30 days)
I have a 2d matrix of points that represents a 2d slice of a 3d model. Ultimately I would like to calculate the distance of perimeter of the 2d shape.
In order to do this, I think I need to order the matrix, starting with one point and then find the closest point to that first point and then the closest point to the next point. Once the matrix is sorted, I will be able to calculate the distance between each successive points in the sorted matrix and this should give me the distance of the perimeter.
I have tried using a convex hull approach but the 2d matrix is not always convex and I would loose important data points.
Thanks in advance for any guidance.
Jan on 4 Mar 2011
There is no simple, general and unique solution: If the points are distributed on an 8 shape, the behaviour in the center is not well defined.
Brett Shoelson on 4 Mar 2011
Do you have the Image Processing Toolbox? Consider using REGIONPROPS, and requesting the PERIMETER of the region.
Brett Shoelson on 5 Mar 2011
Try this instead:
stats = regionprops(cut_surface,'perimeter');
perims = [stats.Perimeter];
That will give you (in "perims") the primeter of each ROI in your segmented (binary) image. If you have more than one ROI in your image, you'll need to make sure that you're selecting the correct element of perims--the one corresponding the shape you want to measure.
Brett Shoelson on 9 Mar 2011
Eoin, I'm not sure what those three non-zero values refer to, since I can't see your code. But if the object you are interested in has a perimeter of 400 (as you pointed out in your email to me), then it's clear that you did something wrong. Perhaps this will help:
% TRY THIS: Find the object with the largest perimeter in the % image "pillsetc.png" (ships with the IPT)
img = rgb2gray(imread('pillsetc.png'));
% Is it binary?
islogical(img) % (no)
% Convert to binary
% (i.e., create a segmentation mask of the objects in the
img = im2bw(img,graythresh(img));
islogical(img) % Now it's binary!
% Now get perimeters
stats = regionprops(img,'Perimeter','Centroid');
perims = [stats.Perimeter]
% And, for illustrative purposes:
centroids = [stats.Centroid];
centroids = reshape(centroids,2,)';
fprintf('You calculated the perimeters of %d objects.\n',numel(perims));
% Note that every white region is a "blob", or ROI. Some are real objects,
% others are specs. We could have cleaned them up (BWAREAOPEN, for
% instance), but that's not necessary. The values in perims correspond the
% those 22 objects. Their positions are determined by the order in which
% the first white pixel in the region is found, going down the columns,
% from left to right.
% Mark the location of the object having the largest perimeter
idx = find(perims == max(perims));
text(centroids(idx,1),centroids(idx,2),sprintf('* P = %0.2f',perims(idx)),'color','r')