Distance between two objects.
4 次查看(过去 30 天)
显示 更早的评论
Hello everyone. In a binary image how is it possible to calculate the minimum horizontal distance between two objects.
2 个评论
Walter Roberson
2016-3-22
I notice that your objects are irregular shape. It would be possible that the horizontal line of least distance might not be where the objects are furthest right or furthest left. Could you confirm that you want the line along which the two have least horizontal distance, not the horizontal component of the distance between the furthest right and furthest left?
采纳的回答
John BG
2016-3-23
编辑:John BG
2016-3-24
% 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
0 个评论
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!