How to add one extra channel into a RGB image

12 views (last 30 days)
Suppose I have RGB image with three channels. Also I have a thermal image with 3 channels I want to do the following:
1) Convert the thermal image into 1 single channel, I think which can be done by rgb2gray() function.
2) Create an extra channel to the RGB image so it will have 4 channels now.
3) Put the image from step 1 , i.e. the 1 channeled thermal image into the newly created 4th channel of RGB image in step 2.
4) Save the 4 channel image.

Answers (2)

Walter Roberson
Walter Roberson on 22 Aug 2023
rgb2gray() is designed for a three-channel input (which you have in this case) but in which the relative channel intensities are to be weighted much the same way as the response curve of the human eye. Studies have shown that for visible light, the intensity of green is more than 5 times as important as the intensity of blue for determining perceived brightness.
When you are using an infrared image, it would be rare that you would want the relative weights of the infrared channels to be exactly the same as the weights that are used to convert RGB to intensity.
Creating a 3D array with 4 channels in MATLAB is not a significant technical problem. Finding routines that can usefully process those arrays is more of challenge.
RGBimage(:,:,4) = ExtraChannel; %pretty simple to implement
Saving the 4 channel image... you should be more specific about how you want to save it.
JPEG and JPEG 2000 files cannot store 4 channels. GIF files cannot store 4 channels.
PNG files can store 4 channels, if you pass imwrite() an RGB array and pass the option 'Transparency' and the content of the extra channel. The extra channel would be stored as transparency (Alpha) in the resutling PNG image; you need the three-output version of imread() to read the extra channel.
TIFF files can store 4 or more channels in a couple of different ways; you would use Tiff routines to process such files.
But I wonder if your case is more suitable for geotiffwrite ?
  1 Comment
DGM
DGM on 22 Aug 2023
For writing PNG with alpha, you'd have to use the 'alpha' option instead of the 'transparency' option. The 'transparency' option only accepts a single color tuple, and so the effected alpha is simply a binarized version of the RGB channels, and carries no object content from the IR image.
% an RGB image
inpict = imread('peppers.png');
% some sort of grayscale image as alpha
alpha = imread('redpepmask.png');
alpha = imgaussfilt(alpha,5); % just for demonstration
% write the thing to a PNG
imwrite(inpict,'test_a.png','alpha',alpha)
This is the image on disk. It's opaque where alpha is white (the red pepper area).
% read it back again
[A,~,aa] = imread('test_a.png');
% show it
imshow(A,'border','tight')
figure
imshow(aa,'border','tight')
MIMT does handle 4-channel RGBA images and has tools for switching back and forth between workflows with attached (RGBA) or loose (RGB+A) alpha channels. That said, I don't really know that it's time to cross that bridge yet.

Sign in to comment.


DGM
DGM on 22 Aug 2023
Edited: DGM on 22 Aug 2023
If your thermal image is RGB, then no, rgb2gray() won't work. The functions rgb2gray() and im2gray() calculate BT601 luma, which doesn't make sense unless the image is a visible-light image. What you likely have is a false-color image. The underlying content (a temperature map) has no color of its own. It's a grayscale image that has been represented in artificial color for sake of visualization.
Given that the colormap used for visualization is often not linear or even monotonic in luma, processing the pseudocolor image with rgb2gray() will end up distorting or destroying information in the underlying T data.
% let's say i have a simple thermal image (a linear ramp)
T = repmat(linspace(-50,75,400),[200 1]);
% i can represent this in pseudocolor in a number of ways
imshow(T,[])
colormap('turbo')
cb = colorbar;
cb.Location = 'east';
truesize(gcf)
% let's say we have such an image on disk somewhere
imwrite(frame2im(getframe(gca)),'Tramp.png')
% ... and we read it from disk and convert it to luma
inpict = imread('Tramp.png'); % uint8-scale RGB
Tluma = rgb2gray(inpict); % uint8-scale luma
imshow(Tluma,'border','tight'); % notice the ambiguity caused by inversion
% plot the horizontal ramp of values; compare to original
figure
hp(1) = plot(T(1,:)); hold on
hp(2) = plot(Tluma(1,:));
ylabel('Temperature')
legend(hp,{'original temperature','junk luma value'})
Note that all meaningful information about T has been lost. Not only are the local differences lost due to the loss of linearity, the overall scale is completely lost, since there's no calibration information being used. The output values are just uint8-scale luma, not temperature.
This same problem happens with images which might look more familiar. Note the inversion in the colorbar.
figure
inpict = imread('flir2-2.jpg');
imshow(inpict,'border','tight')
Tluma = rgb2gray(inpict);
imshow(Tluma,'border','tight')
Instead, see the following threads:
If instead of trying to create a 4-channel image, you're trying to create a composite image representing both visible and IR information simultaneously, then this old thread might be relevant, but it's hard to say.

Community Treasure Hunt

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

Start Hunting!