Asked by maria
on 22 Oct 2013

i have a binary image and i want to measure the distance between the lines. With bwdist i get a matrix that calculates each pixel's distance but i consider the lines as objects, so i want the distance between them. someone that can help? image link: http://tinypic.com/view.php?pic=axhgqs&s=5#.UmZJLXDKHF8

Answer by Juha-Matti Alakoskela
on 29 Oct 2013

Accepted Answer

So, maria, if I understood you correctly, you wish to estimate the distance between two long nearly linear segments, i.e., you do not wish to know the minimum distance between the branched objects but rather the minimum distance between the roughly straight segments of these lines.

What David Legland suggested to you consists of following:

- Make a label image (where each individual object is marked by an object-specific pixel value). Let us call this label image Limg.
- Calculate image distance transform for each object i that is specified by pixel value i in the label image. First make test image Timg=zeros(size(Limg)), set Timg(Limg==i)=1. Now you have B&W image where only the given object "i" is present. Now you can calculate the distance transform Dist=bwdist(Timg).
- Now, to calculate the distance of another object, let us call this "j", from the object "i", we need to check what the distances in the pixels were. For each j that is not equal to i (i.e. j~=i) pick the pixel values from the distance transform, DistanceValues=Dist(Limg==j). Then you have the shortest distance of each pixel of object j to object i. If you take min(DistanceValues) you will get the minimum distance between objects i and j. If you take median(DistanceValues) and if the line-like objects i and j are mostly parallel and have low density of branches, then, because then the distances between the linear segments are expected to be more frequent than the distances between branches, you can get a better estimate of the distance between linear, parallel segments. -- Nevertheless, this will still relatively heavily suffer from the branches in object i, so finding the branch points, cutting at those points, removing the smaller of the objects created, and returning the branch point, and repeating iteratively until you no longer have branch points, and then repeating the calculation above will give you linear segment distances. But in this case, if you only have a single image, it is probably easier to measure the distances manually. You see, the problem is that it is difficult to make your programme detect where the linear segments are. You could try to look into Hough transforms for this purpose (see "Detecting Lines Using the Hough Transform" on page http://www.mathworks.se/help/images/analyzing-images.html#f11-27827).

Duncan
on 4 Aug 2014

Hi, I am also doing something similar. I wrote the code but it doesn't seem to work. I am new to Matlab so I'm not sure what I am doing wrong.

Timg = zeros(size(Limg));

Timg(Limg == i)=1 ;

Dist = bwdist(Timg, 'euclidean');

for j~=i

DistanceValues = Dist(lableledImage == j));

min(DistanceValues);

end

Image Analyst
on 4 Aug 2014

Doesn't look right. Post your code and image as a separate post.

Duncan
on 5 Aug 2014

Sign in to comment.

Answer by Jeff E
on 22 Oct 2013

Edited by Jeff E
on 22 Oct 2013

Below is what I came up with, which is an average distance between objects for an entire image. An example of the distances being calculated is the image in red, between the given lines in white. If this isn't what you had in mind, then you'll need to explain a bit more the measurement you want to make.

You may want to clean up the lines a bit, as small, isolated pixels can have a dramatic effect on the measurement.

imgin = imread('axhgqs.jpg'); % read in image from tinypic

imgin_bw = im2bw(imgin); %convert to binary image

dist_map = bwdist(imgin_bw);

%find points furthest from lines

lines = watershed(dist_map);

lines = ~(lines > 0);

%keep only the intensities that correspond to furthest points between lines

avg_distance_map = dist_map ;

avg_distance_map(~lines) = 0;

%calculate stats

avg_distance_intensity = sum(sum(avg_distance_map)) ; %add up all the kept intensities

avg_distance_area = sum(sum(logical(avg_distance_map))) ; %number of pixels that contribute to intensity

average_distance = avg_distance_intensity / avg_distance_area ;

maria
on 23 Oct 2013

Jeff E
on 23 Oct 2013

The watershed function (in combination with bwdist) finds the points that are furthest from any white pixel.

If you want discrete measurements for each line to its adjacent neighbors, then yes, you would need something like bwlabel to consider each one of them independently. But that is a much more difficult proposition.

Sign in to comment.

Answer by David Legland
on 22 Oct 2013

Answer by Image Analyst
on 29 Oct 2013

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.