Is there any way to fill the inner region of this star by white color without imfill
function?
-
2you can implement the [flood-fill](https://en.wikipedia.org/wiki/Flood_fill) algorithm yourself.. That's what the `imfill` function does. – Amro Mar 30 '16 at 18:41
-
Thanks, I also thought about 2 for loops that paints sequence of pixels to white from first white and until first black. Is there are any other ways to do that? – Vlad Mar 30 '16 at 18:46
-
To quote the docs: `BW2= imfill(BW,'holes') fills holes in the binary image BW. In this syntax, a hole is a set of background pixels that cannot be reached by filling in the background from the edge of the image.`. For example: http://stackoverflow.com/a/1717015/97160 – Amro Mar 30 '16 at 18:48
-
@Vlad: why do you not want to use `imfill`. Your idea should also work, have you tried to implement it? – Matthias W. Mar 30 '16 at 19:24
-
I have an assignment to implement it without using `imfill` with 2 or 3 different algorithms. – Vlad Mar 30 '16 at 19:31
3 Answers
I guess what you want is Polygon Filling. But you have to sort the points and the edges, and then fill everything.
An other simpler solution would be to label all the black components (Union-Find algorithm), and color the ones that do not touch the border.

- 5,597
- 12
- 30
- 58
The following solution is based on you knowing the corners of the polygon that is your star. If that is the case, you can use poly2mask
to generate a matrix with corresponding filled pixels (value 1
) inside (and at the border of) the star and empty pixels (value 0
) outside of the star border.
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
Used e.g. as
boxSize = 500; %// 500x500 pixels
filledStar = createFilledStar(boxSize);
imagesc(filledStar), colormap gray, axis equal

- 70,367
- 12
- 127
- 192
If you don't want to use a pre-built matlab function you can use this code. Basically the code check where are the boundary and fill the star horizontally then unfill vertically the part that "can't be seen horizontally"
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);

- 10,614
- 1
- 17
- 33