Digital Image  
Processing  
®
Using MATLAB  
Second Edition  
Rafael C. Gonzalez  
University of Tennessee  
Richard E. Woods  
MedData Interactive  
Steven L. Eddins  
The MathWorks, Inc.  
Gatesmark Publishing®  
A Division of Gatesmark, LLC  
®
www.gatesmark.com  
Library of Congress Cataloging-in-Publication Data on File  
Library of Congress Control Number: 2009902793  
Gatesmark Publishing  
A Division of Gatesmark, LLC  
www.gatesmark.com  
©
2009 by Gatesmark, LLC  
All rights reserved. No part of this book may be reproduced or transmitted in any form or by any  
means, without written permission from the publisher.  
Gatesmark Publishing® is a registered trademark of Gatesmark, LLC, www.gatesmark.com.  
Gatesmark® is a registered trademark of Gatesmark, LLC, www.gatesmark.com.  
MATLAB® is a registered trademark of The MathWorks, Inc., 3 Apple Hill Drive, Natick, MA  
0
1760-2098  
The authors and publisher of this book have used their best efforts in preparing this book. These  
efforts include the development, research, and testing of the theories and programs to determine  
their effectiveness. The authors and publisher shall not be liable in any event for incidental or  
consequential damages with, or arising out of, the furnishing, performance, or use of these  
programs.  
Printed in the United States of America  
1
0
9
8
7
6
5
4
3
2
1
ISBN 978-0-9820854-0-0  
Fundamentals  
2
Preview  
As mentioned in the previous chapter, the power that MATLAB brings to  
digital image processing is an extensive set of functions for processing mul-  
tidimensional arrays of which images (two-dimensional numerical arrays)  
are a special case. The Image Processing Toolbox is a collection of functions  
that extend the capability of the MATLAB numeric computing environment.  
These functions, and the expressiveness of the MATLAB language, make  
image-processing operations easy to write in a compact, clear manner, thus  
providing an ideal software prototyping environment for the solution of  
imageprocessingproblems.InthischapterweintroducethebasicsofMATLAB  
notation, discuss a number of fundamental toolbox properties and functions,  
and begin a discussion of programming concepts. Thus, the material in this  
chapter is the foundation for most of the software-related discussions in the  
remainder of the book.  
2
.1 Digital Image Representation  
An image may be defined as a two-dimensional function f(x, y), where x and  
y are spatial (plane) coordinates, and the amplitude of f at any pair of coordi-  
nates is called the intensity of the image at that point.The term gray level is used  
often to refer to the intensity of monochrome images. Color images are formed  
by a combination of individual images. For example, in the RGB color system  
a color image consists of three individual monochrome images, referred to as  
the red (R), green (G), and blue (B) primary (or component) images. For this  
reason, many of the techniques developed for monochrome images can be ex-  
tended to color images by processing the three component images individually.  
Color image processing is the topic of Chapter 7.An image may be continuous  
1
3
1
4
Chapter 2  Fundamentals  
with respect to the x- and y-coordinates,and also in amplitude.Converting such  
an image to digital form requires that the coordinates, as well as the amplitude,  
be digitized. Digitizing the coordinate values is called sampling; digitizing the  
amplitude values is called quantization.Thus, when x, y, and the amplitude val-  
ues of f are all finite, discrete quantities, we call the image a digital image.  
2
.1.1 Coordinate Conventions  
The result of sampling and quantization is a matrix of real numbers.We use two  
principal ways in this book to represent digital images. Assume that an image  
f(x, y) is sampled so that the resulting image has M rows and N columns. We  
say that the image is of size M * N . The values of the coordinates are discrete  
quantities. For notational clarity and convenience, we use integer values for  
these discrete coordinates. In many image processing books, the image origin  
is defined to be at (x, y) = (0, 0).The next coordinate values along the first row  
of the image are (x, y) = (0,1). The notation (0,1) is used to signify the second  
sample along the first row. It does not mean that these are the actual values of  
physical coordinates when the image was sampled. Figure 2.1(a) shows this  
coordinate convention. Note that x ranges from 0 to M - 1 and y from 0 to  
N - 1 in integer increments.  
The coordinate convention used in the Image Processing Toolbox to denote  
arrays is different from the preceding paragraph in two minor ways. First, in-  
stead of using (x, y), the toolbox uses the notation (r, c) to indicate rows and  
columns. Note, however, that the order of coordinates is the same as the order  
discussed in the previous paragraph, in the sense that the first element of a  
coordinate tuple, (a, b), refers to a row and the second to a column. The other  
difference is that the origin of the coordinate system is at (r, c) = (1,1); thus, r  
ranges from 1 to M, and c from 1 to N, in integer increments. Figure 2.1(b) il-  
lustrates this coordinate convention.  
Image Processing Toolbox documentation refers to the coordinates in Fig.  
2
.1(b) as pixel coordinates. Less frequently, the toolbox also employs another  
coordinate convention,called spatial coordinates,that uses x to refer to columns  
and y to refers to rows.This is the opposite of our use of variables x and y.With  
.
. . .  
. . . .  
. . . .  
. . . .  
N
a b  
Figuꢀꢁ 2.1  
Coordinate  
0
1
2
N 1  
1
2
3
y
c
0
1
1
2
Origin  
Origin  
2
3
conventions used  
.
.
.
.
(a) in many image  
.
.
.
.
processing books,  
and (b) in the  
Image Processing  
Toolbox.  
.
.
.
.
.
.
.
.
M 1  
M
One pixel  
One pixel  
x
r
2
.2  Images as Matrices 15  
a few exceptions, we do not use the toolbox’s spatial coordinate convention in  
this book, but many MATLAB functions do, and you will definitely encounter  
it in toolbox and MATLAB documentation.  
2
.1.2 Images as Matrices  
The coordinate system in Fig. 2.1(a) and the preceding discussion lead to the  
following representation for a digitized image:  
f(0, 0)  
f(1, 0)  
f(0,1)  
f(1,1)  
f(0, N - 1)  
f(1, N - 1)  
f(x, y) =  
f(M - 1, 0) f(M - 1,1)  f(M - 1, N - 1)  
The right side of this equation is a digital image by definition. Each element  
of this array is called an image element, picture element, pixel, or pel.The terms  
image and pixel are used throughout the rest of our discussions to denote a  
digital image and its elements.  
A digital image can be represented as a MATLAB matrix:  
MATLAB  
documentation uses  
the terms matrix and  
array interchangeably.  
However, keep in mind  
that a matrix is two  
dimensional, whereas an  
array can have any finite  
dimension.  
f(1,1) f(1,2)  f(1,N)  
f(2,1) f(2,2)  f(2,N)  
f =  
f(M,1) f(M,2)  f(M,N)  
where f(1, 1) = f(0, 0) (note the use of a monospace font to denote MAT-  
LAB quantities). Clearly, the two representations are identical, except for the  
shift in origin.The notation f(p,q)denotes the element located in row pand  
column q. For example, f(6,2) is the element in the sixth row and second  
column of matrix f.Typically, we use the letters Mand N, respectively, to denote  
the number of rows and columns in a matrix.A 1* Nmatrix is called a row vec-  
tor, whereas an M*1matrix is called a column vector. A 1* 1matrix is a scalar.  
Matrices in MATLAB are stored in variables with names such as A, a, RGB,  
real_array, and so on. Variables must begin with a letter and contain only  
letters, numerals, and underscores. As noted in the previous paragraph, all  
MATLAB quantities in this book are written using monospace characters.We  
use conventional Roman, italic notation, such as f(x, y), for mathematical ex-  
pressions.  
Recall from Section 1.6  
that we use margin icons  
to highlight the first  
use of a MATLAB or  
toolbox function.  
2
.2 Reading Images  
Images are read into the MATLAB environment using function imread,whose  
basic syntax is  
imread('filename')  
imread  
1
6
Chapter 2  Fundamentals  
Here, filenameis a string containing the complete name of the image file (in-  
cluding any applicable extension). For example, the statement  
>> f = imread('chestxray.jpg');  
reads the image from the JPEG file chestxrayinto image array f. Note the  
semicolon(;) use of single quotes (') to delimit the string filename. The semicolon at the  
end of a statement is used by MATLAB for suppressing output. If a semicolon  
is not included,MATLAB displays on the screen the results of the operation(s)  
prompt(>>)  
specified in that line. The prompt symbol (>>) designates the beginning  
of a command line, as it appears in the MATLAB Command Window (see  
Fig. 1.1).  
When, as in the preceding command line, no path information is included  
in filename, imread reads the file from the Current Directory and, if that  
fails, it tries to find the file in the MATLAB search path (see Section 1.7).The  
simplest way to read an image from a specified directory is to include a full or  
relative path to that directory in filename. For example,  
In Windows, directories  
are called folders.  
>> f = imread('D:\myimages\chestxray.jpg');  
reads the image from a directory called myimagesin the D: drive, whereas  
> f = imread('.\myimages\chestxray.jpg');  
>
reads the image from the myimagessubdirectory of the current working direc-  
tory. The MATLAB Desktop displays the path to the Current Directory on  
the toolbar, which provides an easy way to change it. Table 2.1 lists some of  
the most popular image/graphics formats supported by imreadand imwrite  
(
imwriteis discussed in Section 2.4).  
Typing size at the prompt gives the row and column dimensions of an  
image:  
size  
>> size(f)  
ans =  
1024  
1024  
More generally, for an array A having an arbitrary number of dimensions, a  
statement of the form  
[D1,D2,...,DK] = size(A)  
returns the sizes of the first Kdimensions of A.This function is particularly use-  
ful in programming to determine automatically the size of a 2-D image:  
>> [M, N] = size(f);  
This syntax returns the number of rows (M) and columns (N) in the image. Simi-  
larly, the command  
2
.2  Reading Images 17  
Tꢂblꢁ 2.1  
Some of the  
Format  
Name  
Recognized  
Extensions  
Description  
Windows Bitmap  
image/graphics  
formats support-  
ed by imreadand  
imwrite, starting  
with MATLAB  
7.6. Earlier  
versions support  
a subset of these  
formats. See the  
MATLAB docu-  
mentation for a  
complete list of  
supported formats.  
BMP†  
.bmp  
CUR  
Windows Cursor Resources  
.cur  
FITS†  
GIF  
Flexible Image Transport System  
Graphics Interchange Format  
Hierarchical Data Format  
Windows Icon Resources  
.fts,.fits  
.gif  
HDF  
ICO†  
.hdf  
.ico  
JPEG  
JPEG 2000†  
Joint Photographic Experts Group  
Joint Photographic Experts Group  
.jpg,.jpeg  
.jp2,.jpf,.jpx,  
j2c,j2k  
PBM  
PGM  
PNG  
PNM  
RAS  
TIFF  
XWD  
Portable Bitmap  
.pbm  
Portable Graymap  
Portable Network Graphics  
Portable Any Map  
Sun Raster  
.pgm  
.png  
.pnm  
.ras  
Tagged Image File Format  
X Window Dump  
.tif,.tiff  
.xwd  
Supported by imread, but not by imwrite  
>> M = size(f, 1);  
gives the size of falong its first dimension, which is defined by MATLAB as  
the vertical dimension. That is, this command gives the number of rows in f.  
The second dimension of an array is in the horizontal direction, so the state-  
ment size(f,2)gives the number of columns in f. A singleton dimension is  
any dimension, dim, for which size(A,dim)=1.  
The whos function displays additional information about an array. For  
instance, the statement  
>> whos f  
whos  
gives  
Name  
f
Size  
Bytes  
Class  
uint8  
Attributes  
Although not applicable  
in this example,  
attributes that might  
appear under  
1024x1024 1048576  
Attributesinclude  
terms such as global,  
The Workspace Browser in the MATLAB Desktop displays similar informa-  
tion. The uint8 entry shown refers to one of several MATLAB data classes complex, and sparse.  
discussed in Section 2.5.A semicolon at the end of a whosline has no effect, so  
normally one is not used.  
1
8
Chapter 2  Fundamentals  
2
.3 Displaying Images  
Images are displayed on the MATLAB desktop using function imshow, which  
has the basic syntax:  
imshow  
imshow(f)  
Function imshowhas a  
number of other syntax  
forms for performing  
tasks such as controlling  
image magnification.  
Consult the help page for  
imshowfor additional  
details.  
where fis an image array. Using the syntax  
imshow(f, [low high])  
displays as black all values less than or equal to low, and as white all values  
greater than or equal to high.The values in between are displayed as interme-  
diate intensity values. Finally, the syntax  
imshow(f, [ ])  
sets variable lowto the minimum value of array fand highto its maximum  
value. This form of imshow is useful for displaying images that have a low  
dynamic range or that have positive and negative values.  
EXAMPLE 2.1:  
Reading and  
displaying images.  
 The following statements read from disk an image called rose_512.tif,  
extract information about the image, and display it using imshow:  
>
>
> f = imread('rose_512.tif');  
> whos f  
Name  
f
Size  
Bytes  
Class  
Attributes  
512x512  
262144  
uint8 array  
>> imshow(f)  
A semicolon at the end of an imshowline has no effect, so normally one is not  
used. Figure 2.2 shows what the output looks like on the screen. The figure  
Figuꢀꢁ 2.2  
Screen capture  
showing how an  
image appears  
on the MATLAB  
desktop. Note the  
figure number on  
the top, left of the  
window. In most  
of the examples  
throughout the  
book, only the  
images  
themselves are  
shown.  
2
.3  Displaying Images 19  
number appears on the top, left of the window. Note the various pull-down  
menus and utility buttons. They are used for processes such as scaling, saving,  
and exporting the contents of the display window. In particular, the Edit menu  
has functions for editing and formatting the contents before they are printed  
or saved to disk.  
If another image, g, is displayed using imshow, MATLAB replaces the  
image in the figure window with the new image. To keep the first image and  
output a second image, use function figure, as follows:  
>> figure, imshow(g)  
figure  
Using the statement  
Function figurecreates  
a figure window. When  
used without an  
argument, as shown here,  
it simply creates a new  
figure window. Typing  
figure(n)forces figure  
number nto become  
>> imshow(f), figure, imshow(g)  
displays both images. Note that more than one command can be written on a  
line, provided that different commands are delimited by commas or semico-  
lons. As mentioned earlier, a semicolon is used whenever it is desired to sup- visible.  
press screen outputs from a command line.  
Finally, suppose that we have just read an image, h, and find that using  
imshow(h)produces the image in Fig. 2.3(a).This image has a low dynamic range,  
a condition that can be remedied for display purposes by using the statement  
>> imshow(h, [ ])  
Figure 2.3(b) shows the result. The improvement is apparent.  
The Image Tool in the Image Processing Toolbox provides a more interac-  
tive environment for viewing and navigating within images, displaying detailed  
information about pixel values, measuring distances, and other useful opera-  
tions. To start the Image Tool, use the imtoolfunction. For example, the fol-  
lowing statements read an image from a file and then display it using imtool:  
>
>
> f = imread('rose_1024.tif');  
> imtool(f)  
imtool  
a b  
Figuꢀꢁ 2.3 (a) An  
image, h, with low  
dynamic range.  
(
b) Result of  
scaling by using  
imshow(h,[]).  
(
Original image  
courtesy of Dr.  
David R. Pickens,  
Vanderbilt  
University  
Medical Center.)  
2
0
Chapter 2  Fundamentals  
Figuꢀꢁ 2.4 The Image Tool. The Overview Window, Main Window, and Pixel Region tools are shown.  
Figure 2.4 shows some of the windows that might appear when using the  
Image Tool.The large, central window is the main view. In the figure, it is show-  
ing the image pixels at 400% magnification, meaning that each image pixel is  
rendered on a 4 * 4 block of screen pixels.The status text at the bottom of the  
main window shows the column/row location (701, 360) and value (181) of the  
pixel lying under the mouse cursor (the origin of the image is at the top, left).  
The Measure Distance tool is in use, showing that the distance between the two  
pixels enclosed by the small boxes is 25.65 units.  
The Overview Window, on the left side of Fig. 2.4, shows the entire image  
in a thumbnail view. The Main Window view can be adjusted by dragging the  
rectangle in the Overview Window.The Pixel Region Window shows individual  
pixels from the small square region on the upper right tip of the rose, zoomed  
large enough to see the actual pixel values.  
Table 2.2 summarizes the various tools and capabilities associated with  
the Image Tool. In addition to the these tools, the Main and Overview Win-  
dow toolbars provide controls for tasks such as image zooming, panning, and  
scrolling.  
2
.4  Writing Images 21  
Tꢂblꢁ 2.2 Tools  
associated with  
Tool  
Description  
the Image Tool.  
Pixel Information  
Pixel Region  
Distance  
Displays information about the pixel under the mouse pointer.  
Superimposes pixel values on a zoomed-in pixel view.  
Measures the distance between two pixels.  
Image Information Displays information about images and image files.  
Adjust Contrast  
Crop Image  
Display Range  
Overview  
Adjusts the contrast of the displayed image.  
Defines a crop region and crops the image.  
Shows the display range of the image data.  
Shows the currently visible image.  
2
.4 Writing Images  
Images are written to the Current Directory using function imwrite, which  
has the following basic syntax:  
imwrite(f, 'filename')  
imwrite  
With this syntax, the string contained in filenamemust include a recognized  
file format extension (see Table 2.1). For example, the following command  
writes fto a file called patient10_run1.tif:  
>> imwrite(f, 'patient10_run1.tif')  
Function imwrite writes the image as a TIFF file because it recognizes the  
.tifextension in the filename.  
Alternatively, the desired format can be specified explicitly with a third in-  
put argument. This syntax is useful when the desired file does not use one of  
the recognized file extensions. For example, the following command writes fto  
a TIFF file called patient10.run1:  
>> imwrite(f, 'patient10.run1', 'tif')  
Function imwritecan have other parameters, depending on the file format  
selected. Most of the work in the following chapters deals either with JPEG or  
TIFF images, so we focus attention here on these two formats.A more general  
imwritesyntax applicable only to JPEG images is  
imwrite(f, 'filename.jpg', 'quality', q)  
where qis an integer between 0 and 100 (the lower the number the higher  
the degradation due to JPEG compression).  
2
2
Chapter 2  Fundamentals  
EXAMPLE 2.2:  
Writing an image  
and using  
 Figure 2.5(a) shows an image, f, typical of sequences of images resulting  
from a given chemical process. It is desired to transmit these images on a rou-  
tine basis to a central site for visual and/or automated inspection. In order to  
reduce storage requirements and transmission time, it is important that the  
images be compressed as much as possible, while not degrading their visual  
function imfinfo.  
a b  
c d  
e f  
Figuꢀꢁ 2.5  
(
(
a) Original image.  
b) through (f)  
Results of using  
jpgquality values  
q=50, 25, 15, 5,  
and 0, respectively.  
False contouring  
begins to be  
noticeable for  
q=15[image (d)]  
and is quite  
visible for q=5  
and q=0.  
See Example 2.11 for  
a function that creates  
all the images in Fig. 2.5  
using a loop.  
2
.4  Writing Images 23  
appearance beyond a reasonable level. In this case “reasonable” means no per-  
ceptible false contouring. Figures 2.5(b) through (f) show the results obtained  
by writing image f to disk (in JPEG format), with q = 50, 25, 15, 5, and 0,  
respectively. For example, the applicable syntax for q=25is  
>> imwrite(f, 'bubbles25.jpg', 'quality', 25)  
The image for q = 15 [Fig. 2.5(d)] has false contouring that is barely vis-  
ible, but this effect becomes quite pronounced for q = 5 and q = 0. Thus, an  
acceptable solution with some margin for error is to compress the images with  
q=25. In order to get an idea of the compression achieved and to obtain other  
image file details, we can use function imfinfo, which has the syntax  
imfinfo filename  
imfinfo  
where filenameis the file name of the image stored on disk. For example,  
>> imfinfo bubbles25.jpg  
outputs the following information (note that some fields contain no informa- Recent versions of  
MATLAB may show  
more information in  
tion in this case):  
the output of imfinfo,  
particularly for images  
captures using digital  
cameras.  
Filename: 'bubbles25.jpg'  
FileModDate: '04-Jan-2003 12:31:26'  
FileSize: 13849  
Format: 'jpg'  
FormatVersion: ''  
Width: 714  
Height: 682  
BitDepth:  
ColorType: 'grayscale'  
FormatSignature: ''  
8
Comment: {}  
where FileSizeis in bytes. The number of bytes in the original image is com-  
puted by multiplying Widthby Heightby BitDepthand dividing the result by  
8.The result is 486948. Dividing this by FileSizegives the compression ratio:  
(
486948 13849) = 35.16. This compression ratio was achieved while main-  
taining image quality consistent with the requirements of the application. In  
addition to the obvious advantages in storage space, this reduction allows the  
transmission of approximately 35 times the amount of uncompressed data per  
unit time.  
The information fields displayed by imfinfo can be captured into a so-  
called structure variable that can be used for subsequent computations. Using  
the preceding image as an example, and letting Kdenote the structure variable,  
we use the syntax  
Structures are  
discussed in Section  
2
.10.7.  
>> K = imfinfo('bubbles25.jpg');  
to store into variable K all the information generated by command imfinfo.  
2
4
Chapter 2  Fundamentals  
The information generated by imfinfois appended to the structure variable  
by means of fields, separated from Kby a dot. For example, the image height  
and width are now stored in structure fields K.Height and K.Width. As an  
illustration, consider the following use of structure variable Kto compute the  
compression ratio for bubbles25.jpg:  
>
>
>
>
> K = imfinfo('bubbles25.jpg');  
> image_bytes = K.Width*K.Height*K.BitDepth/8;  
> compressed_bytes = K.FileSize;  
> compression_ratio = image_bytes/compressed_bytes  
compression_ratio =  
5.1612  
3
Note that imfinfo was used in two different ways. The first was to type  
imfinfo bubbles25.jpgattheprompt,whichresultedintheinformationbeing  
displayedonthescreen.ThesecondwastotypeK=imfinfo('bubbles25.jpg'),  
which resulted in the information generated by imfinfo being stored in K.  
These two different ways of calling imfinfo are an example of command-  
function duality, an important concept that is explained in more detail in the  
To learn more about  
command function  
duality, consult the help  
page on this topic. (See  
Section 1.7.2 regarding  
help pages.)  
MATLAB documentation.  
A more general imwrite syntax applicable only to tif images has the  
form  
...  
imwrite(g, 'filename.tif', 'compression', 'parameter', ...  
resolution', [colres rowres])  
'
If a statement does not  
fit on one line, use an  
ellipsis (three periods),  
followed by Return or  
Enter, to indicate that  
the statement continues  
on the next line. There  
are no spaces between  
the periods.  
where 'parameter'can have one of the following principal values: 'none'indi-  
cates no compression; 'packbits'(the default for nonbinary images), 'lwz',  
'
deflate', 'jpeg', 'ccitt'(binary images only; the default), 'fax3'(binary  
images only), and 'fax4'. The 1 * 2 array [colres rowres] contains two  
integers that give the column resolution and row resolution in dots-per-unit  
(the default values are [72 72]). For example, if the image dimensions are in  
inches, colres is the number of dots (pixels) per inch (dpi) in the vertical  
direction, and similarly for rowresin the horizontal direction. Specifying the  
resolution by a single scalar, res, is equivalent to writing [resres]. As you  
will see in the following example, the TIFF resolution parameter can be used  
to modify the size of an image in printed documents.  
EXAMPLE 2.3:  
Using imwrite  
parameters.  
 Figure 2.6(a) is an 8-bit X-ray image, f, of a circuit board generated dur-  
ing quality inspection. It is in jpg format, at 200 dpi. The image is of size  
4
50 * 450 pixels, so its printed dimensions are 2.25 * 2.25 inches.We want to  
store this image in tifformat, with no compression, under the name sf. In  
addition, we want to reduce the printed size of the image to 1.5 * 1.5 inches  
while keeping the pixel count at 450 * 450.The following statement gives the  
desired result:  
2
.4  Writing Images 25  
a
b
Figuꢀꢁ 2.6  
Effects of  
changing the dpi  
resolution while  
keeping the  
number of pixels  
constant. (a) A  
4
50 450 image  
at 200 dpi  
size = 2.25 2.25  
(
inches). (b) The  
same image, but  
at 300 dpi  
(
size = 1.5 1.5  
inches). (Original  
image courtesy of  
Lixi, Inc.)  
>> imwrite(f,'sf.tif','compression','none','resolution',[300 300])  
The values of the vector [colres rowres]were determined by multiplying  
2
00 dpi by the ratio 2.25 1.5 which gives 300 dpi. Rather than do the computa-  
tion manually, we could write  
>> res = round(200*2.25/1.5);  
round  
>> imwrite(f, 'sf.tif', 'compression', 'none' ,'resolution', res)  
where function roundrounds its argument to the nearest integer. It is impor-  
tant to note that the number of pixels was not changed by these commands.  
Only the printed size of the image changed. The original 450 * 450 image at  
2
00 dpi is of size 2.25 * 2.25 inches. The new 300-dpi image [Fig. 2.6(b)] is  
identical, except that its 450 * 450 pixels are distributed over a 1.5 * 1.5-inch  
area. Processes such as this are useful for controlling the size of an image in a  
printed document without sacrificing resolution.  
Sometimes, it is necessary to export images and plots to disk the way they  
appear on the MATLAB desktop. The contents of a figure window can be  
exported to disk in two ways.The first is to use the File pull-down menu in the  
figure window (see Fig. 2.2) and then choose Save As. With this option, the  
2
6
Chapter 2  Fundamentals  
user can select a location, file name, and format. More control over export  
parameters is obtained by using the printcommand:  
print  
print −fno −dfileformat −rresno filename  
where norefers to the figure number in the figure window of interest, file-  
formatrefers to one of the file formats in Table 2.1, resnois the resolution  
in dpi, and filenameis the name we wish to assign the file. For example, to  
export the contents of the figure window in Fig. 2.2 as a tiffile at 300 dpi, and  
under the name hi_res_rose, we would type  
>> print −f1 −dtiff −r300 hi_res_rose  
This command sends the file hi_res_rose.tif to the Current Directory. If  
we type print at the prompt, MATLAB prints (to the default printer) the  
contents of the last figure window displayed. It is possible also to specify other  
options with print, such as a specific printing device.  
2.5 Classes  
Although we work with integer coordinates, the values (intensities) of pixels  
are not restricted to be integers in MATLAB.Table 2.3 lists the various classes  
supported by MATLAB and the Image Processing Toolbox for representing  
pixel values.The first eight entries in the table are referred to as numeric class-  
Tꢂblꢁ 2.3  
Name  
Description  
Classes used for  
image processing  
in MATLAB. The  
first eight entries  
are referred to as  
numeric classes,  
the ninth entry is  
the char class, and  
the last entry is  
the logical class.  
double  
Double-precision, floating-point numbers in the approximate  
range ; 10 (8 bytes per element).  
3
08  
single  
Single-precision floating-point numbers with values in the  
38  
approximate range ; 10 (4 bytes per element).  
uint8  
Unsigned 8-bit integers in the range [0, 255] (1 byte per element).  
uint16  
Unsigned 16-bit integers in the range [0, 65535] (2 bytes per  
element).  
uint32  
Unsigned 32-bit integers in the range [0, 4294967295] (4 bytes per  
element).  
int8  
Signed 8-bit integers in the range [128, 127] (1 byte per element).  
int16  
Signed 16-bit integers in the range [32768, 32767] (2 bytes per  
element).  
int32  
Signed 32-bit integers in the range [2147483648, 2147483647]  
(
4 bytes per element).  
char  
Characters (2 bytes per element).  
logical  
Values are 0 or 1 (1 byte per element).  
MATLAB supports two other numeric classes not listed in Table 2.3, uint64and int64.The toolbox does  
not support these classes, and MATLAB arithmetic support for them is limited.  
2
.6  Image Types 27  
es. The ninth entry is the char (character) class and, as shown, the last entry is  
the logical class.  
Classes uint8and logicalare used extensively in image processing, and  
they are the usual classes encountered when reading images from image file  
formats such as TIFF or JPEG.These classes use 1 byte to represent each pixel.  
Some scientific data sources, such as medical imagery, require more dynamic  
range than is provided by uint8, so the uint16 and int16 classes are used  
often for such data.These classes use 2 bytes for each array element.The float-  
ing-point classes double and single are used for computationally intensive  
operations such as the Fourier transform (see Chapter 4). Double-precision  
floating-point uses 8 bytes per array element, whereas single-precision float-  
ing-point uses 4 bytes. The int8, uint32, and int32classes, although support-  
ed by the toolbox, are not used commonly for image processing.  
2
.6 Image Types  
The toolbox supports four types of images:  
Gray-scale images  
Binary images  
Indexed images  
RGB images  
Gray-scale images are  
referred to as intensity  
images in earlier versions  
of the toolbox. In the  
book, we use the two  
terms interchangeably  
when working with  
Most monochrome image processing operations are carried out using binary  
or gray-scale images, so our initial focus is on these two image types. Indexed  
and RGB color images are discussed in Chapter 7.  
monochrome images.  
2
.6.1 Gray-scale Images  
A gray-scale image is a data matrix whose values represent shades of gray.  
When the elements of a gray-scale image are of class uint8or uint16, they  
have integer values in the range [0, 255] or [0, 65535], respectively. If the image  
is of class double or single, the values are floating-point numbers (see the  
first two entries in Table 2.3). Values of doubleand singlegray-scale images  
normally are scaled in the range [0, 1], although other ranges can be used.  
2
.6.2 Binary Images  
Binary images have a very specific meaning in MATLAB. A binary image is a  
logical array of 0s and 1s. Thus, an array of 0s and 1s whose values are of data  
class, say, uint8, is not considered a binary image in MATLAB. A numeric  
array is converted to binary using function logical. Thus, if A is a numeric  
array consisting of 0s and 1s, we create a logical array Busing the statement  
B = logical(A)  
logical  
If Acontains elements other than 0s and 1s, the logicalfunction converts all  
nonzero quantities to logical 1s and all entries with value 0 to logical 0s. Using  
relational and logical operators (see Section 2.10.2) also results in logical arrays.  
2
8
Chapter 2  Fundamentals  
To test if an array is of class logicalwe use the islogicalfunction:  
islogical  
islogical(C)  
See Table 2.9 for a list of  
other functions based on  
the is...construct.  
If Cis a logical array, this function returns a 1. Otherwise it returns a 0. Logical  
arrays can be converted to numeric arrays using the class conversion functions  
discussed in Section 2.7.  
2
.6.3 A Note on Terminology  
Considerable care was taken in the previous two sections to clarify the use  
of the terms class and image type. In general, we refer to an image as being a  
classimage_type image,” where classis one of the entries from Table 2.3,  
and image_type is one of the image types defined at the beginning of this sec-  
tion. Thus, an image is characterized by both a class and a type. For instance, a  
statement discussing an “uint8gray-scale image” is simply referring to a gray-  
scale image whose pixels are of class uint8. Some functions in the toolbox  
support all the data classes listed in Table 2.3, while others are very specific as  
to what constitutes a valid class.  
2
.7 Converting between Classes  
Converting images from one class to another is a common operation. When  
converting between classes, keep in mind the value ranges of the classes being  
converted (see Table 2.3).  
The general syntax for class conversion is  
B = class_name(A)  
where class_name is one of the names in the first column of Table 2.3. For  
example, suppose that Ais an array of class uint8.A double-precision array, B,  
is generated by the command B=double(A). If Cis an array of class double  
in which all values are in the range [0, 255] (but possibly containing fractional  
values), it can be converted to an uint8array with the command D=uint8(C).  
If an array of class doublehas any values outside the range [0, 255] and it is  
converted to class uint8in the manner just described, MATLAB converts to  
To simplify terminology,  
statements referring to  
values of class double  
are applicable also to the  
singleclass, unless  
stated otherwise. Both  
refer to floating point  
numbers, the only  
difference between them  
being precision and the  
number of bytes needed  
for storage.  
0
all values that are less than 0, and converts to 255 all values that are greater  
than 255. Numbers in between are rounded to the nearest integer.Thus, proper  
scaling of a doublearray so that its elements are in the range [0, 255] is neces-  
sary before converting it to uint8. As indicated in Section 2.6.2, converting  
any of the numeric data classes to logicalcreates an array with logical 1s in  
locations where the input array has nonzero values, and logical 0s in places  
where the input array contains 0s.  
The toolbox provides specific functions (Table 2.4) that perform the scaling  
and other bookkeeping necessary to convert images from one class to another.  
Function im2uint8, for example, creates a unit8 image after detecting the  
2
.7  Converting between Classes 29  
Tꢂblꢁ 2.4  
Toolbox functions  
for converting  
images from one  
class to another.  
Name  
Converts Input to:  
Valid Input Image Data Classes  
im2uint8  
uint8  
logical, uint8, uint16, int16, single,  
and double  
im2uint16  
im2double  
im2single  
mat2gray  
im2bw  
uint16  
double  
single  
logical, uint8, uint16, int16, single,  
and double  
logical, uint8, uint16, int16, single,  
and double  
logical, uint8, uint16, int16, single,  
and double  
doublein the range [0, 1] logical, uint8, int8, uint16, int16,  
uint32, int32, single, and double  
logical  
uint8, uint16, int16, single, and  
double  
data class of the input and performing all the necessary scaling for the toolbox  
to recognize the data as valid image data. For example, consider the following  
image fof class double, which could be the result of an intermediate computa-  
tion:  
f =  
0.5  
.75  
0.5  
1.5  
0
Performing the conversion  
>> g = im2uint8(f)  
im2uint8  
yields the result  
g =  
0
128  
255  
1
91  
from which we see that function im2uint8sets to 0 all values in the input that  
are less than 0, sets to 255 all values in the input that are greater than 1, and  
multiplies all other values by 255. Rounding the results of the multiplication to  
the nearest integer completes the conversion.  
Function im2doubleconverts an input to class double. If the input is of class  
uint8, uint16, or logical, function im2double converts it to class double  
with values in the range [0, 1]. If the input is of class single, or is already of class  
double, im2doublereturns an array that is of class double, but is numerically  
equal to the input. For example, if an array of class double results from com-  
putations that yield values outside the range [0, 1], inputting this array into  
im2double  
3
0
Chapter 2  Fundamentals  
im2doublewill have no effect. As explained below, function mat2graycan be  
used to convert an array of any of the classes in Table 2.4 to a doublearray  
with values in the range [0, 1].  
As an illustration, consider the class uint8image  
Section 2.8.2 explains the  
use of square brackets  
and semicolons to  
>> h = uint8([25 50; 128 200]);  
Performing the conversion  
specify matrices.  
>> g = im2double(h)  
yields the result  
g =  
0
0
.0980  
.4706  
0.1961  
0.7843  
from which we infer that the conversion when the input is of class uint8 is  
done simply by dividing each value of the input array by 255. If the input is of  
class uint16the division is by 65535.  
Toolboxfunctionmat2grayconvertsanimageofanyoftheclassesinTable2.4  
to an array of class doublescaled to the range [0, 1]. The calling syntax is  
mat2gray  
g = mat2gray(A, [Amin, Amax])  
where image g has values in the range 0 (black) to 1 (white). The specified  
parameters, Aminand Amax, are such that values less than Aminin Abecome 0  
in g, and values greater than Amaxin Acorrespond to 1 in g. The syntax  
g = mat2gray(A)  
sets the values of Aminand Amaxto the actual minimum and maximum values  
in A. The second syntax of mat2grayis a very useful tool because it scales the  
entire range of values in the input to the range [0, 1], independently of the class  
of the input, thus eliminating clipping.  
Finally, we consider conversion to class logical. (Recall that the Image  
ProcessingToolbox treats logical matrices as binary images.) Function logical  
converts an input array to a logical array. In the process, nonzero elements  
in the input are converted to 1s, and 0s are converted to 0s in the output. An  
alternative conversion procedure that often is more useful is to use a relational  
operator, such as >, with a threshold value. For example, the syntax  
See Section 2.10.2  
regarding logical and  
relational operators.  
g = f > T  
produces a logical matrix containing 1s wherever the elements of fare greater  
than Tand 0s elsewhere.  
Toolbox function im2bwperforms this thresholding operation in a way that  
automatically scales the specified threshold in different ways, depending on  
the class of the input image. The syntax is  
2
.7  Converting between Classes 31  
g = im2bw(f, T)  
im2bw  
Values specified for the threshold Tmust be in the range [0, 1], regardless of  
the class of the input. The function automatically scales the threshold value  
according to the input image class. For example, if fis uint8and Tis 0.4, then  
im2bwthresholds the pixels in fby comparing them to 255*0.4=102.  
We wish to convert the following small, doubleimage  
> f = [1 2; 3 4]  
f =  
EXAMPLE 2.4:  
Converting  
between image  
classes.  
>
1
3
2
4
to binary, such that values 1 and 2 become 0 and the other two values become  
. First we convert it to the range [0, 1]:  
1
>> g = mat2gray(f)  
g =  
0
0.3333  
1.0000  
0
.6667  
Then we convert it to binary using a threshold, say, of value 0.6:  
>> gb = im2bw(g, 0.6)  
gb =  
0
1
0
1
As mentioned earlier, we can generate a binary array directly using relational  
operators. Thus we get the same result by writing  
>> gb = f > 2  
gb =  
0
1
0
1
Suppose now that we want to convert gbto a numerical array of 0s and 1s  
of class double. This is done directly:  
>> gbd = im2double(gb)  
gbd =  
0
1
0
1
3
2
Chapter 2  Fundamentals  
If gbhad been of class uint8, applying im2doubleto it would have resulted  
in an array with values  
0
0
0.0039  
0.0039  
because im2doublewould have divided all the elements by 255. This did not  
happen in the preceding conversion because im2double detected that the  
input was a logical array, whose only possible values are 0 and 1. If the  
input in fact had been of class uint8 and we wanted to convert it to class  
doublewhile keeping the 0 and 1 values,we would have converted the array by  
writing  
>> gbd = double(gb)  
gbd =  
0
1
0
1
Finally, we point out that the output of one function can be passed directly as  
the input to another, so we could have started with image fand arrived at the  
same result by using the one-line statement  
>> gbd = im2double(im2bw(mat2gray(f), 0.6));  
or by using partial groupings of these functions. Of course, the entire process  
could have been done in this case with a simpler command:  
>> gbd = double(f > 2);  
demonstrating again the compactness of the MATLAB language.  
As the first two entries in Table 2.3 show class numeric data of class double  
requires twice as much storage as data of class single. In most image pro-  
cessing applications in which numeric processing is used, singleprecision is  
perfectly adequate. Therefore, unless a specific application or a MATLAB or  
toolbox function requires class double, it is good practice to work with single  
data to conserve memory. A consistent programming pattern that you will see  
used throughout the book to change inputs to class singleis as follows:  
Recall from Section 1.6  
that we the a margin icon  
to denote the first use of  
a function developed in  
the book.  
tofloat  
[fout, revertclass] = tofloat(f);  
g = some_operation(fout)  
g = revertclass(g);  
See function intrans  
in Section 3.2.3 for an  
example of how tofloat  
is used.  
Function tofloat(see Appendix C for the code) converts an input image f  
to floating-point. If fis a doubleor singleimage, then foutequals f. Other-  
wise, foutequals im2single(f). Output revertclasscan be used to convert  
back to the same class as f. In other words, the idea is to convert the input  
2
.8  Array Indexing 33  
image to single, perform operations using singleprecision, and then, if so  
desired, convert the final output image to the same class as the input.The valid  
image classes for fare those listed in the third column of the first four entries  
in Table 2.4: logical, uint8, unint16, int16, double, and single.  
2.8 Array Indexing  
MATLAB supports a number of powerful indexing schemes that simplify  
array manipulation and improve the efficiency of programs. In this section we  
discuss and illustrate basic indexing in one and two dimensions (i.e., vectors  
and matrices), as well as indexing techniques useful with binary images.  
2
.8.1 Indexing Vectors  
As discussed in Section 2.1.2, an array of dimension 1* Nis called a row vector.  
The elements of such a vector can be accessed using a single index value (also  
called a subscript).Thus, v(1)is the first element of vector v, v(2)is its second  
element, and so forth. Vectors can be formed in MATLAB by enclosing the  
elements, separated by spaces or commas, within square brackets. For exam-  
ple,  
>> v = [1 3 5 7 9]  
v =  
1
3 5 7 9  
>> v(2)  
ans =  
3
A row vector is converted to a column vector (and vice versa) using the trans-  
pose operator (.'):  
transpose  
.')  
(
Using a single quote  
without the period  
>> w = v.'  
computes the conjugate  
transpose. When the data  
are real, both transposes  
can be used interchange-  
ably. See Table 2.5.  
w =  
1
3
5
7
9
To access blocks of elements, we use MATLAB’s colon notation. For example,  
to access the first three elements of vwe write  
colon (:)  
>> v(1:3)  
ans =  
1
3
5
3
4
Chapter 2  Fundamentals  
Similarly, we can access the second through the fourth elements  
>> v(2:4)  
ans =  
3
5
7
or all the elements from, say, the third through the last element:  
end  
>> v(3:end)  
ans =  
5
7
9
where endsignifies the last element in the vector.  
Indexing is not restricted to contiguous elements. For example,  
>> v(1:2:end)  
ans =  
1
5
9
The notation 1:2:endsays to start at 1, count up by 2, and stop when the count  
reaches the last element. The steps can be negative:  
>> v(end:−2:1)  
ans =  
9
5
1
Here, the index count started at the last element, decreased by 2, and stopped  
when it reached the first element.  
Function linspace, with syntax  
linspace  
x = linspace(a, b, n)  
generates a row vector xof nelements linearly-spaced between, and including,  
aand b. We use this function in several places in later chapters. A vector can  
even be used as an index into another vector. For example, we can select the  
first, fourth, and fifth elements of vusing the command  
>> v([1 4 5])  
ans =  
1
7
9
As we show in the following section, the ability to use a vector as an index into  
another vector also plays a key role in matrix indexing.  
2
.8  Array Indexing 35  
2
.8.2 Indexing Matrices  
Matrices can be represented conveniently in MATLAB as a sequence of row  
vectors enclosed by square brackets and separated by semicolons. For example,  
typing  
>> A = [1 2 3; 4 5 6; 7 8 9]  
gives the 3 * 3 matrix  
A =  
1
4
7
2
5
8
3
6
9
Note that the use of semicolons inside square brackets is different from their  
use mentioned earlier to suppress output or to write multiple commands in a  
single line.We select elements in a matrix just as we did for vectors, but now we  
need two indices: one to establish a row location, and the other for the corre-  
sponding column. For example, to extract the element in the second row, third  
column of matrix A, we write  
>> A(2, 3)  
ans =  
6
A submatrix of Acan be extracted by specifying a vector of values for both  
the row and the column indices. For example, the following statement extracts  
the submatrix of Acontaining rows 1 and 2 and columns 1, 2, and 3:  
>> T2 = A([1 2], [1 2 3])  
T2 =  
1
4
2
5
3
6
Because the expression 1:Kcreates a vector of integer values from 1through  
K, the preceding statement could be written also as:  
>> T2 = A(1:2, 1:3)  
T2 =  
1
4
2
5
3
6
The row and column indices do not have to be contiguous, nor do they have to  
be in ascending order. For example,  
3
6
Chapter 2  Fundamentals  
>> E = A([1 3], [3 2])  
E =  
3
9
2
8
The notation A([a b], [c d]) selects the elements in A with coordinates  
a,c), (a,d), (b,c), and (b,d). Thus, when we let E=A([1 3],[3 2]),  
(
we are selecting the following elements in A: A(1, 3), A(1, 2), A(3, 3), and  
A(3,2).  
The row or column index can also be a single colon. A colon in the row  
index position is shorthand notation for selecting all rows. Similarly, a colon  
in the column index position selects all columns. For example, the following  
statement selects the entire 3rd column of A:  
>> C3 = A(:, 3)  
C3 =  
3
6
9
Similarly, this statement extracts the second row:  
>> R2 = A(2, :)  
R2 =  
4
5
6
Any of the preceding forms of indexing can be used on the left-hand side of  
an assignment statement.The next two statements create a copy, B, of matrix A,  
and then assign the value 0to all elements in the 3rd column of B.  
>
>
> B = A;  
> B(:, 3) = 0  
B =  
1
4
7
2
5
8
0
0
0
The keyword end, when it appears in the row index position, is shorthand nota-  
tion for the last row. When endappears in the column index position, it indi-  
cates the last column. For example, the following statement finds the element  
in the last row and last column of A:  
2
.8  Array Indexing 37  
>> A(end, end)  
ans =  
9
When used for indexing, the endkeyword can be mixed with arithmetic opera-  
tions, as well as with the colon operator. For example:  
>> A(end, end − 2)  
ans =  
7
>> A(2:end, end:–2:1)  
ans =  
6
9
4
7
2
.8.3 Indexing with a Single Colon  
The use of a single colon as an index into a matrix selects all the elements of  
the array and arranges them (in column order) into a single column vector. For  
example, with reference to matrix T2in the previous section,  
>> v = T2(:)  
v =  
1
4
2
5
3
6
This use of the colon is helpful when, for example, we want to find the sum of  
all the elements of a matrix. One approach is to call function sumtwice:  
>
> col_sums = sum(A)  
col_sums =  
11  
sum  
1
15  
112  
Function sumcomputes the sum of each column of A, storing the results into a  
row vector. Then we call sumagain, passing it the vector of column sums:  
>
> total_sum = sum(col_sums)  
total_sum =  
38  
2
3
8
Chapter 2  Fundamentals  
An easier procedure is to use single-colon indexing to convert Ato a column  
vector, and pass the result to sum:  
>
> total_sum = sum(A(:))  
total_sum =  
38  
2
2
.8.4 Logical Indexing  
Another form of indexing that you will find quite useful is logical indexing. A  
logical indexing expression has the form A(D), where Ais an array and Dis a  
logical array of the same size as A. The expression A(D) extracts all the ele-  
ments of Acorresponding to the 1-valued elements of D. For example,  
>> D = logical([1 0 0; 0 0 1; 0 0 0])  
D =  
1
0
0
0
0
0
0
1
0
>> A(D)  
ans =  
1
6
where Ais as defined at the beginning of Section 2.8.2.The output of this meth-  
od of logical indexing always is a column vector.  
Logical indexing can be used also on the left-hand side of an assignment  
statement. For example, using the same Das above,  
>> A(D) = [30 40]  
A =  
3
0
4
7
2
5
8
3
40  
9
In the preceding assignment, the number of elements on the right-hand side  
matched the number of 1-valued elements of D. Alternatively, the right-hand  
side can be a scalar, like this:  
>> A(D) = 100  
A =  
2
.8  Array Indexing 39  
1
00  
2
5
8
3
100  
9
4
7
Because binary images are represented as logical arrays, they can be used  
directly in logical indexing expressions to extract pixel values in an image  
that correspond to 1-valued pixels in a binary image. You will see numerous  
examples later in the book that use binary images and logical indexing.  
2
.8.5 Linear Indexing  
The final category of indexing useful for image processing is linear indexing.  
A linear indexing expression is one that uses a single subscript to index a ma-  
trix or higher-dimensional array. To illustrate the concept we will use a 4 * 4  
Hilbert matrix as an example:  
>> H = hilb(4)  
hilb  
H =  
1
0
0
0
.0000  
.5000  
.3333  
.2500  
0.5000  
0.3333  
0.2500  
0.2000  
0.3333  
0.2500  
0.2000  
0.1667  
0.2500  
0.2000  
0.1667  
0.1429  
H([2 11])is an example of a linear indexing expression:  
> H([2 11])  
>
ans =  
0
.5000  
0.2000  
To see how this type of indexing works, number the elements of Hfrom the first  
to the last column in the order shown:  
1
.00001  
0.50005  
0.33336  
0.25007  
0.20008  
0.33339  
0.250010  
0.200011  
0.166712  
0.250013  
0.200014  
0.166715  
0.142916  
0
0
0
.50002  
.33333  
.25004  
Here you can see that H([2 11]) extracts the 2nd and 11th elements of H,  
based on the preceding numbering scheme.  
In image processing, linear indexing is useful for extracting a set of pixel val-  
ues from arbitrary locations. For example, suppose we want an expression that  
extracts the values of Hat row-column coordinates (1, 3), (2, 4), and (4, 3):  
4
0
Chapter 2  Fundamentals  
>
>
> r = [1 2 4];  
> c = [3 4 3];  
Expression H(r,c)does not do what we want, as you can see:  
> H(r, c)  
>
ans =  
0
0
0
.3333  
.2500  
.1667  
0.2500  
0.2000  
0.1429  
0.3333  
0.2500  
0.1667  
Instead, we convert the row-column coordinates to linear index values, as fol-  
lows:  
>
>
> M = size(H, 1);  
> linear_indices = M*(c − 1) + r  
linear_indices =  
14 12  
9
>> H(linear_indices)  
ans =  
0
.3333  
0.2000  
0.1667  
MATLAB functions sub2ind and ind2sub convert back and forth between  
row-column subscripts and linear indices. For example,  
sub2ind  
ind2sub  
>> linear_indices = sub2ind(size(H), r, c)  
linear_indices =  
9
14  
12  
>> [r, c] = ind2sub(size(H), linear_indices)  
r =  
1
2
4
c =  
3
4
3
Linear indexing is a basic staple in vectorizing loops for program optimization,  
as discussed in Section 2.10.5.  
EXAMPLE 2.5:  
Some simple  
image operations  
using array  
 The image in Fig. 2.7(a) is a 1024 * 1024 gray-scale image, f, of class uint8.  
The image in Fig. 2.7(b) was flipped vertically using the statement  
>> fp = f(end:−1:1, :);  
indexing.  
2
.8  Array Indexing 41  
a b  
c
d e  
FIGURE 2.7  
Results obtained  
using array  
indexing.  
(
a) Original  
image. (b) Image  
flipped vertically.  
(
c) Cropped  
image.  
(
d) Subsampled  
image. (e) A  
horizontal scan  
line through the  
middle of the  
image in (a).  
3
2
2
1
1
00  
50  
00  
50  
00  
5
0
0
0
200  
400  
600  
800 1000  
The image in Fig. 2.7(c) is a section out of image (a), obtained using the com-  
mand  
>> fc = f(257:768, 257:768);  
Similarly, Fig. 2.7(d) shows a subsampled image obtained using the statement  
>> fs = f(1:2:end, 1:2:end);  
Finally, Fig. 2.7(e) shows a horizontal scan line through the middle of Fig. 2.7(a),  
obtained using the command  
>> plot(f(512, :))  
plot  
Function plotis discussed in Section 3.3.1.  
4
2
Chapter 2  Fundamentals  
2
.8.6 Selecting Array Dimensions  
Operations of the form  
operation(A, dim)  
where operation denotes an applicable MATLAB operation, A is an array,  
and dimis a scalar, are used frequently in this book. For example, if Ais a 2-D  
array, the statement  
>> k = size(A, 1);  
gives the size of Aalong its first dimension (i.e., it gives the number of rows in  
A). Similarly, the second dimension of an array is in the horizontal direction,  
so the statement size(A, 2)gives the number of columns in A. Using these  
concepts, we could have written the last command in Example 2.5 as  
>> plot(f(size(f, 1)/2, :))  
MATLAB does not restrict the number of dimensions of an array, so being  
able to extract the components of an array in any dimension is an important  
feature. For the most part, we deal with 2-D arrays, but there are several in-  
stances (as when working with color or multispectral images) when it is neces-  
sary to be able to “stack” images along a third or higher dimension. We deal  
with this in Chapters 7, 8, 12, and 13. Function ndims, with syntax  
ndims  
d = ndims(A)  
gives the number of dimensions of array A. Function ndims never returns a  
value less than 2 because even scalars are considered two dimensional, in the  
sense that they are arrays of size 1 * 1.  
2
.8.7 Sparse Matrices  
When a matrix has a large number of 0s, it is advantageous to express it in  
sparse form to reduce storage requirements. Function sparseconverts a ma-  
trix to sparse form by “squeezing out” all zero elements. The basic syntax for  
this function is  
sparse  
S = sparse(A)  
For example, if  
>> A = [1 0 0; 0 3 4; 0 2 0]  
A =  
1
0
0
0
3
2
0
4
0
2
.9  Some Important Standard Arrays 43  
Then  
>> S = sparse(A)  
S =  
(
(
(
(
1,1)  
2,2)  
3,2)  
2,3)  
1
3
2
4
from which we see that Scontains only the (row, col) locations of nonzero ele-  
ments (note that the elements are sorted by columns). To recover the original  
(full) matrix, we use function full:  
>> Original = full(S)  
full  
Original =  
1
0
0
0
3
2
0
4
0
A syntax used sometimes with function sparsehas five inputs:  
S = sparse(r, c, s, m, n)  
The syntax sparse(A)  
requires that there be  
enough memory to  
where r and c are vectors containing, respectively, the row and column indi- hold the entire matrix.  
When that is not the  
case, and the location  
ces of the nonzero elements of the matrix we wish to express in sparse form.  
Parameter s is a vector containing the values corresponding to index pairs  
r, c), and m and n are the row and column dimensions of the matrix. For  
and values of all nonzero  
elements are known, the  
alternate syntax shown  
(
instance, the preceding matrix S can be generated directly using the com- here provides a solution  
for generating a sparse  
matrix.  
mand  
>> S = sparse([1 2 3 2], [1 2 2 3], [1 3 2 4], 3, 3)  
S =  
(
(
(
(
1,1)  
2,2)  
3,2)  
2,3)  
1
3
2
4
Arithmetic and other operations (Section 2.10.2) on sparse matrices are car-  
ried out in exactly the same way as with full matrices. There are a number of  
other syntax forms for function sparse, as detailed in the help page for this  
function.  
2
.9 Some Important Standard Arrays  
Sometimes, it is useful to be able to generate image arrays with known charac-  
teristics to try out ideas and to test the syntax of functions during development.  
In this section we introduce eight array-generating functions that are used in  
4
4
Chapter 2  Fundamentals  
later chapters. If only one argument is included in any of the following func-  
tions, the result is a square array.  
zeros(M,N)generates an M* Nmatrix of 0s of class double.  
ones(M,N)generates an M* Nmatrix of 1s of class double.  
true(M,N)generates an M* Nlogicalmatrix of 1s.  
false(M,N)generates an M* Nlogicalmatrix of 0s.  
magic(M)generates an M* M“magic square.”This is a square array in which  
the sum along any row, column, or main diagonal, is the same. Magic  
squares are useful arrays for testing purposes because they are easy to  
generate and their numbers are integers.  
eye(M)generates anM* Midentity matrix.  
rand(M,N)generates an M* Nmatrix whose entries are uniformly distrib-  
uted random numbers in the interval [0, 1].  
randn(M,N)generates an M* Nmatrix whose numbers are normally distrib-  
uted (i.e., Gaussian) random numbers with mean 0 and variance 1.  
For example,  
>> A = 5*ones(3, 3)  
A =  
5
5
5
5
5
5
5
5
5
>> magic(3)  
ans =  
8
3
4
1
5
9
6
7
2
>> B = rand(2, 4)  
B =  
0
0
.2311  
.6068  
0.4860  
0.8913  
0.7621  
0.4565  
0.0185  
0.8214  
2.10 Introduction to M-Function Programming  
One of the most powerful features of MATLAB is the capability it provides  
users to program their own new functions.As you will learn shortly, MATLAB  
function programming is flexible and particularly easy to learn.  
2
.10.1 M-Files  
M-files in MATLAB (see Section 1.3) can be scripts that simply execute a  
series of MATLAB statements, or they can be functions that can accept argu-  
ments and can produce one or more outputs.The focus of this section in on M-  
2
.10  Introduction to M-Function Programming 45  
file functions. These functions extend the capabilities of both MATLAB and  
the Image Processing Toolbox to address specific, user-defined applications.  
M-files are created using a text editor and are stored with a name of the  
form filename.m, such as average.m and filter.m. The components of a  
function M-file are  
The function definition line  
The H1 line  
Help text  
The function body  
Comments  
The function definition line has the form  
function [outputs] = name(inputs)  
For example, a function to compute the sum and product (two different out-  
puts) of two images would have the form  
function [s, p] = sumprod(f, g)  
where fand gare the input images, sis the sum image, and pis the product im-  
age. The name sumprodis chosen arbitrarily (subject to the constraints at the  
end of this paragraph), but the word functionalways appears on the left, in  
the form shown. Note that the output arguments are enclosed by square brack-  
ets and the inputs are enclosed by parentheses. If the function has a single  
output argument, it is acceptable to list the argument without brackets. If the  
function has no output, only the word functionis used, without brackets or  
equal sign. Function names must begin with a letter, and the remaining char-  
acters can be any combination of letters, numbers, and underscores. No spaces  
are allowed. MATLAB recognizes function names up to 63 characters long.  
Additional characters are ignored.  
Functions can be called at the command prompt. For example,  
>> [s, p] = sumprod(f, g);  
or they can be used as elements of other functions, in which case they become  
subfunctions. As noted in the previous paragraph, if the output has a single  
argument, it is acceptable to write it without the brackets, as in  
>> y = sum(x);  
The H1 line is the first text line. It is a single comment line that follows the  
function definition line.There can be no blank lines or leading spaces between  
the H1 line and the function definition line. An example of an H1 line is  
It is customary to omit  
the space between %  
and the first word in the  
H1 line.  
%SUMPROD Computes the sum and product of two images.  
4
6
Chapter 2  Fundamentals  
The H1 line is the first text that appears when a user types  
help  
>> help function_name  
at the MATLAB prompt. Typing lookforkeyworddisplays all the H1 lines  
containing the string keyword.This line provides important summary informa-  
tion about the M-file, so it should be as descriptive as possible.  
lookfor  
Help text is a text block that follows the H1 line, without any blank lines  
in between the two. Help text is used to provide comments and on-screen  
help for the function. When a user types helpfunction_nameat the prompt,  
MATLAB displays all comment lines that appear between the function defini-  
tion line and the first noncomment (executable or blank) line.The help system  
ignores any comment lines that appear after the Help text block.  
The function body contains all the MATLAB code that performs computa-  
tions and assigns values to output arguments. Several examples of MATLAB  
code are given later in this chapter.  
All lines preceded by the symbol “% that are not the H1 line or Help text  
are considered function comment lines and are not considered part of the Help  
text block. It is permissible to append comments to the end of a line of code.  
M-files can be created and edited using any text editor and saved with the  
extension .m in a specified directory, typically in the MATLAB search path.  
Another way to create or edit an M-file is to use the edit function at the  
prompt. For example,  
edit  
>> edit sumprod  
opens for editing the file sumprod.mif the file exists in a directory that is in  
the MATLAB path or in the Current Directory. If the file cannot be found,  
MATLAB gives the user the option to create it.The MATLAB editor window  
has numerous pull-down menus for tasks such as saving, viewing, and debug-  
ging files. Because it performs some simple checks and uses color to differen-  
tiate between various elements of code, the MATLAB text editor is recom-  
mended as the tool of choice for writing and editing M-functions.  
2
.10.2 Operators  
MATLAB operators are grouped into three main categories:  
Arithmetic operators that perform numeric computations  
Relational operators that compare operands quantitatively  
Logical operators that perform the functions AND, OR, and NOT  
These are discussed in the remainder of this section.  
Arithmetic Operators  
MATLAB has two different types of arithmetic operations. Matrix arithmetic  
operations are defined by the rules of linear algebra. Array arithmetic opera-  
tions are carried out element by element and can be used with multidimen-  
sional arrays. The period (dot) character (.) distinguishes array operations  
.
dot  
notation  
2
.10  Introduction to M-Function Programming 47  
from matrix operations. For example, A*B indicates matrix multiplication in  
the traditional sense, whereas A.*Bindicates array multiplication, in the sense  
that the result is an array, the same size as Aand B, in which each element is the  
product of corresponding elements of Aand B. In other words, if C=A.*B, then  
C(I,J)=A(I,J)*B(I,J). Because matrix and array operations are the same  
for addition and subtraction, the character pairs .+and .–are not used.  
When writing an expression such as B=A, MATLAB makes a “note” that  
Bis equal to A, but does not actually copy the data into Bunless the contents  
of A change later in the program. This is an important point because using  
different variables to “store” the same information sometimes can enhance  
code clarity and readability. Thus, the fact that MATLAB does not duplicate  
information unless it is absolutely necessary is worth remembering when writ-  
ing MATLAB code.Table 2.5 lists the MATLAB arithmetic operators, where A  
and Bare matrices or arrays and aand bare scalars.All operands can be real or  
complex.The dot shown in the array operators is not necessary if the operands  
are scalars. Because images are 2-D arrays, which are equivalent to matrices,  
all the operators in the table are applicable to images.  
Throughout the book, we  
use the term array  
The difference between array and matrix operations is important. For oa bp le yr awt ii ot hn st hi ne t te er rc mh ai nn og le --  
example, consider the following:  
ogy operations between  
pairs of corresponding  
elements, and also  
elementwise operations.  
Tꢂblꢁ 2.5 Array and matrix arithmetic operators. Characters aand bare scalars.  
Operator  
Name  
Comments and Examples  
a+b, A+B, or a+A.  
+
Array and matrix addition  
Array and matrix subtraction a−b, A−B, A−a, or a−A.  
.
*
Array multiplication  
Matrix multiplication  
Cv=A.*B, C(I,J)=A(I,J)*B(I,J).  
*
A*B, standard matrix multiplication, or a*A, multiplication  
of a scalar times all elements of A.  
.
/
\
Array right division†  
Array left division†  
Matrix right division  
Matrix left division  
Array power  
C=A./B,C(I,J)=A(I,J)/B(I,J).  
.
C=A.\B,C(I,J)=B(I,J)/A(I,J).  
/
\
A/Bis the preferred way to compute A*inv(B).  
A\Bis the preferred way to compute inv(A)*B.  
If C=A.^B, then C(I,J)=A(I,J)^B(I,J).  
See helpfor a discussion of this operator.  
.
^
^
Matrix power  
.'  
Vector and matrix transpose A.', standard vector and matrix transpose.  
'
Vector and matrix complex  
conjugate transpose  
A', standard vector and matrix conjugate transpose. When A  
is real A.'=A'.  
+
:
Unary plus  
+Ais the same as 0+A.  
Unary minus  
Colon  
−Ais the same as 0−Aor −1*A.  
Discussed in Section 2.8.1.  
In division, if the denominator is 0, MATLAB reports the result as Inf(denoting infinity). If both the numerator and denomina-  
tor are 0, the result is reported as NaN(Not a Number).  
4
8
Chapter 2  Fundamentals  
a1 a2  
b1 b2  
b3 b4  
A=  
and B=  
a3 a4  
The array product of Aand Bgives the result  
a1b1 a2b2  
A.*B=  
a3b3 a4b4  
whereas the matrix product yields the familiar result:  
a1b1+a2b3 a1b2+a2b4  
A*B=  
a3b1+a4b3 a3b2+a4b4  
Most of the arithmetic, relational, and logical operations involving images are  
array operations.  
Example 2.6, to follow, uses functions maxand min.The former function has  
the syntax forms  
max  
min  
C = max(A)  
C = max(A, B)  
C = max(A, [ ], dim)  
[C, I] = max(...)  
The syntax forms shown  
for maxapply also to  
function min.  
In the first form, if A is a vector, max(A) returns its largest element; if A is  
a matrix, then max(A) treats the columns of A as vectors and returns a row  
vector containing the maximum element from each column. In the second  
form, max(A, B) returns an array the same size as A and B with the largest  
elements taken from Aor B. In the third form, max(A, [], dim) returns the  
largest elements along the dimension of Aspecified by scalar dim. For example,  
max(A,[],1)produces the maximum values along the first dimension (the  
rows) of A. Finally, [C,I]=max(...)also finds the indices of the maximum  
values of A, and returns them in output vector I. If there are duplicate maxi-  
mum values, the index of the first one found is returned. The dots indicate the  
syntax used on the right of any of the previous three forms. Function minhas  
the same syntax forms just described for max.  
EXAMPLE 2.6:  
Illustration of  
arithmetic  
operators and  
functions maxand  
min.  
 Suppose that we want to write an M-function, call it imblend, that forms  
a new image as an equally-weighted sum of two input images. The function  
should output the new image, as well as the maximum and minimum values of  
the new image. Using the MATLAB editor we write the desired function as  
follows:  
function [w, wmax, wmin] = imblend(f, g)  
%
%
%
%
%
%
IMBLEND Weighted sum of two images.  
[W, WMAX, WMIN] = IMBLEND(F, G) computes a weighted sum (W) of  
two input images, F and G. IMBLEND also computes the maximum  
(WMAX) and minimum (WMIN) values of W. F and G must be of  
the same size and numeric class. The output image is of the  
same class as the input images.  
2
.10  Introduction to M-Function Programming 49  
w1 = 0.5 * f;  
w2 = 0.5 * g;  
w = w1 + w2;  
wmax = max(w(:));  
wmin = min(w(:));  
Observe the use of single-colon indexing, as discussed in Section 2.8.1, to  
compute the minimum and maximum values. Suppose that f=[12;34]and  
g=[12;21]. Calling imblendwith these inputs results in the following out-  
put:  
>> [w, wmax, wmin] = imblend(f, g)  
w =  
1
2
.0000  
.5000  
2.0000  
2.5000  
wmax =  
2
wmin =  
1
.5000  
Note in the code for imblendthat the input images, fand g, were multiplied  
by the weights (0.5) first before being added together. Instead, we could have  
used the statement  
>> w = 0.5 * (f + g);  
However, this expression does not work well for integer classes because when  
MATLAB evaluates the subexpression (f + g), it saturates any values that  
overflow the range of the class of fand g. For example, consider the following  
scalars:  
>
>
>
> f = uint8(100);  
> g = uint8(200);  
> t = f + g  
t =  
255  
Instead of getting a sum of 300, the computed sum saturated to the maximum  
value for the uint8class. So, when we multiply the sum by 0.5, we get an incor-  
rect result:  
>> d = 0.5 * t  
d =  
128  
5
0
Chapter 2  Fundamentals  
Compare this with the result when we multiply by the weights first before add-  
ing:  
>> e1 = 0.5 * f  
e1 =  
5
1
0
>
> e2 = 0.5 * g  
e2 =  
00  
>> e = w1 + w2  
e =  
150  
A good alternative is to use the image arithmetic function imlincomb, which  
computes a weighted sum of images, for any set of weights and any number of  
images. The calling syntax for this function is  
imlincomb  
g = imlincomb(k1,f1,k2,f2,...)  
For example, using the previous scalar values,  
>> w = imlincomb(0.5, f, 0.5, g)  
w =  
150  
Typing helpimblendat the command prompt results in the following output:  
%
%
%
%
%
%
IMBLEND Weighted sum of two images.  
[W, WMAX, WMIN] = IMBLEND(F, G) computes a weighted sum (W) of  
two input images, F and G. IMBLEND also computes the maximum  
(WMAX) and minimum (WMIN) values of W. F and G must be of  
the same size and numeric class. The output image is of the  
same class as the input images.  
Relational Operators  
MATLAB’s relational operators are listed in Table 2.6. These are array opera-  
tors; that is, they compare corresponding pairs of elements in arrays of equal  
dimensions.  
EXAMPLE 2.7:  
Relational  
operators.  
 Although the key use of relational operators is in flow control (e.g., in if  
statements), which is discussed in Section 2.10.3, we illustrate briefly how these  
operators can be used directly on arrays. Consider the following:  
>> A = [1 2 3; 4 5 6; 7 8 9]