Lab (3) - Image Processing

Image Types in Matlab
Reading/Writing Images
Image Conversion
Image Coordinate



Image Types in Matlab

The image processing Toolbox supports four basic types of images:

Indexed Image:

An index image consists of two arrays:    1) to represent the image matrix (x,y) location, and 2) the colormap representing the pixels.
The colormap is an m-by-3 matrix of type (class) double. Each row of the colormap matrix specifies the red, green, and blue (RGB) values for a single color. color = [R G B], thus, the R, G, and B are real scalars that range from 0 (black) to 1.0 (highest possible intensity).

The image matrix for this type of image can be represented as class double or unit8.  Unit8 takes 1/8 of the space that the double requires.  If an image is in class double, the value 1 points to the 1st row in the colormap, value 2 to the 2nd row, and so on.  In an image in unit8, there is an offset and the value corresponding to row one is actually 0, and so on.

Intensity Image:

The intensity image is represented as a single matrix.   Each element of this matrix correspond to one pixel of the image. The intensity values can be in class double, in which case it contains values in the range [0,1], or in class unit8, in which case it contains data in [0, 255] range.  This range can represent the gray level where 0 represents black and 255 represents white.

Binary Image:

An binary image is represented with two discrete values, one to represent black (0) and the other for white (1).  A binary image is an intensity image with two levels.  This type of image can be represented as an array of class double or unit8.  However, to save memory, unit8 is the preferable format.

In MATLAB's Image Processing Toolbox,  any function that returns a binary image returns it as a unit8 logical array.  The toolbox uses the presence of the logical flag to determine the data range.  If the logical flag is on, then the range is [0,1] and if it is turned off the range will be [0,255].

RGB Image:

In this image like an indexed image, each pixel color is represented as a set of three values.  These three values represent the red, green, and blue colors respectively.  The difference between an RGB and an index image is that the pixel values are stored directly in the image array.  No need for colormap.

The matrix representing an mxn image is actually an mxnx3 array.  Thus, at each pixel location we will have three values.

Reading/Writing an Image:

imread
MATLAB can read images in the following file formats: BMP, HDF, JPEG, PCX, TIFF, XWD
This table summarizes the types of images that imread can read.

BMP  :       1-bit, 4-bit, 8-bit, and 24-bit uncompressed images; 4-bit and 8-bit run-length encoded (RLE) images
HDF  :        8-bit raster image datasets, with or without associated colormap; 24-bit raster image datasets
JPEG :       Any baseline JPEG image (8 or 24-bit); JPEG images with some commonly used extensions
PCX  :        1-bit, 8-bit, and 24-bit images
PNG :         Any PNG image, including 1-bit, 2-bit, 4-bit, 8-bit, and 16-bit grayscale images; 8-bit and 16-bit
                   indexed images; 24-bit and 48-bit  RGB images
TIFF :        Any baseline TIFF image, including 1-bit, 8-bit, and 24-bit uncompressed images; 1-bit, 8-bit, 16-bit,
                   and 24-bit images with packbits compression, 1-bit images with CCITT compression; also
                   16-bit grayscale, 16-bit indexed, and 48-bit RGB images.
XWD:        1-bit and 8-bit ZPixmaps; XYBitmaps; 1-bit XYPixmaps

imread
A = imread(filename,fmt) reads a grayscale or truecolor image named filename into A. If the file contains a grayscale intensity image, A is a two-dimensional array. If the file contains a truecolor (RGB) image, A is a three-dimensional (m-by-n-by-3) array.

[X,map] = imread(filename,fmt) reads the indexed image in filename into X and its associated colormap into map. The colormap values are rescaled to the range [0,1]. A and map are two-dimensional arrays.

[...] = imread(filename) attempts to infer the format of the file from its content. imfinfo
 

In order to read the image that we have previously used, sl00.pgm, we need to convert that image to a format that MATLAB can understand.  Use the xv software to read that image and then save it as sl00.jpg.

Type:
>> [X,map] = imread('sl00.jpg');

This reads the image and save the pixel intensities in array x and the colormap in map.  You can type, X to see how the array looks like.

Notice that by reading this image we do not display it. We only save the image in the array X.  To display the image, you will use another command:  imshow.

>> imshow(X);

This displays the following window on the screen:

At the top of this screen you will see some tabs.  The first one is the File tab.  This tab provides the functionality listed on the following figure:

One has to go through all these options to discover their functionality.  The Export option is very useful and allows users to covert an image to many different formats, including some to some formats that MATLAB is unable to read.

imwrite

Write an image to a graphics file

Syntax

     imwrite(A,filename,fmt)
     imwrite(X,map,filename,fmt)
     imwrite(...,filename)
     imwrite(...,Param1,Val1,Param2,Val2...)

Description:

