# How to convert from gray scale to RGB

1 view (last 30 days)
Maaz Madha on 27 Nov 2021
Edited: Image Analyst on 28 Nov 2021
I am coding a denoising filter for a colored image and from my understanding I need to convert the original picture into a greyscale, denoise and then convert it again. However, I do not know how to convert it from grayscale back into RGB to see the difference. I have posted the code I've used and have commented the part which should convert it back into an RGB but it is not working. Any help would be appreciated
J=im2gray(I);
figure(1),imshow(J),title('Original noise1')
figure(2),imshow(I),title('Original but in color')
K = wiener2(J,[5 5]);
rgbImage = cat(3, K, K, K);%found after online research
%colors
h=fspecial('unsharp');
L=imfilter(I,h);
figure(4),imshow(L),title('Linear filtered image')
M=medfilt2(J,[3 3]);
figure(5),imshow(M),title('Median filtered image')
Walter Roberson on 27 Nov 2021
If cmap is expected to always be empty because noise1.tif is not a pseudocolor image, then do not use cmap in the code, as that adds to the confusion.
If cmap is expected to be non-empty (at least at times) then in the cases where it is non-empty, the variable I would not be an RGB image, and you would need to use ind2rgb(I,cmap) to make it into an RGB image.

Walter Roberson on 27 Nov 2021
Nearly all of the time, tif images are read in as integer data types. They might be uint8 or int16 or uint16, but they are very seldom single() or double() . single() or double() are possible but uncommon.
J=im2gray(I);
when I is integer data type, im2gray() outputs J as the same integer data type.
K = wiener2(J,[5 5]);
wiener2 filter of an integer data type returns a floating point data type with the same approximate range. So if J was range uint8(0) to uint8(255) then K will be approximately the range 0.0 to 255.0
rgbImage = cat(3, K, K, K);%found after online research
cat(3) of three floating point data types gives a floating point result, such as in the range 0.0 to 255.0
When imshow() is passed only a single image parameter, with no range parameter after the image parameter, then imshow() assumes that any floating point input is in the range 0.0 (minimum) to 1.0 (maximum) and any floating point number greater than 1.0 will be treated as 1.0 . But most of your floating point input is going to be greater than 1.0...
You could fix these problems if you were to use
J = im2gray(im2double(I));
##### 2 CommentsShowHide 1 older comment
Maaz Madha on 27 Nov 2021
My original I matrix is a uint8, while the rgbImage matrix is now a double matrix(same dimensions). I don't understand why this was done, as I am new to denoising images.

Image Analyst on 27 Nov 2021
Edited: Image Analyst on 28 Nov 2021
Not sure what your plans are but one way is to get the gray scale component images from imsplit()
[r, g, b] = imsplit(rgbImage);
then denoise each one, say with a function you call denoise(), and then recombine with cat(3) like you did.
smooth_r = uint8(denoise(r)); % Denoise and cast from double back to uint8
smooth_g = uint8(denoise(g)); % Denoise and cast from double back to uint8
smooth_b = uint8(denoise(b)); % Denoise and cast from double back to uint8
smoothRGB = cat(3, smooth_r, smooth_g, smooth_b);
Another option may be to assume the noise is only in the intensity channel (L in an LAB image or V in an HSV image). So then you could use rgb2hsv() or rgb2lab() and then denoise the V or L channel and go back to RGB color space with hsv2rgb() or lab2rgb().
hsvImage = rgb2hsv(rgbImage);
vImage = hsvImage(:, :, 3);
smooth_v = denoise(vImage)); % Denoise somehow.
% Recombine
hsvImage = cat3(hsvImage(:, :, 1), hsvImage(:, :, 2), smooth_v);
rgbImage = hsv2rgb(hsvImage);
Check your cmap. It should be empty. If it's not empty, you have an indexed image and you need to convert to RGB with
if ~isempty(cmap)
rgbImage = ind2rgb(I, cmap);
end