How to fill the region of interest by white color

Hi All,
I have this Black and white mask
I want to fill the region of interest to be like this
approximatlly by white color to use it for segmentation later,please any could help by a Matlab code to do this job,thanks in advance.

 Accepted Answer

See this demo which uses activecountour to get the outer envelope:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures if you have the Image Processing Toolbox.
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 15;
% Read in a demo image.
folder = 'D:\Temporary stuff';
baseFileName = '4_400_before.png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% File doesn't exist -- didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[rows, columns, numberOfColorBands] = size(grayImage);
if numberOfColorBands > 1
% It's not really gray scale like we expected - it's color.
% Convert it to gray scale by taking only the green channel.
grayImage = grayImage(:, :, 2); % Take green channel.
end
% Display the original gray scale image.
subplot(2, 2, 1);
imshow(grayImage, []);
axis on;
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
subplot(2, 2, 2);
mask = false(rows, columns);
mask(50:300,20:300) = true;
imshow(mask);
axis on;
title('Initial mask', 'FontSize', fontSize);
drawnow;
% Now find the outer boundary.
bw = activecontour(grayImage, mask, 400, 'edge');
subplot(2, 2, 3);
imshow(bw);
axis on;
title('Outer Boundary Mask', 'FontSize', fontSize);
drawnow;
% Display the original gray scale image in the lower left
% So we can display boundaries over it.
subplot(2, 2, 4);
imshow(grayImage, []);
axis on;
hold on;
% Display the initial contour on the original image in blue.
% Display the final contour on the original image in red.
contour(mask,[0 0],'b', 'LineWidth', 2);
contour(bw,[0 0],'r', 'LineWidth', 4);
title('Image with initial and final contours overlaid', 'FontSize', fontSize);
msgbox('Done with activecontour demo');

13 Comments

