MATLAB中填充两个连接组件之间的区域。

7

我有一个在MATLAB中表示数字的二进制图像:

image description

我想要填充所有数字。期望的结果是:

enter image description here

我唯一找到的是 imfill 函数,但这并没有真正帮助我,因为我失去了内部数据(例如9的内部圆)。

3个回答

6
另一种可能性是使用BWBOUNDARIES函数,该函数:

跟踪对象的外部边界以及这些对象内部孔的边界

该信息包含在第四个输出A中,这是一个表示父子孔依赖关系的邻接矩阵。

%# read binary image
bw = imread('SUvif.png');

%# find all boundaries
[B,L,N,A] = bwboundaries(bw, 8, 'holes');

%# exclude inner holes
[r,~] = find(A(:,N+1:end));        %# find inner boundaries that enclose stuff
[rr,~] = find(A(:,r));                      %# stuff they enclose
idx = setdiff(1:numel(B), [r(:);rr(:)]);    %# exclude both
bw2 = ismember(L,idx);                      %# filled image

%# compare results
subplot(311), imshow(bw), title('original')
subplot(312), imshow( imfill(bw,'holes') ), title('imfill')
subplot(313), imshow(bw2), title('bwboundaries')

enter image description here


很好!我有一种感觉,认为一定有一个Matlab函数可以做到这一点,但不知道它是什么。 - Andrey Rubshtein

4
问题是如何区分数字中的孔洞。一种可能的临时解决方案是通过像素内部的面积对它们进行过滤。
function SolveSoProblem()

    I = imread('http://i.stack.imgur.com/SUvif.png');

    %Fill all the holes 
    F = imfill(I,'holes');

    %Find all the small ones,and mark their edges in the image
    bw = bwlabel(I);
    rp = regionprops(bw,'FilledArea','PixelIdxList');
    indexesOfHoles = [rp.FilledArea]<150;   
    pixelsNotToFill = vertcat(rp(indexesOfHoles).PixelIdxList); 
    F(pixelsNotToFill) = 0;
    figure;imshow(F);

    %Remove the inner area
    bw1 = bwlabel(F,4);
    rp = regionprops(bw1,'FilledArea','PixelIdxList');
    indexesOfHoles1 = [rp.FilledArea]<150;
    pixelListToRemove = vertcat(rp(indexesOfHoles1).PixelIdxList);
    F(pixelListToRemove) = 0;

    figure;imshow(F);
end

步骤(1)之后:

输入图片描述

步骤(2)之后:

输入图片描述


1
令人印象深刻的解决方案。 非常感谢! 我唯一改变的小事情就是删除了图像空间小于图像2%的对象,它运行得很好!! - user1240792

0

假设左上角像素始终在要填充的区域之外:

沿着顶部线工作,将像素复制到输出图像中

当您在输入图像中遇到白色像素后跟随黑色像素时,请开始在输出图像中设置白色像素,直到您遇到白色像素后跟随黑色像素。


@EitanT:确实如此——我是根据提供的示例进行的。 - Martin Thompson
1
@MartinThompson 这些图像是二进制的,所以你收到的评论是不相关的。 - mmgp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接