Overlaying Two Binary Images with Two Separate Colors

40 views (last 30 days)
I have two separate binary images that are the result of chopping up an original binary image. The program separates the original image into an image called "loops" and another image called "branches". These images do not overlap at all.
Currently I am displaying the images in two separate figures (both are white pixels on black background), but I would like to combine them into one figure using two different colors (e.g. red for branches and blue for loops).
My initial thought was to convert the binary image to an RGB image and use a loop to change each pixel value from white to whichever color I wanted, then combine the images, but I was hoping there was a simpler way (one that wouldn't have to actually change the binary image values if possible).
Thank you for your help in advance.
  3 Comments
RYAN MTHEMBU
RYAN MTHEMBU on 12 Dec 2021
Hello Richard. I'm currently working with the same problem.. I'm given three binary images of different shapes and I'm asked to generate an RGB colour image combining the three shapes into one.. basically putting putting one shape on top of the other.. And when I read yours its quit similar to what I'm doing .. kindly share your code with me if possible. It would really help me . Thanks in advance
Image Analyst
Image Analyst on 12 Dec 2021
Edited: Image Analyst on 12 Dec 2021
@RYAN MTHEMBU, Richard probably won't answer since he posted this 10 years ago. But we just answered your question recently with somebody wanting to pile a circle, triangle, and parallelogram on top of each other, each with a different color. Just search for it.

Sign in to comment.

Answers (3)

Image Analyst
Image Analyst on 14 Jun 2011
You can make up a color image from them by setting each binary image equal to a color plane. Like
rgbImage = cat(3, branches, loops, loops);
Each argument is a color input channel. This will make the branches image show up as red, and the loops image show up as cyan (since it's equal green and blue).

Walter Roberson
Walter Roberson on 13 Jun 2011
Use different axes (in the same figure) for the two images, but set the CLim property different for the two axes (the caxis() command is a short-cut for that.) That would allow you to interpolate in to different parts of the color map.
f = figure;
foo = rand(64,64)> 0.5;
ax1 = axes('Parent',f,'Position',[0 0 1/2 1]);
ax2 = axes('Parent',f,'Position',[1/2 0 1/2 1]);
im1 = imagesc(foo,'Parent',ax1);
im2 = imagesc(foo,'Parent',ax2);
set([ax1,ax2],'Visible','off');
caxis(ax1,[0 1]);
caxis(ax2,[0 2]);
  1 Comment
Richard Clark
Richard Clark on 14 Jun 2011
Thank you very much for your answer, but the answer below was a little simpler so I went with that.

Sign in to comment.


DGM
DGM on 14 Dec 2023
Edited: DGM on 14 Dec 2023
It wasn't an option in R2010a, but I think imfuse() is the expedient answer in modern contexts. As much as I complain about its misuse, this is an appropriate application, and it offers some conveniences that are rare within IPT. It will compensate for mismatches of class and produce a valid, properly-scaled RGB image which will actually display correctly, whereas direct concatenation generally won't. It will produce a clean raster image, where in-figure composition won't.
Consider the following examples. I'm going to ignore the particular colors used in composition, as you can choose that in either case. I'm just going to use the defaults for imfuse() and the given example for concatenation.
Start with imfuse():
% I, uint8
A = imread('roughsquare.png');
B = imread('roughcircle.png');
montage({A B})
% the default falsecolor mode works fine for numeric images
C = imfuse(A,B);
imshow(C,'border','tight')
% the results are sensible, regardless of the class of either image
% even for logical and signed-integer classes
A = A>128; % A is logical, B is uint8
C = imfuse(A,B); % both images are converted to a common scale, so class mismatch doesn't matter
imshow(C,'border','tight')
% regardless of the input class, the output class is consistently uint8
% so we don't risk creating logical or signed-integer RGB images
% which would otherwise break imshow() for no good reason
B = B>128; % now both B and A are logical
C = imfuse(A,B); % result is uint8 RGB
imshow(C,'border','tight')
Compare to direct concatenation
% I, uint8
A = imread('roughsquare.png');
B = imread('roughcircle.png');
% concatenation requires classes to match
% class can only be 'single','double','uint8',or 'uint16'
% logical and signed-integer images are not allowed
C = cat(3,A,B,B);
imshow(C,'border','tight')
% if the classes mismatch, the results will be garbage
A = A>128; % A is logical, B is uint8
C = cat(3,A,B,B); % result is uint8, so contribution of A is negligible
imshow(C,'border','tight')
% if both images are logical or int16, the result will be a proper RGB mask
% of the corresponding class, but imshow() is too dumb to handle such a simple thing
B = B>128; % now both A and B are logical
C = cat(3,A,B,B); % result is logical RGB
imshow(C,'border','tight') % but imshow() is too dumb to know what to do with that
Error using images.internal.imageDisplayValidateParams>validateCData
If input is logical (binary), it must be two-dimensional.

Error in images.internal.imageDisplayValidateParams (line 30)
common_args.CData = validateCData(common_args.CData,image_type);

Error in images.internal.imageDisplayParseInputs (line 79)
common_args = images.internal.imageDisplayValidateParams(common_args);

Error in imshow (line 253)
images.internal.imageDisplayParseInputs({'Parent','Border','Reduce'},preparsed_varargin{:});
Let me be clear that concatenation is a nice simple answer, but it requires a number of conditions to be met, none of which are mentioned or enforced. Could it be fixed with a few calls to im2uint8()? Sure, but now it's lost some of that elegance and it's become just as dependent on IPT as using imfuse() would.
I like things which are class-agnostic or otherwise generalized enough to be safe. IPT imfuse() manages to provide that.
See also:

Community Treasure Hunt

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

Start Hunting!