Masking out Image area using Binary Mask

Hello
I have an image and I also have a binary mask of the same size(ROI in 1, Background 0). How can I create a new image only with the ROI displayed ?
Is there any difference if the image is grayscale plane or RGB ?
Thank you

 Respuesta aceptada

Kye Taylor
Kye Taylor el 16 de Mayo de 2012
Let I be the m-by-n image, and let M be the m-by-n mask.
The new image, Inew, will be m-by-n and have zeros everywhere there is a zero in M and will be the grayscale value wherever M has a one.
Inew = I.*M;
If the image is RGB (i.e. I is m-by-n-by-3), then use the command
Inew = I.*repmat(M,[1,1,3]);

2 comentarios

function masked = maskout(src,mask)
% mask: binary, same size as src, but does not have to be same data type (int vs logical)
% src: rgb or gray image
masked = bsxfun(@times, src, cast(mask,class(src)));
end
Or the more modern way we've been promoting:
% An alternate method to multiplication channel by channel.
% Mask the image using bsxfun() function
maskedRgbImage = bsxfun(@times, rgbImage, cast(mask, 'like', rgbImage));
When you use cast now, it nags you to use the 'like' keyword instead of a call to the class() function.

Iniciar sesión para comentar.

Más respuestas (3)

Image Analyst
Image Analyst el 16 de Mayo de 2012
Editada: Image Analyst el 22 de Mzo. de 2022
See my demo - it does three different kinds of masking:
% Demo to have the user freehand draw an irregular shape over
% a gray scale image, have it extract only that part to a new image,
% and to calculate the mean intensity value of the image within that shape.
%
% Change the current folder to the folder of this m-file.
if(~isdeployed)
cd(fileparts(which(mfilename)));
end
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 standard MATLAB gray scale demo image.
grayImage = imread('cameraman.tif');
subplot(2, 3, 1);
imshow(grayImage, []);
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();
% Display the freehand mask.
subplot(2, 3, 2);
imshow(binaryImage);
title('Binary mask of the region', 'FontSize', fontSize);
% Calculate the area, in pixels, that they drew.
numberOfPixels1 = sum(binaryImage(:))
% Another way to calculate it that takes fractional pixels into account.
numberOfPixels2 = bwarea(binaryImage)
% Get coordinates of the boundary of the freehand drawn region.
structBoundaries = bwboundaries(binaryImage);
xy=structBoundaries{1}; % Get n by 2 array of x,y coordinates.
x = xy(:, 2); % Columns.
y = xy(:, 1); % Rows.
subplot(2, 3, 1); % Plot over original image.
hold on; % Don't blow away the image.
plot(x, y, 'LineWidth', 2);
drawnow; % Force it to draw immediately.
% Burn line into image by setting it to 255 wherever the mask is true.
burnedImage = grayImage;
burnedImage(binaryImage) = 255;
% Display the image with the mask "burned in."
subplot(2, 3, 3);
imshow(burnedImage);
caption = sprintf('New image with\nmask burned into image');
title(caption, 'FontSize', fontSize);
% Mask the image and display it.
% Will keep only the part of the image that's inside the mask, zero outside mask.
blackMaskedImage = grayImage;
blackMaskedImage(~binaryImage) = 0;
subplot(2, 3, 4);
imshow(blackMaskedImage);
title('Masked Outside Region', 'FontSize', fontSize);
% Calculate the mean
meanGL = mean(blackMaskedImage(binaryImage));
% Report results.
message = sprintf('Mean value within drawn area = %.3f\nNumber of pixels = %d\nArea in pixels = %.2f', ...
meanGL, numberOfPixels1, numberOfPixels2);
msgbox(message);
% Now do the same but blacken inside the region.
insideMasked = grayImage;
insideMasked(binaryImage) = 0;
subplot(2, 3, 5);
imshow(insideMasked);
title('Masked Inside Region', 'FontSize', fontSize);
% Now crop the image.
topLine = min(x);
bottomLine = max(x);
leftColumn = min(y);
rightColumn = max(y);
width = bottomLine - topLine + 1;
height = rightColumn - leftColumn + 1;
croppedImage = imcrop(blackMaskedImage, [topLine, leftColumn, width, height]);
% Display cropped image.
subplot(2, 3, 6);
imshow(croppedImage);
title('Cropped Image', 'FontSize', fontSize);

22 comentarios

