群集生长的blob

时间:2015-02-08 06:54:00

标签: performance matlab image-processing shortest-path

考虑以下来自Mathworks的图像:

enter image description here

我用

标记了斑点
 [L, num]= bwlabel(I);

如何迭代连接所有blob,即启动一个blob并找到最近的blob。考虑最左边的两个blob,可以有很多行可以从blob的许多点绘制来连接到另一个blob,但最短的一个将通过找到最接近另一个blob的blob的像素,在另一个blob中找到一个相似的像素并连接这两个像素来获得。我想以这种方式连接它们。连接它们后,使它们成为单个blob,找到最接近这个新blob的blob连接它们,依此类推,直到所有整个图像都有一个封闭的结构?此外,斑点不总是圆形的,它们是随机的形状。

这里也提出了类似的问题:

How to find the shortest path between two blobs(contours/closed curves) using MATLAB?
http://in.mathworks.com/matlabcentral/newsreader/view_thread/270149

使用bwdist(),我可以分离两个blob并使用暴力方法通过测试第二个链接中提到的两个blob中的所有像素对来找到最短距离但是它需要很长时间。在那里更好的方法来解决这个问题,以便更快地获得结果?

修改

这是另一张图片:

enter image description here

必填图片:

enter image description here

1 个答案:

答案 0 :(得分:3)

方法#1:与质心点连接

%// Read image, convert to binary and remove some whitish border across it
im = im2bw(imread('http://i.stack.imgur.com/vUsrl.png'));
BW = im(3:end-2,3:end-2);
figure, imshow(BW), title('Starting/Original Image')

%// Find centroid points for each blob
cpts = reshape(round(struct2array(regionprops(BW,'Centroid'))),2,[])'; %//'

%// Initialize 2 groups- "hungry" & "feeder" groups, naming them as grp1 & grp2
grp1 = []; grp2 = cpts;

%// Initialize the blob index matching IDs
R = 1; C = 1;

while ~isempty(grp2)

    %// Get one from Group-2 into Group 1 based on the closest one that was
    %//obtained from the previous iteration. Remove that from Group -2.
    grp1 = [grp1 ; grp2(C,:)];
    grp2(C,:) = [];

    %// Find squared distances between those two groups
    sq_distmat = squared_dist(grp1,grp2);

    %// Find the IDs minimum one across row and column which would be the
    %IDs for group 1 and 2 respectively, calling them as R and C
    [~,idx] = min(sq_distmat(:));
    [R,C] = ind2sub(size(sq_distmat),idx);

    %// Draw the connecting line
    BW = linept(BW, grp1(R,2), grp1(R,1), grp2(C,2), grp2(C,1));

end
figure, imshow(BW), title('Final Connected Image')

相关功能 -

function sq_distmat = squared_dist(A,B)

[nA,dim] = size(A);
nB = size(B,1);

A_ext = ones(nA,dim*3);
A_ext(:,2:3:end) = -2*A;
A_ext(:,3:3:end) = A.^2;

B_ext = ones(nB,dim*3);
B_ext(:,1:3:end) = B.^2;
B_ext(:,2:3:end) = B;

sq_distmat = A_ext * B_ext.';

return;

动画乐趣 -

enter image description here


方法#2:连接轮廓点

%// Read image, convert to binary and remove some whitish border across it
im = im2bw(imread('http://i.stack.imgur.com/vUsrl.png'));
BW = im(3:end-2,3:end-2);

%// Find boundary points as a cell array
bpts_cell = bwboundaries(BW);

%// Initialize 2 groups- "hungry" & "feeder" groups, naming them as grp1 & grp2
grp1c = []; grp2c = bpts_cell;

ID = 1;
for iter = 1:numel(bpts_cell)-1

    %// Get one from Group-2 into Group 1 based on the closest one that was
    %obtained from the previous iteration. Remove that from Group -2.
    grp1c = [grp1c ; grp2c(ID)];
    grp2c(ID,:) = [];
    grp1 = vertcat(grp1c{:});
    grp2 = vertcat(grp2c{:});

    %// Find squared distances between those two groups
    sq_distmat = squared_dist(grp1,grp2);

    %// Find the IDs minimum one across row and column which would be the
    %IDs for group 1 and 2 respectively, calling them as R and C
    [~,idx] = min(sq_distmat(:));
    [R,C] = ind2sub(size(sq_distmat),idx);

    %// Draw the connecting line
    BW = linept(BW, grp1(R,1), grp1(R,2), grp2(C,1), grp2(C,2));

    lens = cellfun('length',grp2c);
    clens = cumsum(lens);    
    ID = find(C<=clens,1);
end

动画乐趣 -

enter image description here

带有编辑图像的动画输出 -

enter image description here