Masking out Image area using Binary Mask
110 views (last 30 days)
Show older comments
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
0 Comments
Accepted Answer
Kye Taylor
on 16 May 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 Comments
Jerry
on 23 Jul 2016
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
Image Analyst
on 23 Jul 2016
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.
More Answers (3)
Image Analyst
on 16 May 2012
Edited: Image Analyst
on 22 Mar 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 Comments
Image Analyst
on 23 Mar 2022
@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.
Pablo Dias
on 29 Aug 2018
Considering RGB image:
I(repmat(M,[1,1,3])~=0)=0;
1 Comment
John Rogers
on 10 Apr 2021
Thanks Pablo. This worked perfectly when I changed ~= to ==. John
I(repmat(M,[1,1,3])==0)=0;
See Also
Categories
Find more on Image Processing Toolbox in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!