How to find distance in binary image?

20 views (last 30 days)
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:

Accepted Answer

Juha-Matti Alakoskela
Juha-Matti Alakoskela on 29 Oct 2013
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:
  1. Make a label image (where each individual object is marked by an object-specific pixel value). Let us call this label image Limg.
  2. 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).
  3. 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

Sign in to comment.

More Answers (3)

Jeff E
Jeff E on 22 Oct 2013
Edited: 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 ;
Jeff E
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.

David Legland
David Legland on 22 Oct 2013
Hi maria, If you consider a label image (one label for each line), you can call "bwdist" function for each label "i". Then, for each label "j", witj j~=i, you can consider the minimum value of the distance map in the pixels corersponding to label j. This will give you the (minimum) distance between lines i and j.
  1 Comment
maria on 22 Oct 2013
hey david thanks for the answer.unfortunately I don't understand why I should consider the minimum value for j equal to i.. could you please help me a little bit more?

Sign in to comment.

Image Analyst
Image Analyst on 29 Oct 2013
All these discussions hinge on doing exactly what maria says. But I would like to take a larger view and ask what if what she said she wants us to do for her is not the best approach? What if those lines are not accurate? How did she get the lines? Maybe it's not appropriate to use an edge detector. After all, we have not seen the original image that the lines were derived from, and not seen the lines overlaid on the original image. Can I trust the lines? I don't know. Perhaps she wants an average spatial frequency of some ridged or rippled pattern and it's better to take a Fourier approach. Perhaps that, or other methods, will work as well or even better. I have no idea because I can't see the original image and I don't know the larger context. Often a poster say "help me do X" but they don't say it's because they need Y. So people tell them how to do X. But if you knew they needed Y , you could say "X is not the best or most appropriate way to get Y, you should really use Z instead ."
  1 Comment
maria on 29 Nov 2013
juha's answer helped a lot, thanks for the reply :)

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!