特定物体与其他物体之间的最短距离

Shortest distance between a specific object to other objects

在这两个处理查找二值图像中对象之间距离的帖子之后,我如何才能 output/calculate 仅 output/calculate 特定对象与其余对象之间的最短距离(例如,{1->3 }, {2->5}, {3->1}, {4->7)?

脚本:

clc;
clear all;
I = rgb2gray(imread('E:/NCircles.png'));
imshow(I);
BW = imbinarize(I,'adaptive');
BW = imfill(BW, 'holes');
BW = bwlabel(BW); 

s = regionprops(BW,'Area', 'BoundingBox', 'Eccentricity', 'MajorAxisLength', 'MinorAxisLength', 'Orientation', 'Perimeter','Centroid');


imshow(BW)
hold on
for k = 1:numel(s)
    c = s(k).Centroid;
    text(c(1), c(2), sprintf('%d', k), 'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle');
end

boundaries = bwboundaries(BW);
numberOfBoundaries = size(boundaries, 1);
for k = 1 : numberOfBoundaries
    thisBoundary = boundaries{k};
    plot(thisBoundary(:,2), thisBoundary(:,1), 'r', 'LineWidth', 3);
end
hold off;

% Define object boundaries
numberOfBoundaries = size(boundaries, 1)

for b1 = 1 : numberOfBoundaries
    for b2 = 1 : numberOfBoundaries
        if b1 == b2
            % Can't find distance between the region and itself
            continue;
        end
        boundary1 = boundaries{b1};
        boundary2 = boundaries{b2};
        boundary1x = boundary1(:, 2);
        boundary1y = boundary1(:, 1);
        x1=1;
        y1=1;
        x2=1;
        y2=1;
        overallMinDistance = inf; % Initialize.
        % For every point in boundary 2, find the distance to every point in boundary 1.
        for k = 1 : size(boundary2, 1)
            % Pick the next point on boundary 2.
            boundary2x = boundary2(k, 2);
            boundary2y = boundary2(k, 1);
            % For this point, compute distances from it to all points in boundary 1.
            allDistances = sqrt((boundary1x - boundary2x).^2 + (boundary1y - boundary2y).^2);
            % Find closest point, min distance.
            [minDistance(k), indexOfMin] = min(allDistances);
            if minDistance(k) < overallMinDistance
                x1 = boundary1x(indexOfMin);
                y1 = boundary1y(indexOfMin);
                x2 = boundary2x;
                y2 = boundary2y;
                overallMinDistance = minDistance(k);
            end
        end
        % Find the overall min distance
        minDistance = min(minDistance);
        % Report to command window.
        fprintf('The minimum distance from region %d to region %d is %.3f pixels\n', b1, b2, minDistance);

        % Draw a line between point 1 and 2
        line([x1, x2], [y1, y2], 'Color', 'y', 'LineWidth', 3);
    end
end 

给定如上定义的 BWboundaries,以及计算到所有其他对象的距离的源对象:

source_object = 1;   % label of source object in BW

使用bwdist:

构造一个距离图像,使每个像素的值是它与源对象的距离
% anonymous function to convert cell array of subsripts
% into cell array of indices
indsfun = @(a) sub2ind(size(BW), a(:,1), a(:,2));

% use function on all of the cell's boundary objects
object_inds = cellfun(indsfun, boundaries, 'UniformOutput', false);


source_image = zeros(size(BW));   % create image containing only source object
source_image(object_inds{source_object}) = 1;

% compute distance from source to all other pixels in image
dist_image = bwdist(source_image, 'euclidean');   % replace with desired metric
imagesc(dist_image);   % not necessary, but gives a cool image

现在,对于原始图像中的每个对象,找到其边界到源对象边界的最小距离:

min_dist = zeros(1,numel(boundaries));   % hold minimum distances

for target_object = 1:numel(boundaries)
   % get the distance values at the indices of the target object
   % and store the minimum.
   min_dist(target_object) = min(dist_image(object_inds{target_object}));
end

最后,min_dist 将包含从源对象到所有其他对象的最小(边界)距离。您图像上的示例 运行 给出以下欧几里得距离:

min_dist =

 Columns 1 through 7:
     0.00000    67.54258    60.00000   207.23416   154.48625   168.79869   319.01410

 Columns 8 through 13:
   236.05296   324.71063   344.05814   367.00000   469.07996   509.00000