For others who may be interested, I've attached a demo using the standard coins demo image.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures if you have the Image Processing Toolbox.
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 15;
% Read in a standard MATLAB gray scale demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
baseFileName = 'coins.png';
% baseFileName = 'eight.tif';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% File doesn't exist -- didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[rows, columns, numberOfColorBands] = size(grayImage);
if numberOfColorBands > 1
% It's not really gray scale like we expected - it's color.
% Convert it to gray scale by taking only the green channel.
grayImage = grayImage(:, :, 2); % Take green channel.
end
% Display the original gray scale image.
subplot(2, 2, 1);
imshow(grayImage, []);
axis on;
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
% Let's compute and display the histogram.
[pixelCount, grayLevels] = imhist(grayImage);
subplot(2, 2, 2);
bar(grayLevels, pixelCount);
grid on;
title('Histogram of original image', 'FontSize', fontSize);
xlim([0 grayLevels(end)]); % Scale x axis manually.
% Construct an initial mask that is the convex hull of everything.
subplot(2, 2, 2);
% mask = grayImage < 175; % Use for eight.tif
mask = grayImage > 80; % Use for coins.png
mask = bwconvhull(mask, 'Union');
imshow(mask);
axis on;
title('Initial mask', 'FontSize', fontSize);
drawnow;
% Now find the improved outer boundary using active contours.
bw = activecontour(grayImage, mask, 400, 'edge');
subplot(2, 2, 3);
imshow(bw);
axis on;
title('Outer Boundary Mask', 'FontSize', fontSize);
drawnow;
% Display the original gray scale image in the lower left
% So we can display boundaries over it.
subplot(2, 2, 4);
imshow(grayImage, []);
axis on;
hold on;
% Display the initial contour on the original image in blue.
% Display the final contour on the original image in red.
contour(mask,[0 0],'b', 'LineWidth', 4);
contour(bw,[0 0],'r', 'LineWidth', 4);
title('Image with initial and final contours overlaid', 'FontSize', fontSize);
msgbox('Done with activecontour demo');
Image Analyst ,I appreciate and thank you very much for your effort to help me,now I tried the concave hull demo you gave me,but I got this
with green boundary,so I tried your pretty good and excellent solution,please I want to fill the boundary automatically because I have many images for melanoma detection and the lesion may be in different locations in the image like this
where the activecontour works in a specific initial mask like that you suggested
*mask(50:300,20:300) = true;* ,( *with my thanks to you of course* )it is not automated,so I need to detect the edge of the lesion the by *Ant Colony Optimization for edge detection* then use it as a mask for segmentation then apply features extraction method on it,Thank you for your understanding my situation.
Explain why you think the code that uses activecontour is not automatated. It looks automated to me. It started with the broken edges you gave, and ended with a reasonable mask with a solid contour. Sure there were some lines of code to do that but nothing where the user had to manually draw or select something in the image. Please define automated because you're using a different definition than me.
Thank you very much and I hope that I did not bother you at the beginning of the New Year,I think the selection of mask values at constant values as mask(50:300,20:300) = true,break the meaning of automated,I mean that this mask should be dynamic to be general for all types of images,do you agree with me?
Look where I used the starting mask (your ant image) with bwconvhull() to get the starting mask for activecontour.
startingMask = bwconvhull(antImage, 'Union');
finalMask = activecontour(antImage, startingMask, 400, 'edge');
This is not defining via hard coding some mask in a fixed position. It's dependent on the image. Use bwconvhull() like that if you want something more automated. So you would pass your ant edge image into bwconvhull() to get the starting mask, then pass into activecontour() to get the final mask. I think that should be good.
Please could you explain how can do that in matlab code because I am afraid to make some mistake where I am not professional like you in Matlab coding.
I gave you the two lines for you to use. Below I put them in and also I could reduce the number of activecontout iterations from 400 to 150 because the starting mask is closer to the desired mask if we start with a convex hull instead of a big rectangle. Here is the code:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures if you have the Image Processing Toolbox.
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 15;
% Read in a demo image.
folder = 'D:\Temporary stuff';
baseFileName = '4_400_before.png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% File doesn't exist -- didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[rows, columns, numberOfColorBands] = size(grayImage);
if numberOfColorBands > 1
% It's not really gray scale like we expected - it's color.
% Convert it to gray scale by taking only the green channel.
grayImage = grayImage(:, :, 2); % Take green channel.
end
% Display the original gray scale image.
subplot(2, 2, 1);
imshow(grayImage, []);
axis on;
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
subplot(2, 2, 2);
% Turn grayscale image into a binary image.
% Threshold it and get rid of that one pixel wide border all the way around the image.
mask = imclearborder(grayImage > 0);
mask = bwconvhull(mask, 'Union');
imshow(mask);
axis on;
title('Initial mask', 'FontSize', fontSize);
drawnow;
% Now find the outer boundary.
bw = activecontour(grayImage, mask, 150, 'edge');
subplot(2, 2, 3);
imshow(bw);
axis on;
title('Outer Boundary Mask', 'FontSize', fontSize);
drawnow;
% Display the original gray scale image in the lower left
% So we can display boundaries over it.
subplot(2, 2, 4);
imshow(grayImage, []);
axis on;
hold on;
% Display the initial contour on the original image in blue.
% Display the final contour on the original image in red.
contour(mask,[0 0],'b', 'LineWidth', 2);
contour(bw,[0 0],'r', 'LineWidth', 4);
title('Image with initial and final contours overlaid', 'FontSize', fontSize);
msgbox('Done with activecontour demo');
Image Analyst you are Excellent I dont know what I must say more than to you?You really did it ,I'll test it on the another images and I'll be back to tell you,thank you very very much,smart and professional Image Analyst.
You're welcome. Can you accept one of my answers (not one of yours)?
Dear Image Analyst, Of course,and I am sorry to be late to accept your answers;because I went happy to bed yesterday for you solution to my question and did n't check the http://www.mathworks.com/ because I was busy all today,again I am sorry.
As Has comments to Image Analyst:
Active contour
Can't we use rgb2gray() instead of taking only the Green channel?
You can do whatever you want. If you have an image with continuous colors, then using rgb2gray() will take the weighted average of the 3 color channels (that's a lot of computations). However if your image is already gray scale (all three color channels are identical), then taking just one of them will be faster since no math needs to take place. If you're going to take just one of them, you should look at the channels first to determine which of them gives you the most contrast. Chances are you can pick just one of the color channels and it will give you more contrast, making the segmentation you'll do next easier, than the contrast of the average of the R, G, and B channels.

Sign in to comment.

More Answers (2)

Your gaps are fairly big and are going to cause you problems, I suspect.

9 Comments

Thanks Walter Roberson,I used se=strel('disk',2); imclose(bwimage,se), But I did not get the properate result!, Then I tried to use bwboundaries(BW)to fill within boundary ,But I could not!
Could anyone help me please?
Image Analyst,could you help me?I read your answer for someone to fill the ROI only when the edge of ROI was red ,but I couldn't find the answer now by searching,please where can I find it?
I used this http://www.mathworks.com/matlabcentral/fileexchange/25157-image-segmentation-tutorial-blobsdemo Demo of Image Analyst for blobs detection I got this
but how can I fill within detected boundary
Link doesn't work. Please fix it. Did you adjust the threshold to the best value as you were following the demo? I also have an app for that in my File Exchange.
I attached the image of boundary after detection
Sorry I couldn't attached in comment,so is attaced as an answer
Consider using Alpha Shapes. The effect can be like putting an elastic band around the object, effectively closing the curve.
Alpha shapes might be good. Sometimes the boundary can go inside the points so you have to be aware of how you do it to make sure it gives you a boundary you are happy with. Concave hull doesn't go inside points (I don't think) though it can jump gaps. I don't have experience with alpha shapes (though I'd like to) but I do have experience with concave hulls.

Sign in to comment.

How did you get that bad mask in the first place? I think it might be better to improve it from the start than to try to fix up a bad one. If you need to use that one I'd just close with a bigger disk, or use imline to burn a line into the images manually, or use edge linking methods, or use the concave hull (restricted convex hull, demo attached).

10 Comments

I used the ant algorithm for edge detection (I must use it). I want to do all operations (automatically),How can fill the boundary by white color?
Please can I have an answer?
Why there is no answer,please help me
Sometimes I have to leave the house to do things like buy food.
hamed, it is New Years Eve in North America. We have celebration preparations to make. And house-work to do. And other people to answer here. And several other forums on various topics that we are dealing with as well.
Also with the effect of the wind, the temperature outside my house is -40C at the moment (-48C last night) so I am on edge about whether my furnace will break or not.
So, did you try the concave hull demo I gave you?
Why do you have to use ant? What is the original image? What is the bottom image in your original question? It looks masked - how did you do that if your edges are broken? What's the original unmasked image look like, so I can see if edge detection is best or if you can get by with simple thresholding? Did you try anything I suggested? I'm not inclined to offer more until I get my questions answered.
Which "ant algorithm" ? Ant Colony Optimization?
Not sure, but that's what I assumed. It's the only ant algorithm I've ever heard of.

Sign in to comment.

Categories

Asked:

on 31 Dec 2013

Moved:

DGM
on 13 Feb 2023

Community Treasure Hunt

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

Start Hunting!