在MATLAB中填充二进制图像而不使用imfill函数

时间:2016-03-30 18:34:13

标签: matlab image-processing

对于像enter image description here

这样的图片

有没有办法用没有imfill功能的白色填充这颗恒星的内部区域?

3 个答案:

答案 0 :(得分:1)

我猜你想要的是Polygon Filling。但是你必须对点和边进行排序,然后填充所有内容。

另一个更简单的解决方案是标记所有黑色组件(Union-Find算法),并为不接触边框的组件着色。

答案 1 :(得分:1)

以下解决方案基于您了解作为星星的多边形的角落。如果是这种情况,您可以使用poly2mask生成一个矩阵,其中包含相应的填充像素(值1),位于星形和空像素内(以及边界处)(值0在星界外面。

E.g。

function filledStar = createFilledStar(boxSize)

%// center star in box
xCenter = boxSize/2;
yCenter = xCenter;

%// setup: star with random rotation
angles = (rand + (0:1/10:1))*2*pi; %// polygon corners, angle
rOuter = boxSize*0.5;              %// star outer radius
rInner = boxSize*0.2;              %// star inner radius

%// generate star polygon corner coordinates
r = [repmat([rOuter rInner],1,5), rOuter];
x = xCenter + r.*cos(angles);
y = yCenter - r.*sin(angles);

%// convert polygon to 0-1 mask (as double) in box
starMask = double(poly2mask(x, y, boxSize,boxSize));

%// (if you'd like to smooth edges), apply gaussian and return
filledStar = imgaussfilt(starMask,1);

end

用于例如如

boxSize = 500; %// 500x500 pixels
filledStar = createFilledStar(boxSize);

imagesc(filledStar), colormap gray, axis equal

enter image description here

答案 2 :(得分:1)

如果您不想使用预先构建的matlab函数,可以使用此代码。基本上代码检查边界在哪里并水平填充星形然后垂直地填充“水平不能看见”的部分

I = im2bw(imread('image.png'));

hliml = zeros(1,size(I,1));
hlimr = zeros(1,size(I,1));
vliml = zeros(1,size(I,2));
vlimr = zeros(1,size(I,2));

for i = 1:size(I,1)
    if ~isempty(find([diff(I(i,:)),0]==1,1,'first'))
hliml(i) = find([diff(I(i,:)),0]==1,1,'first');
    end
    if ~isempty(find([diff(I(i,:)),0]==-1,1,'last'))
hlimr(i) = find([diff(I(i,:)),0]==-1,1,'last');
    end
end

for i = 1:size(I,2)
     if ~isempty(find([diff(I(:,i));0]==1,1,'first'))
vliml(i) = find([diff(I(:,i));0]==1,1,'first');
     end
     if ~isempty(find([diff(I(:,i));0]==-1,1,'last'))
vlimr(i) = find([diff(I(:,i));0]==-1,1,'last');  
     end
end


for i = 1:size(I,1)
    if hliml(i)~=0
        I(i,hliml(i):hlimr(i)) = 1;
    end
end

for i = 1:size(I,2)
     if vliml(i)~=0
        I(1:vliml(i),i) = 0;
        I(vlimr(i):end,i) = 0;
     end
end

imshow(I);

水平填充 step1

垂直展开 step2