Sheshjee
Sheshjee el 24 de Nov. de 2012
??? Attempt to reference field of non-structure array. getting this error.
??? Attempt to reference field of non-structure array.
Error in ==> masking at 12 binaryImage = hFH.createMask();
Image Analyst
Image Analyst el 24 de Nov. de 2012
You've modified my demo somehow and broken it. I know this because line 12 of my demo is not "binaryImage = hFH.createMask();". You probably changed this line for some reason: "hFH = imfreehand();" I can't tell unless you post your code (start your own thread for this).
s
s el 15 de Feb. de 2013
can u tell me how can i modify above coding if i use colour image instead of gray image?????
Image Analyst
Image Analyst el 15 de Feb. de 2013
Please start a new question for this.
Hi, can you help me send me your email?
Image Analyst
Image Analyst el 26 de En. de 2015
No, sorry. I don't carry on private side conversations on MATLAB. I do it all here.
kristie bell
kristie bell el 31 de Mzo. de 2015
Hi,
i read your code and i find it really useful for me! Can i check, how can I apply your demo mask to a colour image?
To mask an RGB color image, do this:
% Mask the image using bsxfun() function
maskedRgbImage = bsxfun(@times, rgbImage, cast(mask, class(rgbImage)));
jiyo
jiyo el 7 de Mzo. de 2016
What if I need to mask 2 parts simultaneously and extract them or display them in separate frames?
Walter Roberson
Walter Roberson el 7 de Mzo. de 2016
You cannot do that, jiyo. You need to do the extraction one part at a time. You might be able to find the information about what to extract for both regions simultaneously using a single regionprops() call, and you can request the SubarrayIdx property to get the array indices for each region, but you would need to loop over the regions extracting one at a time if you want them extracted to different frames.
Image Analyst
Image Analyst el 7 de Mzo. de 2016
You'll see how a mask with several blobs is created, then each blob is measured and then, in a loop, is cropped out one at a time. Whether masking or measuring with regionprops are considered "simultaneously" is a rhetorical question that doesn't really matter. However if you have the Parallel Computing Toolbox, then I think you could make a case for it being simultaneous, but again it doesn't really matter.
snehal dahiphale
snehal dahiphale el 26 de Abr. de 2017
Sir, I already have a binary mask to be applied on an RGB image.
how do I apply the binary mask using image 'imoverlay' to extract only remaining RGB parts of the image after applying the binary mask?
Use the mask to index into each color channel:
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
% Get the pixel values for each color channel but only within the mask.
redPixels = redChannel(imoverlay); % A 1-d vector (list).
greenPixels = greenChannel(imoverlay);
bluePixels = blueChannel(imoverlay);
tran ngoc chau
tran ngoc chau el 19 de Jul. de 2017
good work!
kh
kh el 30 de En. de 2019
I was impressed by your answer Answer by Image Analyst .
I am trying to use your code for a 3D volume. My volume g has a size of 491x215x495.
I would like to crop and use a binary mask like in your code. It should be a mask in xy-dimension.
But how can I apply it for the dimension z?
Many thanks.
kh
ahsen beyza goktas
ahsen beyza goktas el 9 de Jun. de 2020
how can i try this code on another picture?
thank you
ahsen, change this line to list the filename of the image you want:
grayImage = imread('cameraman.tif');
or call uigetfile() to let the user browse for one.
Mohammad Nouman
Mohammad Nouman el 7 de Ag. de 2020
@Image Analyst- Thanks alot for this demo code! Best wishes
rui Zeng
rui Zeng el 21 de Mzo. de 2022
thank you for this tutorial!
Lisa Grooten
Lisa Grooten el 23 de Mzo. de 2022
Thanks for the code. But I have question. Instead of using an ROI for the binary image, I use a threshold value of a double containing temperature values. Burning the image black where the binary filter is not true works, but the the problem is that the remaining part becomes white. This is because my 'grayImage' turns white.
binaryImage = grayImage >= 25.5;
Is this because it is not a normal grayscale imag, but a double? Can't I use such an image to place a mask on? Or is there a way to avoid that my grayImages gets white?
Hope you can help me,
Thanks in advance, Lisa
@Lisa Grooten it does not matter if your image is uint8 or double as far as getting a binary image is concerned. However MATLAB considers any double value more than 1 to be white and less than 0 to be black. To have the display not do that, use [] (empty square brackets) in your call to imshow():
imshow(yourDoubleImage, []);
If you still have problems, post your code and image in a new question.
Lisa Grooten
Lisa Grooten el 25 de Mzo. de 2022
@Image Analyst Thank you for your answer!

Iniciar sesión para comentar.

Dimitris M
Dimitris M el 17 de Mayo de 2012

1 voto

Thank you both for your nice codes !
Pablo Dias
Pablo Dias el 29 de Ag. de 2018
Considering RGB image:
I(repmat(M,[1,1,3])~=0)=0;

1 comentario

Thanks Pablo. This worked perfectly when I changed ~= to ==. John
I(repmat(M,[1,1,3])==0)=0;

Iniciar sesión para comentar.

Categorías

Más información sobre Image Processing Toolbox en Centro de ayuda y File Exchange.

Preguntada:

el 16 de Mayo de 2012

Comentada:

el 25 de Mzo. de 2022

Community Treasure Hunt

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

Start Hunting!

Translated by