Fill a circle enclosed by it's circumference (of type double) with white.

3 views (last 30 days)
I want to fill a specific region on an image with white (value 255). The specific region forms a circle. (whose co-ordinates of centre and circumference are calculated)
1. I used imfill but the co-ordinates of circle are of type double. Hence I got an error. When I convert the co-ordinates to to uint16, the co-ordinates don't form a contour (closed figure). Hence I can't use imfill.
2. I used roifill which accepts circumference co-ordinates of type double. It fills the values with a grey shade and not exactly 255.
Is there a way by which I can use roifill but fill it with white (instead of smoothing and filling with a shade of gray)? Or can I use the imfill command itself so that it accepts input of type double? Or is there anything else I can do?
I have attached the co-ordinates of circle's circumference which I have calculated and the centre of circle. I have also attached the image on which I am plotting the circle (if required). I want to make the pixels which lie inside this circle white and the others black.

Accepted Answer

Image Analyst
Image Analyst on 14 Mar 2015
Try this:
clc;
workspace; % Make sure the workspace panel with all the variables is showing.
format long g;
format compact;
fontSize = 20;
% Check that user has the Image Processing Toolbox installed.
hasIPT = license('test', 'image_toolbox');
if ~hasIPT
% User does not have the toolbox installed.
message = sprintf('Sorry, but you do not seem to have the Image Processing Toolbox.\nDo you want to try to continue anyway?');
reply = questdlg(message, 'Toolbox missing', 'Yes', 'No', 'Yes');
if strcmpi(reply, 'No')
% User said No, so exit.
return;
end
end
%==========================================================================
baseFileName = 'sanofi.png';
folder = 'C:\Users\meghana\Documents\Temporary';
% 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.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, '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, 3, 1);
imshow(grayImage, []);
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')
% Let's compute and display the histogram.
[pixelCount, grayLevels] = imhist(grayImage);
subplot(2, 3, 2);
bar(grayLevels, pixelCount);
grid on;
title('Histogram of original image', 'FontSize', fontSize);
xlim([0 grayLevels(end)]); % Scale x axis manually.
% Find mask
mask = grayImage > 100;
% Fill holes
mask = imfill(mask, 'holes');
% Erode it to make it smaller
mask = imerode(mask, true(90));
% Display the mask image.
subplot(2, 3, 3);
imshow(mask, []);
axis on;
title('Mask Image', 'FontSize', fontSize);
% Mask the image.
maskedImage = grayImage .* uint8(mask);
% Display the original gray scale image.
subplot(2, 3, 4);
imshow(maskedImage, []);
title('Masked Image', 'FontSize', fontSize);
% Mask again finding dark things
binaryImage = maskedImage > 0 & maskedImage < 175;
% Get rid of small specks.
binaryImage = bwareaopen(binaryImage, 100);
% Display the binary image.
subplot(2, 3, 5);
imshow(binaryImage, []);
title('Masked Image of Dark Things', 'FontSize', fontSize);
% Put it on a white background
finalImage = 255 * ones(rows, columns, 'uint8');
% Replace the mask pixels in the binary image of the final image
% with the pixels from the original image.
finalImage(binaryImage) = grayImage(binaryImage);
% Display the final image.
subplot(2, 3, 6);
imshow(finalImage, []);
title('Final Image of Logo', 'FontSize', fontSize);
  1 Comment
Meghana Dinesh
Meghana Dinesh on 16 Mar 2015
Edited: Meghana Dinesh on 16 Mar 2015
Thanks a lot for the code. It works according to what I want for the images which I have attached. However, it doesn't give the required result for all the images I am dealing with ( which I have uploaded on dropbox ). I think using:
mask = grayImage > 100;
isn't a very efficient method in may case. The mask isn't created properly.
Are there any parameters I can tune so that it works for all images?
To avoid all this, what I am doing now is fitting a circle within the contour, and whatever lies outside the circle and inside the circle, making it 0 and 1 respectively (this is my mask). I multiply this mask with the original image. I shall then binarize the image and proceed (or I 'll apply the algorithm which you have shared within this inner circle to extract the pattern)
So the step I am stuck in at present is to find the co-ordinates of circle in uint form and not double. Given the center of circle and radius, how can I find the continuous / connected co-ordinates of pixels on it's circumference? I agree it won't be a smooth circle. It's alright.
Kindly let me know your feedback regarding this.

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 14 Mar 2015
Depends on exactly what you want to do. Do you want to fill the words and logo on the cap with the surrounding gray levels "smeared in"? Or is replacing those pixels with the average gray level of the entire cap good enough? And do you have the latest MATLAB R2015a - the roifill command has been improved. Prior to this version you'll have to dilate the binary image of the letters a little bit before you call roifill(), so that the outer perimeter of the mask actually lies on the white surround rather than on the letters, otherwise you'll get the gray like you said.
  1 Comment
Meghana Dinesh
Meghana Dinesh on 14 Mar 2015
Edited: Meghana Dinesh on 14 Mar 2015
Basically, I want to extract only the pattern within the circle, making the rest of the image white. In order to do this, I want to create an image (img2) of same resolution where the co-ordinates within the circle are white (logic 1) and outside are black (logic 0). So when I do
img_prod = immultiply (img, img2);
I get the output img_prod with only the information contained within the circular region.
Example (for another pattern):
This is what I intend to do in order to get the pattern even for the present image attached. Please let me know if my approach is right.
Further, I am doing this to get a template for a template matching algorithm (which I have described here).
I am using MATLAB R2014b. I will start using MATLAB R2015a in a couple of days.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!