# Minimum distance between two objects

34 views (last 30 days)

Show older comments

##### 0 Comments

### Accepted Answer

Matt J
on 24 Apr 2021

Edited: Matt J
on 24 Apr 2021

load('Bones')

reg=regionprops(Image,'PixelList');

[D,I1] = pdist2(reg.PixelList,'euclidean','Smallest',1);

[minDistance,I2]=min(D);

minDistance,

imshow(Image)

hold on

xy=num2cell([reg(1).PixelList(I1(I2),:);reg(2).PixelList(I2,:)],1);

line(xy{:},'Color','c','LineWidth',3);

axis([113.0131 208.1735 186.9023 282.0627])

hold off

### More Answers (1)

Image Analyst
on 26 Apr 2021

@Vihan P, see code adapted for your image. I also did it both ways, using sqrt(), where I just plotted one of the closest pairs, and pdist2() where I plotted all 3 of the closest pairs. If it helps you, please vote for the answer. I also answered you in your original "Answer" in the other person's thread where you first asked this.

clc; % Clear the command window.

close all; % Close all figures (except those of imtool.)

clear; % Erase all existing variables. Or clearvars if you want.

workspace; % Make sure the workspace panel is showing.

format long g;

format compact;

fprintf('Beginning to run %s.m ...\n', mfilename);

fontSize = 13;

% Check that user has the Image Processing Toolbox installed.

hasIPT = license('test', 'image_toolbox');

if ~hasIPT

% User does not have the toolbox installed.

message = sprintf('Sorry, but you do not seem to have the Image Processing Toolbox.\nDo you want to try to continue anyway?');

reply = questdlg(message, 'Toolbox missing', 'Yes', 'No', 'Yes');

if strcmpi(reply, 'No')

% User said No, so exit.

return;

end

end

%===============================================================================

% Read in a standard MATLAB color demo image.

folder = pwd; %'C:\Users\Lakshya\Documents\Temporary';

baseFileName = 'knee.png';

% Get the full filename, with path prepended.

fullFileName = fullfile(folder, baseFileName);

if ~exist(fullFileName, 'file')

% Didn't find it there. Check the search path for it.

fullFileName = baseFileName; % No path this time.

if ~exist(fullFileName, 'file')

% Still didn't find it. Alert user.

errorMessage = sprintf('Error: %s does not exist.', fullFileName);

uiwait(warndlg(errorMessage));

return;

end

end

grayImage = imread(fullFileName);

% Get the dimensions of the image. numberOfColorBands should be = 3.

[rows, columns, numberOfColorBands] = size(grayImage);

% Display the original image.

subplot(2, 2, 1);

imshow(grayImage);

axis on;

title('Original Gray Scale Image', 'FontSize', fontSize);

% Enlarge figure to full screen.

set(gcf, 'units','normalized','outerposition',[0 0 1 1]);

% Binarize the image

binaryImage = imbinarize(grayImage);

% Display the image.

subplot(2, 2, 2);

imshow(binaryImage);

title('Binary Image', 'FontSize', fontSize);

% Fill the outline to make it solid so we don't get boundaries

% on both the inside of the shape and the outside of the shape.

binaryImage = imfill(binaryImage, 'holes');

% Display the image.

subplot(2, 2, 3);

imshow(binaryImage);

% bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.

% Plot the borders of all the coins on the original grayscale image using the coordinates returned by bwboundaries.

hold on;

boundaries = bwboundaries(binaryImage);

numberOfBoundaries = size(boundaries, 1);

for k = 1 : numberOfBoundaries

thisBoundary = boundaries{k};

plot(thisBoundary(:,2), thisBoundary(:,1), 'r', 'LineWidth', 3);

end

title('Filled Binary Image with Boundaries', 'FontSize', fontSize);

hold off;

% Define object boundaries

numberOfBoundaries = size(boundaries, 1)

boundary1 = boundaries{1};

boundary2 = boundaries{2};

boundary1x = boundary1(:, 2);

boundary1y = boundary1(:, 1);

x1=1;

y1=1;

x2=1;

y2=1;

overallMinDistance = inf; % Initialize.

index1 = 1;

index2 = 1;

for k = 1 : length(boundary2)

boundary2x = boundary2(k, 2);

boundary2y = boundary2(k, 1);

% For this blob, compute distances from boundaries to edge.

allDistances = sqrt((boundary1x - boundary2x).^2 + (boundary1y - boundary2y).^2);

% Find closest point, min distance.

[minDistance(k), indexOfMin] = min(allDistances);

if minDistance(k) < overallMinDistance

overallMinDistance = minDistance(k);

x1 = boundary1x(indexOfMin);

y1 = boundary1y(indexOfMin);

x2 = boundary2x;

y2 = boundary2y;

index2 = k;

index1 = indexOfMin;

end

end

% Report to command window.

fprintf('Min Distance from sqrt() method = %f at index %d of boundary 1 and index %d of boundary 2.\n', ...

overallMinDistance, index1, index2);

hFig = figure;

h1 = subplot(1, 2, 1);

imshow(binaryImage);

axis on;

title('Closest Distance from sqrt()', 'FontSize', fontSize);

h2 = subplot(1, 2, 2);

imshow(binaryImage);

axis on;

title('Closest Distances from pdist2()', 'FontSize', fontSize);

hFig.WindowState = 'maximized';

hold on;

% Draw a line between point 1 and 2

line(h1, [x1, x2], [y1, y2], 'Color', 'y', 'LineWidth', 3);

%======================================================================================

% For comparison, use pdist2()

allDistances2 = pdist2(boundary1, boundary2);

minDistance2 = min(allDistances2(:));

% Find all points that have that min distance - there may be several that have it.

[r, c] = find(allDistances2 == minDistance2)

boundary1x = boundary1(:, 2);

boundary1y = boundary1(:, 1);

boundary2x = boundary2(:, 2);

boundary2y = boundary2(:, 1);

for k = 1 : length(r)

% Report to command window.

index1 = r(k);

index2 = c(k);

fprintf('Min Distance from pdist2() method = %f at index %d of boundary 1 and index %d of boundary 2.\n', ...

minDistance2, index1, index2);

xLine = [boundary1x(index1), boundary2x(index2)];

yLine = [boundary1y(index1), boundary2y(index2)];

line(h2, xLine, yLine, 'Color', 'm', 'LineWidth', 1.5);

end

You can't see the magenta lines in the right image very well, but they're there.

### See Also

### Categories

### Community Treasure Hunt

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

Start Hunting!