I am trying to do a very simply task; reading R, G, B, bands from a file (in TIF), and then combining them to produce a colored TIF image. When I read the bands, they appear to be of type uint16. Therefore, I convert them to uint8 before combining them (otherwise the image appears black). But after that, the combined image appears white. Why does this happen? This is my code
[red, rmap] =imread('red.tif'); %uint16
[green, gmap] =imread('green.tif'); %uint16
[blue, bmap] =imread('blue.tif'); %uint16
subplot(2,2,1); imshow(red, rmap)
subplot(2,2,2); imshow(green,gmap)
subplot(2,2,3); imshow(blue,bmap)
rgb = cat(3, uint8(red), uint8(green), uint8(blue));
subplot(2,2,4); imshow(rgb); title('Combined')
This is a sample output:
sample output.png

Antworten (2)

Jan
Jan am 27 Feb. 2019

0 Stimmen

uint8 converts all values above 255 to 255. So use:
rgb = im2uint8(cat(3, red, green, blue));
which scales the data accordingly.

4 Kommentare

Nour Aburaed
Nour Aburaed am 28 Feb. 2019
Thank you for your answer. The combined image appears black now.
Jan
Jan am 28 Feb. 2019
@Nour Aburaed: I can not test what's going on, because I do not have your data and I do not know, how you try to display the data. Remember that after converting the data, the colormap has changed also. Then imshow(red, rmap) cannot work, of course.
You can easily check the values of the rgb array by your own. When working with colormaps is confusing, convert the data to RGB. ind2rgb will help you. I cannot know, what you get as colormap for e.g. [red, rmap]=imread('red.tif'), but the problem seems to be a confusion of indexed versus rgb images, and/or the class of the data. Working with double and RGB images is a good idea to reduce the complexity.
Nour Aburaed
Nour Aburaed am 28 Feb. 2019
I tried using imshow() with and without colormap. The individual bands can be viewed whether I include a colormap or not. For the combined image, it is always either black or white with or without including the color map. Unfortunately I cannot share the data that I am using. But thanks for your help, I will try to make use of the hints you gave me. So are you suggesting that I work with images of type double instead of uint8?
You can prefer double or uint8 as you like. Using doubles will allow to keep the information of uint16, while this is lost with uint8. The main idea is to avoid troubles with different types and/or index or RGB images. If you mix the types, problems like saturated images (all white or all black) can be expected. So decide for a standard format and convert all input to it:
function Img = myIMRead(File, varargin)
[Img, Map] = imread(File, varargin{:});
if ~isempty(Map) % If it is an indexed image, convert it to 3D RGB array
Img = ind2rgb(Img, Map);
end
Img = im2double(Img); % Convert it to double (or im2uint8, if you like)
end

Melden Sie sich an, um zu kommentieren.

Image Analyst
Image Analyst am 28 Feb. 2019

0 Stimmen

Did you try it without a map but using [], like
imshow(red, []); % Use bracket bracket to scale actual data to display's range without altering the data variable.
or do you require the stored pseudocolor color map? If that works, then no need to use ind2rgb() or im2uint() or im2double() or anything else.

Kategorien

Mehr zu Images finden Sie in Hilfe-Center und File Exchange

Produkte

Version

R2018b

Gefragt:

am 27 Feb. 2019

Beantwortet:

am 28 Feb. 2019

Community Treasure Hunt

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

Start Hunting!

Translated by