MATLAB Answers

How can assign a color channel to an image series?

9 views (last 30 days)
My question is two-fold:
I'm using Bio-Formats to import an image series (or stack) from multiphoton into Matlab.
No problem there. I have two series that I want to assign a color (such as blue for DAPI and red for Collagen) similar to what can be done in ImageJ, where you assign an image series a channel and ultimately merge stacks.
1) As a preliminary step I tried isolating a single frame out, which was a grayscale image (uint16). I attempted the following (based on
imshow(RGBimage) or imshow(RGBimage,[])
I get a black window, where I expected some structures to be red. However, imshow(grayimage,[]) works fine. How can I add color to a single frame?
2) Scaling this up: Is there a way to apply a color to the whole image series that I import from Bio-Formats?
This may be something very basic. I tried looking elsewhere and have attempted to apply suggestions but have had no luck thus far. Many thanks!


Walter Roberson
Walter Roberson on 13 Feb 2020
would be an error unless grayimage happened to be a vector with the same length as size(grayimage) -- which would have to be length 2. For example,
grayimage = randi(255,1,2);
RGBimage = cat(3, grayimage, size(grayimage), size(grayimage))
size(grayimage) would be 1 2 which would be a vector of length 2, and it would be valid to cat(3) the vector of length 2 in grayimage with the two size vectors.
Samuel Salinas
Samuel Salinas on 14 Feb 2020
Hi Walter,
Thank you for the reply.
Your comment made sense. I updated my original question because reading your reply made me realize I forgot to add indicate that i had created zero arrays in the same size as my grayscale image. But I still arrive at the same problem.

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 14 Feb 2020
The classic reason to get out a black window when you use imshow() but imshow() with [] looks okay, is to start with image data that is you start with single or double precision data values that are in the range 0 to 1, and you cat() those together with zeros that are uint8.
gi = rand(5, 7);
rgb = cat(3,gi,zeros(size(gi),'uint8'),zeros(size(gi),'uint8'));
imshow(rgb) %will be pretty much all black
class(rgb) %will be uint8
There is another related even more common problem, where you get out an image that is completely saturated in the color with possibly a couple of scattered black spots, but no shades of color. With rgb images, this is commonly a completely white image except for a couple of black locations. This related problem is caused by having converted uint8 values to double precision in the range 0. to 255., and then put together with other double precision values such that the end result is double precision but with a value range of 0. to 255. Example,
ri = randi([0 255], 5, 7, 3, 'uint8'); %an rgb image with lots of shades
di = double(ri); %an array with values ranging 0. to 255., but not a standard image
imshow(di) %will be mostly white
imshow looks at the data type to decide what to do, instead of looking at the data range. Data type double() expects shades according to values in the range 0 to 1. Any value less than 0 is treated the same as 0 when showing an image; any value greater than 1 is treated as 1 (full brightness) when showing the image. Double precision 0. to 255. is mostly values greater than 1, so all positions are to be maximum brightness except for the few that are 0 (black.)
You need to carefully check the datatype and value range of what you are concatenating together.
If you want to use double precision for images, do not use double() to convert it: use im2double(), which will rescale by the appropriate constant so that the maximum expected value for the data type is mapped to 1. It is really common for people to think that double(IMAGE) converts the representation of IMAGE from uint8 to something that will display the same way but be double precision, and that is just not the case.


Show 3 older comments
Walter Roberson
Walter Roberson on 14 Feb 2020
Your slice_col has a maximum value of 1613, which is only about 2.5% of the range possible for uint16 .
slice_cold = mat2gray(slice_col);
RGBd = cat(3,slice_cold,zeros(size(slice_cold)),zeros(size(slice_cold)));
Now if you want you can
RGB16 = im2uint16(RGBd);
RGB8 = im2uint8(RGBd);
Use whichever of the two is appropriate for your needs.
Walter Roberson
Walter Roberson on 14 Feb 2020
However, if it is an image series, really what you need to do is know the maximum value over ALL of the images, and mat2gray(slice_col, [0 ThatMaximum]) . If you do not do that, then each slice will be adjusted relative to itself and you will not be able to compare slice to slice.

Sign in to comment.

More Answers (1)

Spencer Chen
Spencer Chen on 13 Feb 2020
1) What you want to achieve get is probably something like this:
or you can do:
RGBimage = repmat(grayimage,[1 1 3]);
RGBimage(:,:,2:3) = 0;
Anyway, I gave you 2 examples because it will benefit your Matlab skills if you can understand what's happening in both.
2) You can simply pseudo color your plots in red-scale using the colormap() function after you plot.

  1 Comment

Samuel Salinas
Samuel Salinas on 14 Feb 2020
Hi Spencer,
Thank you for the feedback. I ran both of your suggestions but I still get a black screen.

Sign in to comment.


Community Treasure Hunt

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

Start Hunting!