How do I convert my RGB image to grayscale without using the Image Processing Toolbox?

255 views (last 30 days)
I read a TrueColor image into MATLAB as a 3D RGB matrix. I would like to convert it to grayscale so that I can analyze the intensities, or modify the colormap according to intensity.

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 12 Aug 2010
To convert an RGB image to grayscale, you can use the RGB2GRAY command from the Image Processing Toolbox. If you do not have this toolbox, then you can use the standard NTSC conversion formula that is used for calculating the effective luminance of a pixel:
intensity = 0.2989*red + 0.5870*green + 0.1140*blue
The following code can be used as an example:
% Assume you have an RGB image of class double, or create a random one
rgb = rand(200,200,3);
% Convert it
gray = 0.2989 * rgb(:,:,1) + 0.5870 * rgb(:,:,2) + 0.1140 * rgb(:,:,3);

More Answers (1)

DGM
DGM on 25 Apr 2022
Edited: DGM on 4 Jun 2022
EDIT: It's worth noting that as of R2014b, rgb2gray() no longer requires IPT. Still, if you're writing code for others and intend to support legacy versions, you might still want to be wary of the dependency.
There is more than one way to represent an RGB image as grayscale. If you want to replicate rgb2gray() from Image Processing Toolbox, you want luma as calculated with the BT470/601 constants.
% get an RGB image
rgbpict = imread('peppers.png');
rgbpict = imresize(rgbpict,0.5); % don't need giant images for an example
rgbpict = im2double(rgbpict); % need to cast & scale for this to work
imshow(rgbpict)
% Rec 470/601 (analog/digital SD video)
factors = permute([0.299 0.587 0.114],[1 3 2]);
Y601 = sum(bsxfun(@times,rgbpict,factors),3);
601
If you want to use BT709 luma constants, you can do that too.
% Rec 709 (HDTV video)
factors = permute([0.2126 0.7152 0.0722],[1 3 2]);
Y709 = sum(bsxfun(@times,rgbpict,factors),3);
709
There are other things that you could use, depending on the context.
If you just want the intensity (as in HSI) of an image:
ipict = mean(rgbpict,3);
If instead you want value (as in HSV)
vpict = max(rgbpict,[],3);
or if you want lightness (as in HSL)
lpict = min(rgbpict,[],3)/2 + max(rgbpict,[],3)/2;
If you want L* lightness (as in CIELAB, CIELUV), you could do that like so ...
Lpict = rgb2lightness(rgbpict)/100; % introduced in R2019a
CIE L*
... but rgb2lab() and rgb2lightness() are part of IPT.
So that brings up the question of why IPT can't be used. If it's being avoided because it's an arbitrary restriction dictated by your homework, then you'll have to do the work assigned. If you can't use IPT because you don't have it and you just want a working solution, then MIMT mono() can do them all without needing IPT.
% get an RGB image
rgbpict = imread('peppers.png');
rgbpict = imresize(rgbpict,0.5);
% use MIMT mono()
Y601 = mono(rgbpict,'y601');
Y709 = mono(rgbpict,'y709');
ipict = mono(rgbpict,'i');
vpict = mono(rgbpict,'v');
lpict = mono(rgbpict,'l');
Lpict = mono(rgbpict,'llch');
imshow([Y601 Y709 ipict; vpict lpict Lpict])
combined mono() examples

Community Treasure Hunt

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

Start Hunting!