MATLAB: Distance between two objects.

digital image processingimage processing

Hello everyone. In a binary image how is it possible to calculate the minimum horizontal distance between two objects.

Best Answer

% 1.- acquiring image
A=imread('2D_distance_between_2_objects.jpg')
% since it's already a quite sharp image, just use one layer
A1=A(:,:,1)
% I took screenshot directly from your question, so clean a bit
A1(A1<125)=0;A1(A1>=125)=255
% 2.- find contours with Laplacian
A2=del2(double(A1))
figure(2);imshow(A2)
% the Laplacian detects contours but the range is now [-191.25 382.5] and type double
% 3.- calculate all contour points % split into 2 areas each one containing one of the shapes
[sz1a2 sz2a2]=size(A2)
S1=A2(:,[1:floor(sz2a2/2)]) % left
S2=A2(:,[floor(sz2a2/2)+1:sz2a2]) % right
figure(3);h_im_S1=imshow(S1)
figure(4);h_im_S2=imshow(S2)
S1xy=h_im_S1.CData
S2xy=h_im_S2.CData
% this
% S1xy(S1xy<125)=0;S1xy(S1xy>=125)=255;
% S2xy(S2xy<125)=0;S2xy(S2xy>=125)=255;
% now doesn't work because it removes contour points on straight lines, keeping only contour points
% when contour changing direction, instead clean this way:
min_S1xy=min(min(S1xy))
S1xy(find(S1xy<0))=S1xy(find(S1xy<0))+abs(min_S1xy)
S1xy(find(S1xy>10))=S1xy(find(S1xy>10))+abs(min_S1xy)
S1xy(find(S1xy>255))=255 % clipping

min_S2xy=min(min(S2xy))
S2xy(find(S2xy<0))=S2xy(find(S2xy<0))+abs(min_S2xy)
S2xy(find(S2xy>10))=S2xy(find(S2xy>10))+abs(min_S2xy)
S2xy(find(S2xy>255))=255 % clipping
% 4.- skim: for each pair [255 255] null one of them, not implemented.
% without skimming now we have a tops 2 pixels wide line defining edges
S1xy=uint8(S1xy)
S2xy=uint8(S2xy)
[L11 L12]=ind2sub(size(S1xy),find(S1xy>200)) % L12 is x
[L21 L22]=ind2sub(size(S2xy),find(S2xy>200)) % L22 is x
% checking not having crossed x and y
% figure(3);h_im_S1=imshow(S1)
% figure(4);h_im_S2=imshow(S2)
% figure(3);hold all;plot(L12,L11,'ro')
% figure(4);hold all;plot(L22,L21,'ro')
% this line
L22=L22+floor(sz2a2/2)
% puts together both shapes to measure distances between all points of contour 1 % to all points of contour 2
L11=uint64(L11);L12=uint64(L12);L21=uint64(L21);L22=uint64(L22);
% again checking contour points on expected shape edges
figure(2);imshow(A2)
figure(2);hold all;plot(L12,L11,'ro')
figure(2);hold all;plot(L22,L21,'ro')
now that we have coordinates of all contour points lets find all possible distances between both contours.
in this problem it would be ambiguous to define distance between these 2 shapes other that the minimum distance. In doing so it would fail to comply with 2nd and 3rd conditions for a measure to be defined as distance:
For a given set and geometry (locations attitudes ..) there can only be one distance, to develop useful measurements. Otherwise it would not be able to combine starting measurements to reach reliable combinations.
% 5.- the 'horizontal' distance fails to comply with the condition that overlapping or touching objects should have distance zero: .
these 2 objects don't touch but if considering the 'horizontal' distance questioned by Mr Roberts, then they would be touching because the distance is zero. Same confusion would be generated for apparently non-overlapping objects that would be considered to overlap when they actually don't.
the initial question reads 'horizontal' but it's hard to consider the problem would need a MATLAB CENTRAL question for something that can be solved with:
max(L12)-min(L22)
but that is ambiguous and not reliable for the development of further calculations.
% 6.- now the distance you may really want, straight shortest line between the surfaces % of the non-touching non-overlapping objects
% 6.1.- direct assault with 2 for loops: if attempting to solve it with 1-step-wide for loops:
dist_mins=[0 ;0; 0]; % distances logged in dist_mins(1,:)
for i=1:length(L21)
for j=1:length(L11)
dist=((double(L21(i))-double(L11(j)))^2+(double(L22(i))-double(L12(j)))^2)^.5;
dist_mins=[dist_mins [dist;i;j]];
%figure(2);imshow(A2)
%figure(2);hold all;plot(L22(i),L21(i),'ro')
%figure(2);hold all;plot(L12(j),L11(j),'ro')
%figure(2);hold all;plot([L22(i) L12(j)],[L21(i) L11(j)],'r')
end;
end;
remove initial zeros
dist_mins(:,1)=[]
min(dist_mins(1,:)) =
97.185389848474657
find where in the log variable dist_mins
find(dist_mins(1,:)==min(dist_mins(1,:))) =
527
dist_mins(:,527) =
1.0e+02 *
0.971853898484747
0.010000000000000
5.270000000000000
let's plot the result:
i=1;j=527
j =
527
figure(2);imshow(A2)
figure(2);hold all;plot(L22(i),L21(i),'ro')
figure(2);hold all;plot(L12(j),L11(j),'ro')
figure(2);hold all;plot([L22(i) L12(j)],[L21(i) L11(j)],'r')
If you find this answer of any help solving your question, please click on the thumbs-up vote link,
thanks in advance
John