The goals of this lab include doing the specific tasks outlined below
and understanding general concepts behind the tasks.
In this lab, you'll investigate some very basic techniques used in image
processing. You will be enhnacing a program that manipulates bitmap
pictures. Some of this material is described in Sections 9.2-9.4
and 11.5 of Astrachan/Tapestry. The lab uses matrices to
store bitmaps (pictures).
Lab 4 table of contents
For this lab you'll first write the member function to read image files
from disk, then you'll write some function to manipulate images.
Finally, you'll modify the Pixmap class to make it more memory
efficient.
Bit Map Background
Many different forms of graphical images exist. Common forms include
gif ,
tiff , and X-window dumps . In this assignment a
form of image called a bitmap will be used. These bitmaps can be
black-and-white, gray-scale, and color. This assignment uses only
black-and-white and gray-scale images.
Pixels
An image can be represented as a 2-dimensional grid of
pixels, each of which can be off (white) or on (black).
Color and gray-scale images can be represented using multi-valued
pixels. For example, numbers from 0 to 255 can represent different
shades of gray.
A bitmap is a 2-D grid of 0's and 1's, where a 0
corresponds to an off pixel and a 1 corresponds to an on pixel. For
example, the following is a bitmap which represents a 9x8 picture of
a `<' sign. The bitmap of 0's and 1's is shown on the left, the image
the usepix will display is on the right.
0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 |
![]() |
Representing images as bitmaps is very natural, and some reasonably nice tools for drawing and displaying bitmaps can be found in the UNIX environment. In this lab we will use xv to display our images. Although representing such images using the '0' and '1' characters (or the numbers 0 and 1) may be wasteful of space (a character is 8-bits and as a '0' or '1' represents only 1-bit of information), it is conceptually simple and methods for compressing such images exist.
In this section of the lab you'll copy files, compile a basic image processing program, and manipulate a "random" image.
First change into your cps100e subdirectory (type pwd
to verify where you are). Create a
lab4 subdirectory by typing mkdir lab4 and change
into this subdirectory (be sure to check that you're
in the lab4 subdirectory.) Now copy the files for the lab
(don't forget the . when copying).
You should see the files listed below (these are links to the files in case you use Netscape, and for users outside of Duke).
Be sure you're in the lab4 subdirectory, and check to see that all files are there (type ls). Then, from an xterm window (at the prompt [1] ola@teer8% or similar) compile the first version of the program by typing: make usepix. This should compile several files and link them together with the library libtapestry.a. Now run the program by typing: usepix at the prompt. When you run the program, you can "load" a file, but the read routine is not complete. Use the 'l' (for load) option then type the number of an image. To display an image choose the 'd' option. Your program will display a random image that is the same size as the image in the file because the Read member functions are not implemented.
In this part of the lab you'll implement changes to The Pixmap class (in pixmap.cc). You will implement member functions ReadNormalFile, ReadCompressedFile, Invert, and HorizReflect functions.
image type (C1, P1, P2) # comment string cols rows optional gray levels pixel value pixel value ... pixel value pixel value ...The pixels are stored row by row (this is called row-major order). For example, the < sign shown above is stored in a file as shown below (you can read this file in when you run the program!)
P1
# CREATOR: XV Version 3.00 11/29/94
8 9
0 0 0 0 0 1 1 0
0 0 0 0 1 1 0 0
0 0 0 1 1 0 0 0
0 0 1 1 0 0 0 0
0 1 1 0 0 0 0 0
0 0 1 1 0 0 0 0
0 0 0 1 1 0 0 0
0 0 0 0 1 1 0 0
0 0 0 0 0 1 1 0
You need to write the function to read the pixel values. First you'll
write ReadNormalFile.
The body of the inner loop should read a value from the file (use >>, the extraction operator) and store the value in myImage
When you can read and display .pgm and .pbm files you should try the Vertical Reflect option and re-display. You'll notice a change. You'll next implement Invert and Horizontal Reflect.
Include this statement in the body of two nested loops that run j and k appropriately through all rows and columns. Check you invert function by reading in an image (try one of the owen or idiot images), inverting it, and displaying it.
You should look at the VertReflect member function which reflects left-to-right (through a vertical line). for help in how to reflect a pixmap. Note that in VertReflect the left-half columns are swapped with the right-half columns inside a loop that visits every row.
However, you will want to reflect the pixmap horizontally rather than vertically.
When you're done, check your function by reflecting and displaying an image.
For this part of the lab you'll add code to read compressed images. Only black and white images are compressed. Images are compressed by storing a count of consecutive 0's and 1's rather than the 0's and 1's themselves. For example, rather than storing
0 0 0 0 0 1 1 1 1 0 0 1 1 1 1 1 1we can store the counts of consecutive 0's and 1's:
5 4 2 6
As a further example, the < image above is compressed as follows (note that the # of rows and columns is the same as in the uncompressed image.)
C1 # CREATOR: CPS06 Pixmap 9/25/95 8 9 5 2 5 2 5 2 5 2 5 2 7 2 7 2 7 2 7 2 1
To read a compressed image you'll fill in the code for the member function ReadCompressedFile. You need to read each number (e.g., 5 2 5 2 ...) in the < image above and store the right number of 0's and 1's based on these numbers. Rather than using nested for loops you should use the loop pattern below. This loop reads each number, then uses a for loop to set the correct numbers of 0's and 1's. By convention the first number in a file is always some number of consecutive zeros (there might be zero 0's).
In the current implementation of the Pixmap class, the Matrix myImage is resized every time a new image is read in. Sometimes this wastes memory since there is no need to resize the Matrix if it is already large enough to store the image being read. We will modify the class to avoid resizing always by keeping track separately of the capacity of the Matrix myImage and the size of the image stored in the Matrix.
Load (use the file menu or C-x C-f) the file pixmap.h.
Type M-x query-replace, that's Escape-x, followed (in the minibuffer) by "query-replace". You can hit the TAB key after "repl" and the command will be completed (partially). If you hit TAB again, the choices will appear and you can type "st" TAB to complete the command, then hit return.
You probably won't notice any change in the performance of your program, but you should be sure to recompile and re-run it.
submit100e lab4.N README pixmap.cc pixmap.h
You can enter the files in any order (you don't need to submit usepix.cc because it didn't change, (but you can submit it.)
Remember that every assignment must have a README file submitted with it (please use all capital letters). Include your name, the date, and an estimate of how long you worked on the assignment in the README file. You must also include a list of names of all those people with whom you collaborated on the assignment.
You also must turn in the inlab questions either by turning in the sheet during lab or by submitting the answers with your README.
First the Matrix myImage is resized, then starting in the lower-right corner, and working back to the upper-left corner, each pixel is expanded by rowExp X colExp. This most likely will involve a quadruply nested loops. The outer loops visit every pixel in the original image. The inner two loops copy the pixel into an enlarged area of the Matrix. It's possible to do this with two loops, but that's tricky too.
submit100e lab4.N.xtra README pixmap.cc pixmap.h