The information described below covers MATLAB commands and digital image concepts that we have not covered previously this semester. You will need to use the MATLAB help system extensively to research more details about the commands listed below. If you are confused about any of these topics after investigating the MATLAB Help command, please ask your instructor for additional help.
Each photo editor project will hopefully be unique. The information below is provided as generic help to all students. You are not required to use all of the commands listed below. Use only the ones appropriate for your photo editor implementation.
Digital Images (a short primer)
A digital image is a sampling of light intensities -- typically over a very short period of time . A camera's "shutter speed" determines the length of time light is allowed to hit the camera's photo sensors. The number of samples taken of the incoming light determines a digital image's resolution. If a camera contains 600 rows of sensors, where each row contains 800 individual sensors, then the camera has 600x800 = 480,000 sensors and the resulting image contains 480,000 picture elements (pixels).
If you sample light you get a set of intensity values. These intensity values can be used to create a "gray scale" (i.e., black and white) image. If you take light and pass it through special prisms, you can separate the light into its various wavelengths. By separating light into its red, green, and blue wavelengths, and sampling the intensities of each component, you can create "full color" images.
Most camera images are created using CCD (charged-coupled devices). A good description of CCD's can be found at http://www.ghg.net/akelly/ccdbasic.htm.
Image Data
MATLAB command |
Description |
imread() | Picture = imread(Filename, Format); Reads an image from a file into memory and returns it's pixel intensity values in an array. Valid file formats include 'bmp',
'cur',
'gif',
'hdf',
'ico',
'jpg' or
'jpeg',
'pbm',
'pcx',
'pgm',
'png', 'pnm',
'ppm',
'ras',
'tif' or
'tiff',
'xwd'
(Note: in some rare cases an image file might be unreadable because
it uses a non-standard encoding.) |
imwrite() | imwrite(Picture, Filename, Format); Creates an
image data file on your hard drive. The first argument is the
image data. The second argument must be a valid file name. The third
argument must be a valid
format type from the following options: 'bmp',
'cur',
'gif',
'hdf',
'ico',
'jpg' or
'jpeg',
'pbm',
'pcx',
'pgm',
'png', 'pnm',
'ppm',
'ras',
'tif' or
'tiff',
'xwd'. |
Note: Always use 'fully qualified file names' with the
imread() and
imwrite() commands.
Image Type | Double-Precision Data (double Array) |
8-Bit Data (uint8 Array) 16-Bit Data (uint16 Array) |
Indexed (colormap) | Image is stored as a two-dimensional (m-by-n) array of integers in the range [1, length(colormap)]; colormap is an m-by-3 array of floating-point values in the range [0, 1]. | Image is stored as a two-dimensional (m-by-n) array of integers in the range [0, 255] (uint8) or [0, 65535] (uint16); colormap is an m-by-3 array of floating-point values in the range [0, 1]. |
True color | (RGB)Image is stored as a three-dimensional (m-by-n-by-3) array of floating-point values in the range [0, 1]. | Image is stored as a three-dimensional (m-by-n-by-3) array of integers in the range [0, 255] (uint8) or [0, 65535] (uint16). |
If you use imread() to read a typical camera photograph, the image will be a 3D array of uint8 values. For your CS211 project, you do not need to make your code work for all 4 types of images -- just 3D arrays of uint8 values. If you developed your photo editor into a "full blown" commercial system, your code would need to work for all 4 image data types.
Displaying images
MATLAB displays images in axes GUI components. Note the following:
- When using the image() command, the image is always displayed in the current axes' rectangle. To set the current axes, use
axes(Specific_axes_handle)
- If the image dimensions (width and height) have a different ratio from the dimensions of the axes component, the image will be stretched to fill the entire axes rectangle. If you want to display your image without distortion, use a
set(Axes_handle, 'Position', [x y width height])
command to make the axes component have the same aspect ratio (width to height ratio) as the image.
- Image rows increase down the Y axis; Image columns increase left-to-right along the X axis.
You may (or may not) need to use color maps. (You will need color maps if you want to display only a single color component of an image, e.g., only the red intensity values.) Note that MATLAB only allows one active color map for each figure window. You can change the color map at any time, but you can only have one active color map.
User Interactions
To capture the pressing and releasing of mouse buttons and the movement of your mouse, you must set callback functions for your GUI figure window. It is best to do this in your *_OpeningFcn() function. The following commands register callback functions for mouse events. (Change the variable names appropriately for your program.)
set(handles.Main_figure_handle, 'WindowButtonDownFcn', {@Window_button_pressed, handles} ); set(handles.Main_figure_handle, 'WindowButtonMotionFcn', {@Window_button_motion, handles} ); set(handles.Main_figure_handle, 'WindowButtonUpFcn', {@Window_button_released, handles} );For each callback function that you set, you have to write a callback function to process the corresponding event. For example, given the commands above, you would implement the following function:
function Window_button_pressed(hObject, eventdata, handles) ...When a mouse event callback function is called, you can use appropriate get() function calls to get information about the event. Some possible useful information includes:
Location = get(Axes_handle, 'CurrentPoint');
Location = get(Figure_handle, 'CurrentPoint');
MouseButtonType = get(Figure_handle, 'SelectionType');
Key = get(Figure_handle, 'CurrentCharacter');Currently_selected_object = gco();
IMPORTANT: If you get the location of the cursor using the figure handle, you will get the cursor location relative to the entire window. If you get the cursor location using an axes handle, you get the cursor location relative to the axes.
Functionality Suggestions
Each photo editor implementation will be unique and include unique functionality. The following discussions may (or may not) apply to your implementation. Use the following information if you are implementing any of the functionality discussed below -- and ignore it otherwise.
Adjusting the "color" of an image requires that the image be represented in an appropriate "color model." All images in MATLAB are represented using the RGB (Red Green Blue) color model because this is the color model used by all display monitors. However, to manipulate the color values in an image in meaningful ways, it is often necessary to change an image's color values into a different "color model." One example is explained below. There are many other "color models" that are very useful for the manipulation of images.
The YIQ color model is used for broadcast television signals and JPG image compression encodings. The three color components are:
Y : stands for intensity -- basically gray-scale values (this is the only signal shown on black and white TV's)
I : is a color difference value (Red - Y)
Q : is a color difference value (Blue - Y)
It is straightforward to convert RGB images into YIQ images using the following transformation:
[Y I Q] = [ 0.299 0.587 0.114; ... * [R G B]'
0.701 -0.587 -0.114; ...
-0.299 -0.587 0.886]It is straightforward to convert YIQ images back into RGB images using the inverse transformation:
[R G B] = [1.0000 1.0000 0.0000, ... * [Y I Q]'
1.0000 -0.5094 -0.1942, ...
1.0000 0.0000 1.0000]
To edit an image using the YIQ color model, you would convert your RGB image into the YIQ color model, modify the YIQ values, and then convert the image back into RGB values for display. Note that the (Red Green Blue) color values are all unsigned 8 bit integers in the range [0, 255], while the YIQ values can be negative. Y varies from [0, 255], I varies from [-178.755, +178.755], and Q varies from [-225.93, +225.93].The "colors" of an image can be manipulated in many other ways, including using other "color models" or mathematical equations performed on the RGB values.
Changing the resolution of an image requires that you increase or decrease the number of pixels that represent the image. This requires two different algorithms, depending on whether you are increasing or decreasing the image resolution.
To increase an image's resolution, you need to calculate an appropriate pixel color for each new, higher resolution pixel value based on a percentage average of 4 pixel colors from the smaller resolution image. Use the following algorithm:
For each pixel in the larger resolution image:
Calculate its position in the original image using an appropriate scale and offset.
Use the floor() function to calculate the fractional portions of the location and to calculate the row and column values for the surrounding pixels.
Calculate the areas of the four "fractional" sub-regions surrounding the location.
Calculate the intensity of the magnified pixel using the four surrounding original pixels and the calculated areas.
An example helps explain this algorithm. Suppose the pixel at row 100, column 205 in the higher resolution image maps to the point (56.305, 102.61) in the original image. This location is surrounded by the pixels in rows 56 and 57 and columns 102 and 103. The color of the higher resolution pixel should be a blended average of the colors of these 4 surrounding lower resolution pixels. The areas defined by the fractional portions of the mapped location (i.e., (0.305, 0.61)) define the percentage of each surrounding pixel's color.
The percentage of influence of each original pixel intensity is determined by the area catty-corner from its location. If the variable name for the original image data is 'Original", the intensity of the higher resolution pixel at (100,205) is
Original(56,102) * A3 + Original(56,103) * A2 + Original(57,102) * A4 + Original(57,103) * A1
To calculate the location of a higher resolution pixel within the lower resolution image, use the following equations:
Col_scale_factor = Columns_in_low_res_image / Columns_in_high_res_image; Row_scale_factor = Rows_in_low_res_image / Rows_in_high_res_image;Row_fraction = (Row_in_high_res_image-1)*Row_scale_factor + 1; Column_fraction = (Col_in_high_res_image-1)*Col_scale_factor + 1;To decrease an image's resolution, to any arbitrary value requires that each pixel in the lower resolution image be a weighted sum of one or more pixels in the higher resolution image. Use the following algorithm:
For each pixel in the lower resolution image:
Calculate the exact area this pixel "covers" in the higher resolution image.
Calculate the exact sub-regions of this coverage area that surround each pixel and divide this area by the total "coverage" area. This is the percentage of color this pixel adds to the weighted sum.
Assign the lower resolution image pixel this weighted sum color.