How to compare the distance between 2 structures and a center point.

As seen in the image there are 2 binary structures located in an image. I have already calculated a center point, in the image it is the red mark, and want to calculate the distance of the center point to points of both structures.
I have already used bwdist to calculate the distance between centre point and both seperate structures.
D = bwdist(map_centre_point);
%map_centre_point is a binary image, same size as struc1 and struc2, with value 1 at the centre point.
distance_struc1 = struc1 .* D;
distance_struc2 = struc2 .* D;
Now I need a method to compare the values of corresponding pixels of both structures with each other. My idea was to implement a line which goes clockwise and compare the values of the two structures, however i cannot implement this.
So to be precise: I want to know the values of struc1 and struc2 where it intersect the yellow line. And then I want to know it for the green line, etc. etc. Any ideas, or help how to implement this would be appreciated.

 Accepted Answer

Matt J
Matt J on 23 Dec 2013
Edited: Matt J on 23 Dec 2013
I want to know the values of struc1 and struc2 where it intersect the yellow line.
I assume you really meant to say, you want distance_struc1,2 where they intersect the yellow line.
This could be tough unless you're sure that a line radiating from the "center" will not intersect the inner or outer curve multiple times. See also this very similar thread.
You also need a way of interpolating between the pixels of the structures if the yellow line doesn't intersect the pixels on those curves precisely, which it normally will not. You could use SPLINE or something similar to fit the struc's with continuous parametric curves x(t), y(t). Then you could find the intersections of the yellow line with the continuous curve and the corresponding t0 with fminsearch. Once you have x(t0),y(t0) on each curve you can measure distances.

6 Comments

You're right, I want distance_struc1,2. I am fairly certain that the line will not intersect the inner or outer curve multiple times. I am not sure how to use the spline function on a 2d image. I don't understand how to use fminsearch to find the intersection either. Could you explain it a little more dummy proof?
Here's a simpler but related approach.
You extract the coordinates X and Y of both curves using find(). Then, find the rays from the "center" to each X(i), Y(i)
Rx=X-Xcenter; %ray x-coordinate
Ry=Y-Ycenter; %ray y-coordinate
Then find the polar coordinates of these rays
[thetas,distances]=cart2pol(Rx,Ry);
Now if your "yellow line" has polar angle theta when the origin is defined at your center point, then the distance along this line to the curve can be modeled by
dist_theta= interp1(thetas,distances,theta);
which is exact when the yellow line passes exactly through one of the X(i), Y(i) sample points.
You can do this for both curves, thereby obtaining distances inner_dist_theta and outer_dist_theta. If you're looking for the difference,
separation = outer_dist_theta - inner_dist_theta;
Sorry for the late response, I was away for the holidays. I tried this approach, however an error remains. "The grid vectors are not monotonic increasing." The reason for this is probably that my structures weren't as easy as I thougt, i.e. it does intersect the inner/outer curve multiple times.
However currently it isn't necessary anymore to know the distance from the centre point. Therefore I have also tried the inter-point distance matrix mentioned in the other thread to determine the distance between the pixels.
boundaries_outer = find(outer_curve);
boundaries_inner = find(inner_curve);
s = ipdm(boundaries_outer, boundaries_inner, 'NearesNeighbor', 'Result','Structure')
However this results in the following error, "Property/value pairs must come in PAIRS". Further help would be appreciated.
You have an odd number of input arguments. IPDM expects an even number,
s = ipdm(boundaries_outer, boundaries_inner, 'Subset','NearestNeighbor', 'Result','Structure')
Also, find() will not return x,y coordinate pairs unless you call with more output arguments.
You're right, I just checked in the code.
[rows1 cols1] = find(outer_curve);
boundaries_outer = [rows1 cols1];
Is there a way to interpolate the innerstructure untill it matches the amount of input arguments of the outer argument? Losing argument in the outer structure to make ipdm viable is not really an option.
IPDM doesn't require that you have equal number of points in both sets.

Sign in to comment.

More Answers (1)

Are struc1 and struc2 binary images? How did you get them? Do you have the coordinates of every point on them? If you can't get them while making them, then you can get the coordinates of each afterwards by labeling them. Then just use Pythagorean theorem to get the distance from the center point to every point on the boundary of each.
labeledImage = bwlabel(binaryImage);
% Get struc1:
[rows1, cols1] = find(labeledImage == 1); % Outer ring
% Get struc2:
[rows2, cols2] = find(labeledImage == 2); % Inner ring
% Calculate distances of every point to the center.
distances1 = sqrt((rows1-centerRow)^2+(cols1-centerCol)^2);
distances2 = sqrt((rows2-centerRow)^2+(cols2-centerCol)^2);
After that I'm not sure how you're defining the lines intersecting them, and if there is one line or two lines. If you just wanted to run around the outer ring visiting every pixel and finding the inner pixel that intersects that line, I'm sure you know how to do that. Then just subtract the distances if you want to find the distance between them.
You said "So to be precise: I want to know the values of struc1 and struc2 where it intersect the yellow line." Well, to be precise the value of struc1 or struc2 where it intersects the line is 1/true/white/255 or whatever you want to call it when the pixel is white. I have a feeling your not really being precise because I don't think that is useful information.

2 Comments

struc1 and struc2 are binary images, they are the edges of a manual segmented area.
Furthermore I used function bwdist(map_centre_point) to make a distance map. map_centre_point is zeros(size(struc1)) & 1 at centre point. So map_centre_point is only one at the defined centre and zeros in the rest of the image. The function bwdist(map_centre_point) then calculates the distance.
Then I multiply it with the binary image struc1 and struc2 seperately. So the variable distance_struc1 is not 1/true/white/255 but the actual distance between that point and the centre point.
I hope this makes my question a bit clearer, so I want distance_struc1,2 where they intersect the yellow line.
That could work but it's not efficient and unnecessary. No need to calculate this for every single pixel in the entire image (which is what bwdist does). I think it would be faster to just do it for just the "set" pixels, though I'm not sure how fast find() would be but I expect it's faster than bwdist(). Anyway modify my code
% Get struc1 perimeter coordinates:
[rows1, cols1] = find(struc1); % Outer ring
% Get struc2 perimeter coordinates:
[rows2, cols2] = find(struc2); % Inner ring
% Calculate distances of every point to the center.
distances1 = sqrt((rows1-centerRow)^2+(cols1-centerCol)^2);
distances2 = sqrt((rows2-centerRow)^2+(cols2-centerCol)^2);
% Run around outer ring getting distances to inner ring.
for k = 1 : length(rows1)
% First find out which pixel on the inner ring
% is on the line between center and outer ring.
% Use point slope formula
% ysAlongLine = slope * (x-xCenter) + yCenter
% I assume you can do this one part.
% Just plug in cols1 for x
% x,y may lie between pixels.
% Now find which pixel in row2 and col2 is closest to ring 1 (outer)
innerRingDistancesToLine = sqrt((rows1-ysAlongLine ).^2+(cols1-x).^2);
% You could actually get rid of (cols1-x).^2 because it's always 0.
[~, indexOfClosest] = min(innerRingDistancesToLine);
% Now find distances between the two perimeter points
r1 = rows1(k);
c1 = cols1(k);
r2 = rows2(indexOfClosest);
c2 = cols2(indexOfClosest);
distance(k) = sqrt((r2-r1)^2+(c2-c1)^2);
end

Sign in to comment.

Asked:

on 23 Dec 2013

Commented:

on 8 Jan 2014

Community Treasure Hunt

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

Start Hunting!