Filling a specific region with a colour

53 views (last 30 days)
med-sweng
med-sweng on 5 Aug 2013
Commented: Image Analyst on 4 Sep 2020
Is there a way in MATLAB to fill a specific region with some colour? I looked at roifill, but wasn't clear if it does the work? I selected the area but don't know if a colour can be specified.
Thanks.

Answers (3)

Image Analyst
Image Analyst on 5 Aug 2013
Try this demo:
% Demo to have the user freehand draw an irregular shape over a gray scale image.
% Then it creates new image with a specified color inside the drawn shape.
clc; % Clear command window.
clear; % Delete all variables.
close all; % Close all figure windows except those created by imtool.
imtool close all; % Close all figure windows created by imtool.
workspace; % Make sure the workspace panel is showing.
fontSize = 16;
% Read in a standard MATLAB gray scale demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
baseFileName = 'cameraman.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);
[rows, columns, numberOfColorChannels] = size(grayImage);
imshow(grayImage, []);
axis on;
title('Original Grayscale Image', 'FontSize', fontSize);
set(gcf, 'Position', get(0,'Screensize')); % Maximize figure.
message = sprintf('Left click and hold to begin drawing.\nSimply lift the mouse button to finish');
uiwait(msgbox(message));
hFH = imfreehand();
% Create a binary image ("mask") from the ROI object.
binaryImage = hFH.createMask();
xy = hFH.getPosition;
% Now make it smaller so we can show more images.
subplot(2, 2, 1);
imshow(grayImage, []);
axis on;
drawnow;
title('Original Grayscale Image', 'FontSize', fontSize);
% Display the freehand mask.
subplot(2, 2, 2);
imshow(binaryImage);
axis on;
title('Binary mask of the region', 'FontSize', fontSize);
% If it's grayscale, convert to color
if numberOfColorChannels < 3
rgbImage = cat(3, grayImage, grayImage, grayImage);
else
% It's really an RGB image already.
rgbImage = grayImage;
end
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
% Specify the color we want to make this area.
desiredColor = [146, 40, 146]; % Purple
% Make the red channel that color
redChannel(binaryImage) = desiredColor(1);
greenChannel(binaryImage) = desiredColor(2);
blueChannel(binaryImage) = desiredColor(3);
% Recombine separate color channels into a single, true color RGB image.
rgbImage = cat(3, redChannel, greenChannel, blueChannel);
% Display the image.
subplot(2, 2, 3);
imshow(rgbImage);
title('Image with color inside the mask region', 'FontSize', fontSize);
  7 Comments
Fed
Fed on 4 Sep 2020
Edited: Fed on 4 Sep 2020
Thank you very much, I'll try as you have suggested.
Sorry to bother you again but do you know how I could colour only a part of the mask shown in the cameraman image above? I'm not very skilled on Image Processing yet and can't find a proper solution.

Sign in to comment.


Susan
Susan on 5 Aug 2013
Yes, roifill will fill a region with some color, but you have to specify the color after you draw the region on the image, before you double click to finalize it. The following was from the roifill help file "Changing the color of the polygon: Move the pointer inside the region. Right-click and select Set color from the context menu."
The other way that you can accomplish this, which I prefer, is to use patch objects. To do this, see http://blogs.mathworks.com/steve/2008/08/20/image-visualization-using-transparency/. The blog describes how you can use patch objects to overlay regions on top of the image, but you could just as easily replace the selected region in your image with a colored ROI using the same methods.

Sara Macchiavello
Sara Macchiavello on 2 Sep 2020
Goodmorning,
I found your question very helpful also for my project but I'd like to ask you if working on that region I can modify contrast, saturation or luminance is possible. Do you know if is there the possibility to obtain this effect?
I also tried with roipoly and drawfreehand but I can't obtaint this result.
Thank you,
  4 Comments
Image Analyst
Image Analyst on 3 Sep 2020
Edited: Image Analyst on 3 Sep 2020
Sara, try this. Since you can't Accept this answer since it's not yours, can you at least vote for my Answer (way up at the top) by clicking on the Vote icon?
% Initialization steps.
clc; % Clear the command window.
fprintf('Beginning to run %s.m ...\n', mfilename);
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
rgbImage = imread('lenaColor.png');
[rows, columns, numberOfColorChannels] = size(rgbImage);
imshow(rgbImage, []);
axis on;
set(gcf, 'Position', get(0,'Screensize')); % Maximize figure.
message = sprintf('After you see the cross hairs, \nleft-click and hold to begin drawing.\nSimply lift the mouse button to finish');
uiwait(msgbox(message));
hFH = imfreehand();
% Create a binary image ("mask") from the ROI object.
binaryImage = hFH.createMask();
xy = hFH.getPosition;
% Now make it smaller so we can show more images.
subplot(3, 3, 1);
imshow(rgbImage, []);
axis on;
drawnow;
% Display the freehand mask.
subplot(3, 3, 2);
imshow(binaryImage);
axis on;
% Get the HSV image.
hsvImage = rgb2hsv(rgbImage);
hueImage = hsvImage(:, :, 1);
saturationImage = hsvImage(:, :, 2);
valueImage = hsvImage(:, :, 3);
% Show all the images
subplot(3, 3, 2);
imshow(hsvImage, []);
impixelinfo;
title('HSV Image', 'FontSize', fontSize);
subplot(3, 3, 3);
imshow(hueImage);
impixelinfo;
title('Hue Image', 'FontSize', fontSize);
subplot(3, 3, 4);
imshow(saturationImage);
impixelinfo;
title('Saturation Image', 'FontSize', fontSize);
subplot(3, 3, 5);
imshow(valueImage);
impixelinfo;
title('Value Image', 'FontSize', fontSize);
% Increase saturation but only within the mask area.
someFactor = 1.6;
saturationImage(binaryImage) = saturationImage(binaryImage) * someFactor;
imshow(saturationImage);
impixelinfo;
title('Altered Saturation Image', 'FontSize', fontSize);
% Recombine original saturation and value channels
% with new hue channel.
hsvImage = cat(3, hueImage, saturationImage, valueImage);
subplot(3, 3, 6);
imshow(hsvImage, []);
impixelinfo;
title('Altered HSV Image', 'FontSize', fontSize);
% Convert back to RGB color space.
rgbImage2 = hsv2rgb(hsvImage);
% Display the image.
subplot(3, 3, 7);
imshow(rgbImage2);
impixelinfo;
title('Altered RGB Image', 'FontSize', fontSize);
fprintf('Done running %s.m ...\n', mfilename);
Sara Macchiavello
Sara Macchiavello on 3 Sep 2020
Thank tou very much!
It works and I understood how to apply this also for other transformations that I had to do.
I'd like to ask you something else, because now I need a result with less sharp and marked edges of the irregular region, obtaining a more faded transition between the original image and the modified zone. It there a way to obtain this more realistic result?

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!