fill a boundary region with white colour

25 views (last 30 days)
i have identified boundaries from a binary image using
boundaries = bwboundaries(bw);
The output of the above line of code is shown below
[108,69;108,69]
[691,69;691,69]
23x2 double
i wanted to select boundaries{2} and boundaries{3} and fill that region with white colour, how can i do it?
  7 Comments
Elysi Cochin
Elysi Cochin on 29 Nov 2019
Edited: Elysi Cochin on 29 Nov 2019
Thank you Image Analyst sir
Through your previous suggestions itself i did changed the use of bwboundaries
Your below code worked for me
filledBlobs = imfill(bw, 'holes'); % Fill FIRST!
props = regionprops(filledBlobs, 'Area'); % Measure areas of all blobs.
sortedAreas = sort([props.Area], 'descend'); % Get all areas into one vector sorted by decreasing area.
% Use bwareafilt to keep only blobs in the range from the second largest to third largest.
blobs2and3 = bwareafilt(filledBlobs, [sortedAreas(3), sortedAreas(2)]);
% Now erase the 2nd and 3rd blobs from the original bw (unfilled) image.
bw(blobs2and3) = false;
Sir actually i had few set of images, in those set, not all but most of the images had 2nd and 3rd largest blob i wanted to eliminate. So first i thought of keeping only those working images. Then when i tried keeping the range condition for area, few more images worked.
Thank you Image Analyst sir for your detailed explanation. Your suggestions and answers have always been like teachings to me, from the time i have joined Mathworks. Thank you sir
Image Analyst
Image Analyst on 29 Nov 2019
How do you decide which to keep in the various images? What are you looking at? What criteria is it that you check to determine which blobs to keep and which to discard?

Sign in to comment.

Accepted Answer

Thiago Henrique Gomes Lobato
You can transform the contourns in a binary image, fill it and than translate it back to your original image. Here is an example adapted from the matlab bwboundaries documentation.
I = imread('rice.png');
BW = imbinarize(I);
[B,L] = bwboundaries(BW,'noholes');
figure
imshow(label2rgb(L, @jet, [.5 .5 .5]))
hold on
for k = 1:length(B)
boundary = B{k};
if k <length(B)/2 % Half with fill and half without so one can verify the difference between them
% Binary image with same size
Ibinary = I==0;
% Get contourn image and plot it in the binary image
ind = sub2ind(size(Ibinary),boundary(:,2),boundary(:,1));
Ibinary(ind) = 1;
% Close the binary image
Ibinary = imfill(Ibinary,'holes');
% Get combination of index and plot in the figure
Index = find(Ibinary==1);
[row,col] = ind2sub(size(Ibinary),Index);
plot(row,col , 'w', 'LineWidth', 2)
else % Matlab example with only the boundaries
plot(boundary(:,2), boundary(:,1), 'w', 'LineWidth', 2)
end
end
untitled.jpg
  6 Comments
Thiago Henrique Gomes Lobato
It actually shoudn't matter how the different outpus are done, could you maybe post your image?
Guillaume
Guillaume on 24 Nov 2019
"And Guillaume, it is indeed a kind of reverse work, but it could be that the other contours are needed for something else, and if this is indeed the case in your approach one would need use bwlabel, get the needed regions, then either use bwboundaries again or implement the additional routines in the other select regions, also lots of work. If the other contours aren't needed than it would be more efficient"
If the boundaries are needed for something else, then grab the 2nd output of bwboundaries then. It's the same labeled image returned by bwlabel. Tracing the boundaries and the reverse operation of flood filling a boundary are both complex operations, so doing one just to reverse it is a bit of a waste:
[boundaries, labelimage] = bwboundaries(bw); %labelimage is the output of bwlabel(bw) that bwboundaries call.

Sign in to comment.

More Answers (2)

Guillaume
Guillaume on 24 Nov 2019
Edited: Guillaume on 24 Nov 2019
boundaries{2} is only two pixels, there's nothing to fill!
Anyway, if all you want is to fill the region, then bwboundaries is a waste of time. You only need the first step of the bwboundaries algorithm, which is the region labels obtained with bwlabel.
labels = bwlabel(bw);
white = uint8(255); %or 1 if your image is double
bw(ismember(labels, [2 3]) = white; %fill pixels whose labels are 2 or 3 with white.
edit: so it turns out you want to fill the two largest objects of your image. Why didn't you ask help on that to start with?
The easiest way to fill the two largest blobs of image bw:
tofill = bwareafilt(bw, 2, 'largest');
bw(tofill) = 0;
done!

Image Analyst
Image Analyst on 24 Nov 2019
Simply do this:
bw = imfill(bw, 'holes');
since boundaries came from BW, and the first two boundaries are not really closed boundaries, the code above will fill the third boundary in bw.
  4 Comments
Guillaume
Guillaume on 24 Nov 2019
As I explained already, tracing the boundaries of a region just to fill it is a complete waste of time. You've already got all the pixels of each region from bwlabel. You also got them again from regionprops, so using the slow bwboundaries to get something less useful is pointless.
In any case, if you want to fill the two largest blobs, bwareafilt is probably the best function. See edit to my answer.
Image Analyst
Image Analyst on 24 Nov 2019
Right. No need to call bwboundaries(), and better to extract what is wanted in advance with bwareafilt() than to get properties of them with regionprops(), and then figure out from the areas which ones to keep.

Sign in to comment.

Categories

Find more on Image Processing Toolbox in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!