How MATLAB Represents Pixel Colors
By Steve Eddins, MathWorks
What colors do these pixel values represent?
252 249 246 243 237
255 255 250 246 243
253 254 248 245 243
250 249 245 243 239
If you are familiar with image processing you might think of 255 as "white," and so assume that the values above represent white and near-white pixels. But these values don’t, in fact, come from a picture at all. They are Boston-area digital elevation values, downloaded from the U.S. Geological Survey (USGS) . The value 255 is a measurement in meters, and has no inherent "color."
MATLAB can display the values of any matrix as an image. For example, depending on the commands you use, MATLAB can display the digital elevation values like this:
or like this:
Displaying your matrix as an image in a variety of ways gives you further insight into your data. By understanding the different image types explained in this article, you’ll know exactly how MATLAB turns matrix values into image pixel colors. You can then control the way MATLAB displays your data, and correct images that display incorrectly.
An image type is a particular method of associating matrix values with pixel colors. MATLAB has three basic image types:
- Truecolor--generated by digital cameras and widely used in computer graphics
- Indexed and scaled indexed--often used to display scientific and engineering data with an associated color scale representing the data units
The Image Processing Toolbox identifies two additional types:
- Grayscale--often used in image processing and image analysis algorithms
- Binary--often used as a mask to indicate segmentation results or a region of interest
In a truecolor image, every image pixel has three values associated with it: the red, green, and blue components. You represent a truecolor image in MATLAB with a three-dimensional array of size M-by-N-by-3. Display functions in MATLAB and the Image Processing Toolbox treat such an array as a truecolor image.
For example, let’s construct a truecolor image with two rows and two columns. The top two pixels should be red and blue, the bottom two, yellow and gray. First, we make three separate 2-by-2 matrices, one for each of the three color components.
red = [1 0; 1 0.7]
green = [0 0; 1 0.7]
blue = [0 1; 0 0.7]
Next, we use the
cat function to concatenate the three component matrices along the third dimension.
truecolor_image = cat(3, red, green, blue);
Finally, we call the MATLAB
image(truecolor_image) axis equal % Display the image using square pixels
You can see that with a truecolor image, the values of the array specify the color of each image pixel directly. This form of representation gives you the most control over the display, but it may not be the most appropriate image type to use for engineering and scientific data.
In an indexed image, the image matrix values do not determine the pixel colors directly. Instead, MATLAB uses the matrix values as indices for looking up colors in the figure's colormap. For example, the MATLAB file
clown.mat contains the following indexed image.
load clown whos
Name Size Bytes Class
X 200x320 512000 double array
caption 2x1 4 char array
map 81x3 1944 double array
Grand total is 64245 elements using 513948 bytes
X contains the lookup table indices, while
map contains the associated colormap. Both must be used to display the image correctly.
To determine the color of the (5,5) pixel, we must first determine what
Then we incorporate that value as a row index into the colormap matrix,
0.9961 0.5781 0.1250
The (5,5) pixel has a lot of red, some green, and a little blue.
Displaying the image requires two MATLAB commands, one to create the image and one to set the figure's colormap:
Unlike truecolor images, indexed images are affected by changes in the figure's colormap.
Indexed image display was much more common 15 years ago, when most color graphics displays were limited to at most 256 simultaneous colors. Today they are useful for displaying data with different kinds of color scales. Because the indexed image values must be integers, however, a scaled indexed image offers more flexibility.
Scaled indexed images
Like an ordinary indexed image, a scaled indexed image uses matrix values to look up colors in the figure’s colormap. The difference is that the matrix values are linearly scaled to form lookup table indices. To display a matrix as a scaled indexed image, use the MATLAB image display function
For example, let’s display a small magic square using
image and then compare it with a display using
A = magic(5)
A = 17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
We first display
image and a 256-color grayscale colormap:
image(A) colormap(gray(256)) axis equal
Notice that the displayed image is very dark. That's because the element values of A vary between 1 and 25, and so the image uses only the first 25 colors of the grayscale colormap—all of which are dark.
Compare that display with this one, which uses
imagesc(A) colormap(gray(256)) axis equal
imagesc displays the lowest value of
A, which is 1, using the first colormap color, which is black. It displays the highest value of
A, which is 25, using the last colormap color, which is white. All the other values between 1 and 25 are mapped linearly onto the colormap. For example, the value 12 is displayed using the 118th colormap color, which is an intermediate shade of gray.
If you switch colormaps, the values of
A will be scaled and displayed using the colors in the new colormap.
You can also obtain this scaling effect by manipulating low-level Handle Graphics properties directly. If you develop GUI programs in MATLAB, you often need to use low-level functions and properties instead of functions like
imagesc, so it’s worth exploring the details. Let us look at two HG properties that are fundamental in determining how pixel colors are displayed.
Image objects have a property called CDataMapping.
h = image(A); get(h, 'CDataMapping')
You can see that the default value of CDataMapping is 'direct'. This means that values of
A are used directly as indices into the colormap. CDataMapping can also be 'scaled', which is the value you get when you use
h = imagesc(A); get(h, 'CDataMapping')
The low and high values for the scaling are controlled by the CLim (color limits) property of the axes property. Let’s return to our magic square:
h = imagesc(A); get(gca, 'CLim')
By default, the
imagesc function assigns the minimum and maximum values of
A to the CLim vector. You can specify your own color limits by adding an optional second argument to
imagesc(A, [10 15]) colormap(gray) axis equal
imagesc displayed the value 10 (and lower values) as black. Similarly, it displayed the value 15 (and higher values) as white. Values between 10 and 15 were displayed as shades of gray.
Please refer to the quick reference guide at the end of this article look for more information on Handle Graphics properties that control pixel color.
Scaled image display is very important in engineering and scientific applications of image processing, because the object of interest often isn't a "picture" in the ordinary sense but an array containing measurements in a physical unit that is unrelated to light intensity, such as meters in the dataset from the USGS.
Grayscale images contain only brightness information. A grayscale image is a scaled indexed image that uses a grayscale colormap. If you pass a single argument containing a two-dimensional matrix to the Image Processing Toolbox image display functions,
imshow, these functions will automatically display the matrices using a grayscale colormap. (The MATLAB functions
imagesc, on the other hand, simply use whatever colormap is already in the figure.) This example uses a synthetic image constructed from a simple sinusoidal function:
theta = linspace(0, 2*pi, 256); I = repmat((-cos(2*theta) + 1)/2, [256 1]); h = imshow(I); % Save the handle for use below.
y = zeros(1000,1); for n = 1:1000 y(n) = max(svd(randn(n))); end plot(y);
The following key properties have been set automatically by
For floating-point images, the Image Processing Toolbox convention is to display 0 as black and 1 as white.
The toolbox automatically uses a grayscale colormap.
map = get(gcf, 'Colormap'); map(1:5, :) % Display the first few colormap colors
0 0 0
0.0039 0.0039 0.0039
0.0078 0.0078 0.0078
0.0118 0.0118 0.0118
0.0157 0.0157 0.0157
imtool) handle all these details automatically.
The toolbox functions
imtool let you override the conventional display range and specify your own black and white values. You do this by providing a second input argument. Like
imagesc, the optional second argument is a two-element vector containing the black and white values. In the call to
imshow below, 0.4 (and any lower value) is displayed as black. A value of 0.6 or higher is displayed as white.
imshow(I, [0.4 0.6])
Grayscale images are frequently used in image processing algorithms that operate directly on relative brightness values rather than on colors. They are also commonly used for printed materials.
y = zeros(1000,1); for n = 1:1000 y(n) = max(svd(randn(n))); end plot(y);
Binary images contain only black and white pixels. The output of an image segmentation algorithm is often a binary image, where the white pixels represent the object of interest and the black pixels represent the background.
Image Processing Toolbox functions treat a logical matrix as a binary image. A logical matrix contains only 0s (displayed as black) and 1s (displayed as white).
bw = imread('text.png'); islogical(bw)
h = imshow(bw);
Binary images are sometimes used for text or for line art. They are also used in image processing as a mask. An image mask divides the pixels into two sets. One set, typically the white pixels, contains the locations of interest. For example, the white pixels might indicate detected objects. The other set indicates the background locations.
In Handle Graphics, the following properties of image, axes, and figure objects interact to determine an image pixel's color.
Image Object: Cdata Values And Dimensionality
- If the image CData is three-dimensional and the size of the third dimension equals 3, then the CData values are taken to represent RGB values directly.
- If the image CData is two-dimensional, then the image display colors come from the figure colormap. MATLAB uses CData values (either directly or in scaled form) as lookup indices into the colormap.
Image Object: CDataMapping
If the image CData is two-dimensional, then the image display colors come from the figure's colormap, and the image CDataMapping property controls the way the colormap lookup is performed.
- If CDataMapping is 'direct', then CData values are used directly as lookup indices into the colormap.
- If CDataMapping is 'scaled', then CData values are scaled to form lookup indices into the colormap.
For truecolor images, the CDataMapping property has no effect on the displayed pixel colors.
Image Object: Cdata Class
If the image is truecolor, then the class of the CData array (uint8, uint16, or double) determines which values are displayed as white. If the CData class is double, then [1 1 1] is white. If the class is uint8, then [255 255 255] is white. If the class is uint16, then [65535 65535 65535] is white. The values [0 0 0] always represent black.
If the image is indexed, then the class of the CData array affects the indexing operation. If the CData class is double, then the value 1 corresponds to the first colormap color. If the class is uint8 or uint16, then value 0 corresponds to the first colormap color.
Axes Object: CLim
If the image CData is two-dimensional and if the image CDataMapping is 'scaled', then the two-element axes CLim property determines the scaling function. The first element gives the value that maps to the first colormap color, and the second gives the value that maps to the last colormap color.
For truecolor images, or if the image CDataMapping property is 'direct', the CLim property has no effect on the displayed pixel colors.
Figure Object: Colormap
If the image CData is two-dimensional, then all displayed pixel colors come from the figure Colormap.
For truecolor images, the Colormap property has no effect on the displayed pixel colors.
If the figure AlphaMap, the image AlphaData, or the image AlphaDataMapping properties are set to nondefault values, then some pixels may be displayed transparently. Refer to the MATLAB Handle Graphics documentation to learn more about these properties.