MATLAB Answers

How to display multiple ROI (masks) in different colors on one image?

7 views (last 30 days)
Phillip Wulff
Phillip Wulff on 18 Jun 2021
Answered: DGM on 19 Jul 2021
I have problem displaying multiple ROI(masks) on one image. I am able to display one mask on the image, and then imfuse the images at the end. But this means that the colors of each mask becomes increasingly transparent, and i would like to avoid that. Please support with ideas and upgrades to the current code.
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;
Image = imread('Report_Picture.png');
[rows, columns, numberOfColorChannels] = size(Image);
imshow(Image, []);
axis on;
title('Report Image', 'FontSize', fontSize);
% set(gcf, 'Position', get(0,'Screensize')); % Maximize figure.
message = sprintf('1 freehand');
uiwait(msgbox(message));
roi = images.roi.AssistedFreehand;
draw(roi);
message = sprintf('2 freehand');
uiwait(msgbox(message));
roi2 = images.roi.AssistedFreehand;
draw(roi2);
message = sprintf('3 freehand');
uiwait(msgbox(message));
roi3 = images.roi.AssistedFreehand;
draw(roi3);
message = sprintf('4 freehand');
uiwait(msgbox(message));
roi4 = images.roi.AssistedFreehand;
draw(roi4);
mask1 = createMask(roi);
mask2 = createMask(roi2);
mask3 = createMask(roi3);
mask4 = createMask(roi4);
% % Display the freehand mask.
% imshow(mask3);
% axis on;
% title('Binary mask of the region', 'FontSize', fontSize);
% If it's grayscale, convert to color
if numberOfColorChannels < 3
rgbImage = cat(3, Image, Image, Image);
else
% It's really an RGB image already.
rgbImage = Image;
end
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
redChannel2 = rgbImage(:, :, 1);
greenChannel2 = rgbImage(:, :, 2);
blueChannel2 = rgbImage(:, :, 3);
redChannel3 = rgbImage(:, :, 1);
greenChannel3 = rgbImage(:, :, 2);
blueChannel3 = rgbImage(:, :, 3);
redChannel4 = rgbImage(:, :, 1);
greenChannel4 = rgbImage(:, :, 2);
blueChannel4 = rgbImage(:, :, 3);
% Specify the color we want to make this area.
desiredColor1 = [235, 18, 22]; % Red
desiredColor2 = [0, 255, 0]; % Green
desiredColor3 = [251, 255, 0]; % Yellow
desiredColor4 = [251, 255, 0]; % Yellow
% Make the red channel that color
redChannel(mask1) = desiredColor1(1);
greenChannel(mask1) = desiredColor1(2);
blueChannel(mask1) = desiredColor1(3);
redChannel2(mask2) = desiredColor2(1);
greenChannel2(mask2) = desiredColor2(2);
blueChannel2(mask2) = desiredColor2(3);
redChannel3(mask3) = desiredColor3(1);
greenChannel3(mask3) = desiredColor3(2);
blueChannel3(mask3) = desiredColor3(3);
redChannel4(mask4) = desiredColor4(1);
greenChannel4(mask4) = desiredColor4(2);
blueChannel4(mask4) = desiredColor4(3);
% Recombine separate color channels into a single, true color RGB image.
rgbImage1 = cat(3, redChannel, greenChannel, blueChannel);
imwrite(rgbImage1,'C:\Users\phillip.wulff\Ergo Files\Report\Pictures\Picture1.png');
rgbImage2 = cat(3, redChannel2, greenChannel2, blueChannel2);
imwrite(rgbImage2,'C:\Users\phillip.wulff\Ergo Files\Report\Pictures\Picture2.png');
rgbImage3 = cat(3, redChannel3, greenChannel3, blueChannel3);
imwrite(rgbImage3,'C:\Users\phillip.wulff\Ergo Files\Report\Pictures\Picture3.png');
rgbImage4 = cat(3, redChannel4, greenChannel4, blueChannel4);
imwrite(rgbImage4,'C:\Users\phillip.wulff\Ergo Files\Report\Pictures\Picture4.png');
% Display the image.
A = imfuse(rgbImage1,rgbImage2,'blend','Scaling','none');
A = imfuse(A,rgbImage3,'blend','Scaling','none');
A = imfuse(A,rgbImage4,'blend','Scaling','none');
imshow(A);
title('Image with color inside the mask region', 'FontSize', fontSize);

Answers (1)

DGM
DGM on 19 Jul 2021
I know this is probably too late to help, but consider this:
fontSize = 16;
Image = imread('Report_Picture.png');
[rows, columns, numberOfColorChannels] = size(Image);
imshow(Image, []);
axis on;
title('Report Image', 'FontSize', fontSize);
disp('Make freehand selection 1 of 4')
%message = sprintf('1 freehand');
%uiwait(msgbox(message)); % wow that's annoying
roi = images.roi.AssistedFreehand;
draw(roi);
disp('Make freehand selection 2 of 4')
roi2 = images.roi.AssistedFreehand;
draw(roi2);
disp('Make freehand selection 3 of 4')
roi3 = images.roi.AssistedFreehand;
draw(roi3);
disp('Make freehand selection 4 of 4')
roi4 = images.roi.AssistedFreehand;
draw(roi4);
mask1 = createMask(roi);
mask2 = createMask(roi2);
mask3 = createMask(roi3);
mask4 = createMask(roi4);
% If it's grayscale, convert to color
if numberOfColorChannels < 3
rgbImage = cat(3, Image, Image, Image);
else
% It's really an RGB image already.
rgbImage = Image;
end
% Specify the color we want to make this area.
desiredColor1 = [235, 18, 22]; % Red
desiredColor2 = [0, 255, 0]; % Green
desiredColor3 = [251, 255, 0]; % Yellow
desiredColor4 = [251, 255, 0]; % Yellow
% generate overlays from masks
olay1 = 255-mask1.*permute(255-desiredColor1,[1 3 2]);
olay2 = 255-mask2.*permute(255-desiredColor2,[1 3 2]);
olay3 = 255-mask3.*permute(255-desiredColor3,[1 3 2]);
olay4 = 255-mask4.*permute(255-desiredColor4,[1 3 2]);
alloverlays = (olay1 + olay2 + olay3 + olay4)/4;
% combine overlay with image
A = uint8((double(rgbImage) + alloverlays)/2);
% Display the image.
imshow(A);
title('Image with color inside the mask region', 'FontSize', fontSize);
There are a lot of ways you can combine images, but using something like imfuse() can become cumbersome and limiting. The above is the source image averaged with the average of overlays. In this way all overlays are transparent, they have the same weight and the source is subdued.
If you don't want the background subdued, just do a darken-only blend:
A = min(uint8(alloverlays),rgbImage);
If you actually want the masked regions to not be transparent, then it'll have to be decided whether they should be transparent with respect to each other, otherwise overlapping regions will obscure each other (might not matter if they never overlap). Let's assume that they can blend with each other, but not the source image:
allmasks = repmat(mask1|mask2|mask3|mask4,[1 1 3]);
A = rgbImage;
A(allmasks) = uint8(alloverlays(allmasks));
If they should stack atop each other, then alloverlays would be calculated differently.

Community Treasure Hunt

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

Start Hunting!