imwrite(A,filename,fmt) writes the image in A to filename. A can be either a grayscale image (M-by-N) or a truecolor image (M-by-N-by-3). If A is of class uint8 or uint16, imwrite writes the actual values in the array to the file. If A is of class double, imwrite rescales the values in the array before writing, using uint8(round(255*A)). This operation converts the floating-point numbers in the range [0,1] to 8-bit integers in the range [0,255].

imwrite(X,map,filename,fmt) writes the indexed image in X and its associated colormap map to filename. If X is of class uint8 or uint16, imwrite writes the actual values in the array to the file. If X is of class double, imwrite offsets the values in the array before writing using uint8(X-1). (See note below for an exception.) map must be a valid MATLAB colormap of class double; imwrite rescales the values in map using uint8(round(255*map)). Note that most image file formats do not support colormaps with more than 256 entries.

imwrite

Will return information about the image data in a file.

Example:
» imfinfo('sl00.jpg')

ans =

        Filename: 'sl00.jpg'
        FileModDate: '30-Jan-2001 23:07:52'
        FileSize: 10653
             Format: 'jpg'
      FormatVersion: ''
              Width: 256
             Height: 256
           BitDepth: 8
          ColorType: 'grayscale'
    FormatSignature: ''

To learn more about any of the above commands, type help followed by the command name.  There are several fucntions that are designed to covert one image format to another.

dither
Convert an image, increasing apparent color resolution by dithering

Syntax

     X = dither(RGB,map)
     BW = dither(I)

Description
X = dither(RGB,map) creates an indexed image approximation of the RGB image in the array RGB by dithering the colors in colormap map. It also can create a binary image from a grayscale intensity image by dithering.

There are more functions for conversions; gray2ind, gradslice, im2bw, ind2gray, ind2rgb, mat2gray, rgb2gray, rgb2indUse the help command to finf out what each one these function does.

Image Conversion

The following commands convert unit8 images to images in double
Indexed B=double(A)+1;
Intensity or RGB B=double(A)/256;
Binary B=double(A);

The following commands convert double images to images in unit8
Indexed B=unit8(round(A-1));
Intensity or RGB B=unit8(round(A*255));
Binary B=logical(unit8(round(A)));

Can you explain why we used round?

Note: When you convert a binary image of type double to unit8, the flag is not turned on automatically.  You can use the logical function to create an array with the logical flag on:

B = logical(unit8(round(A)));

To turn the flag off use:  B = +A.

Image Coordinate

There are basically two major coordinates one can use; 1) pixel coordinate, and 2) spatial coordinate.

1) Pixel Coordinate:  In this coordinate system every pixel is represented with 2 numbers (x,y).  The first number, x, represents the location of that pixel with respect to the first pixel on the same row and the second one, y, represent the location with respect to the first pixel on the same column.  Thus, pixel at (2,3) location is located on the 3rd row and 4th column.  Of course everything is integer.

2) Spatial Coordinate: This system is basically what we use in geometry to represent a point in the 2-D space.  A point can be represented with its exact location with respect to the reference point.  In this system we may have locations that are defined as real values.  Example: A point at (2.5, 3), is located at x = 2.5 and y = 3 location on the 2-D space.

Displaying an image

We have already tried the imshow command.  There is a very important note to take when we use this command.  The imshow command will display the image at its default axis size.  Thus, it must use interpolation to to determine the values for pixels that do not correspond to the element on the image matrix.  We can fix this problem by using another command, truesize.

The truesize command will assign a pixel screen pixel to each pixels on the original image.  There are times that the image is very small and you may not want to display it using the truesize command.  In such a case, you command, you use the notruesize.  Example:  imshow(X, map, 'notruesize').

>> imshow(X);
>> imshow(X, map);
>> imshow(X, map,'notruesize');

Displaying indexed images:
We used:
>> imshow(X, map);
to display the 'sl00.jpg' image.  We have already displayed this image without using 'map'.  Did you see a difference when you used 'map'.

Displaying intensity images:
To display an intensity image, we will use imshow(I).  Let's create an intensity image of sl00.jpg. How?
>> I = imread('sl00.jpg');
>> imshow(I);

We can represent the sl00 image with fewer gray levels than what the original image has.  You have already printed the information regarding the sl00 image using: imfinfo('sl00.jpg').  That image is a gray scale image with 256 levels [0, 255].  Here is how you can display the image with different gray levels:

>> imshow(I, 128);  Display the same image with 128 gray levels. This is the same for the rest.
>> imshow(I, 64);
>> imshow(I, 32);
>> imshow(I, 16);
>> imshow(I, 8);
>> imshow(I, 4);
>> imshow(I, 2);

Is this the same as what we did in Lab (2) when we reduced the gray levels?

Displaying Binary images:
We can use imread to read binary images and use imshow to display them:.
>> BW = imread('sl00.jpg');

You need to make that the logical flag is properly set. We have discussed this in the previous parts of this lab.