Filling a specific region with a colour
古いコメントを表示
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.
回答 (3 件)
Image Analyst
2013 年 8 月 5 日
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 件のコメント
Simon
2016 年 8 月 22 日
Thanks for this information and code. The code with example worked well. But when I provided my own *.tif file I got the following errors:
Error using imageDisplayValidateParams>validateCData (line 117) Unsupported dimension.
Error in imageDisplayValidateParams (line 31) common_args.CData = validateCData(common_args.CData,image_type);
Error in imageDisplayParseInputs (line 79) common_args = imageDisplayValidateParams(common_args);
Error in imshow (line 198) [common_args,specific_args] = ...
Error in FillAnArbitraryRegionWithColor_01 (line 29) imshow(grayImage, []);
How resolve these errors. Thanks
Simon
2016 年 8 月 22 日
As an alternative - instead of marking a region, if the boundary is defined by (x,y) coordinates how to color within the region defined by the (x,y) coordinates? Thanks
Image Analyst
2016 年 8 月 24 日
Attach your tiff file. Somehow it seems like it didn't get into a proper 2D array that could be considered as a gray scale image.
I'm not sure of your question. In my code xy is the list of (x,y) coordinates. You can create those in any way - it doesn't have to be with imfreehand().
Fed
2020 年 9 月 3 日
Hello,
I'm working on multiple masks on the same image.
Imm = imread('lena .bmp');
figure(1)
imshow(Imm)
title('Original image')
% Message
message = sprintf('Left click and hold to begin drawing.\nSimply lift the mouse button to finish\nDouble tap on at any point of the image after having drawn the desired number of masks.');
uiwait(msgbox(message));
hFH = drawfreehand();
%Mask creation
binaryImage = hFH.createMask();
sz = size(binaryImage); %dimension of the output mask
totMask = false(sz);
while sum(binaryImage(:)) > 10 %Less than 10 pixels are considered an empty mask
totMask = totMask | binaryImage;
hFH = drawfreehand(); %Drawing another mask
binaryImage = hFH.createMask();
end
%Show the final result
figure(2)
imshow(totMask)
title('Multiple masks');
Do you know how to consider only one of the masks drown and extract it from the loop in order to save it in a new variable? I can't figure how to do it.
Thank you in advance.
Image Analyst
2020 年 9 月 3 日
Call imwrite() or save() with binaryImage. I have no idea which one you want to save if there are several of them drawn. Maybe you can use questdlg() to ask the user.
Image Analyst
2020 年 9 月 4 日
Try imoverlay().
Susan
2013 年 8 月 5 日
0 投票
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
2020 年 9 月 2 日
0 投票
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 件のコメント
Image Analyst
2020 年 9 月 2 日
I've attached some demos that may help. If you want something more specific, hopefully you'll figure out how to adapt them. Basically you need to get your region then do the math on pixels in that region. You can either do it only on pixels in that region using indexing, or you can do it on the whole image and just replace the original pixels with the pixels in that region.
Sara Macchiavello
2020 年 9 月 2 日
Thank you very much!
I tried to use the code above obtaining a blurred irregular portion of my image
Imm = imread('lena .bmp');
[rows, columns, numberOfColorChannels] = size(Imm);
imshow(Imm, []);
axis on;
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.
imshow(Imm, []);
axis on;
drawnow;
% Display the freehand mask.
imshow(binaryImage);
axis on;
h = ones(30,30)/900; %filter
% filtraggio piano per piano per applicare il blurring circolare anche
% all'immagine RGB
filtered_im = zeros(size(Imm));
filtered_im(:,:,1) = roifilt2(h, Imm(:,:,1), binaryImage);
filtered_im(:,:,2) = roifilt2(h, Imm(:,:,2), binaryImage);
filtered_im(:,:,3) = roifilt2(h, Imm(:,:,3), binaryImage);
filtered_im = uint8(filtered_im); %convertion
figure
imshow(filtered_im)
title('Blurring RGB image');

Now I have to obtain a similar result but, instead of blurring, with saturation, contrast or luminance variation. Do you know how I could obtain this result?
I already tried using HSV image to modify saturation but I note a wrong bluish color in image.
Imm = imread('lena .bmp');
[rows, columns, numberOfColorChannels] = size(Imm);
imshow(Imm, []);
axis on;
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.
imshow(Imm, []);
axis on;
drawnow;
% Display the freehand mask.
imshow(binaryImage);
axis on;
hsvImage = rgb2hsv(Imm);
hueImage = hsvImage(:, :, 1);
saturationImage = hsvImage(:, :, 2);
valueImage = hsvImage(:, :, 3);
% Increase saturation.
someFactor = 1.6;
saturationImage = saturationImage * someFactor;
% Recombine original saturation and value channels
% with new hue channel.
hsvImage = cat(3, hueImage, saturationImage, valueImage);
% Convert back to RGB color space.
rgbImage = hsv2rgb(hsvImage);
% Display the image.
imshow(rgbImage);
%apply only on the specific region
Imm(binaryImage) = rgbImage(binaryImage);
imshow(Imm);

I also tried to apply an indexing technique but it's not very clear what I should do in the code.
Thank you in advance,
Sara
Image Analyst
2020 年 9 月 3 日
編集済み: Image Analyst
2020 年 9 月 3 日
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
2020 年 9 月 3 日
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?
カテゴリ
ヘルプ センター および File Exchange で Red についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!