IC 210 FALL 2012
Programming Project 2
Image Processing
Executive Summary
You will create a program that will perform some basic image processing, including drawing on an image, finding one image inside another, and flipping an image.
Due Dates and Honor
·
Friday October 19 2012 – at start of
class: a mandatory
interim milestone is due. This milestone consists of completing steps 1 and 2.
Meeting this milestone is worth 10 points of your project grade. If you miss
this deadline, you can still get 6 pts if submitted by start of class Mon Oct
22, 2012, or 4 pts if submitted by 0800 Tuesday Oct 23. Here is what to submit:
o
Blackboard:
under “Step 2”, submit (a) project2.cpp and (b) the file f14-2.pgm that you
produce by running the sample output shown with step 2.
o
Hardcopy:
Turn in printout of project2.cpp.
Style/comments are encouraged but not graded at this point.
· Final submission due by the “close of business” on Wednesday October 24, 2012 (yes, that means if necessary you have until first thing the following day, Thursday).
Again, this is a Programming Project, and it is very
important that you understand and abide by the Department's policy concerning
programming projects. Please view:
http://www.usna.edu/CS/resources/ProgrammingPolicy.pdf
Important Notes Up Front
Details
The project is divided up into several functions, worth varying
number of points, not strictly based on difficulty. We suggest doing the
steps in order, but if you get stuck you may skip a step if that step is not
needed for continuing.
All of your program’s functionality will be implemented via
function calls, with your main() function serving
primarily as a central hub with some sort of selection structure calling the
functions that implement the required functionality (thus, your main() function
should be relatively short!). The user should be able to continue selecting
options until he chooses to quit.
Five sample input files are provided for you (download
images.zip from the course website):
1.
f14.pgm
– a fighter jet.
2.
frag.pgm
– a small fragment of f14.pgm (used for the “find” option later)
3.
beirut.pgm
– an image of a crowd
4.
bf.pgm
– a small fragment of Beirut.pgm (used for the “find” option later)
5.
smiley.pgm
– a tiny image of a smiley face. Very
useful for debugging!
After downloading, type this in a Terminal to unpack the
files: unzip images.zip
These files are all Portable Gray Map
files (with a .pgm extension). Each .pgm starts with a magic number: "P2". The
next line gives the number of columns and then rows in the image. The next line
gives the range of intensity of the pixels. If the number is 100, then pixels
can be between 0 and 100, where 0 is black and 100 is
white. Commonly that number is 255. (NOTE: For this project, you are free to
assume that this maximum will always be 255). The remaining lines give the
individual pixel values, row by row. The pixel at row 0 and col
0 will be the top left corner of the image.
PGM files are stored in plain
ASCII format – so you can look at them with any text editor (such as gedit). As an example, here is the
contents of the provided smiley.pgm file:

In this file you can see the header (3
lines), then 10 rows that each contains 8 pixel values. Note that in the second
line of the header, the number of COLUMNS is given first, not the number of
rows! (this is
perhaps the opposite of what you might expect).
More examples can be found at the wikipedia
page.
TIP: Below,
sample screenshots are given with the f14.pgm file. To debug your program, it
is highly recommended that you also try using the smiley.pgm file – this is
small enough that you can examine the contents of this file (and the new file
after you save it) with a text editor – do the results match what you expect?
Step 1:
(15 pts.) Load and Save.
Write a
program that does this:
1. Note: in the steps below, you must create (and use) a
function to do the primary work of reading a file, and also a function to do
the primary work of writing a file.
2. Output a welcome greeting that includes your name and
alpha.
3. Prompt the user for the name of a .pgm file.
4. Open the file and read the header. If the first line of the header is not
correct for a .pgm file, print an error message and
exit.
5. Print out the dimensions of the image (rows, then
columns)
6. Read all of the data pixels into an array. How big does your array need to be?
7. Prompt the user for a second filename.
8. Write the image (header and data) to the new file.
IMPORTANT: in the output file, add a “newline” after the end of each row of
data – this will make debugging much easier.
9. Use the “eog” program and a
text editor to verify that the new file is correct.
10. Here is a sample run where user enters “f14.pgm”, then
“f14-2.pgm”. Make yours look just like
this (except yours will also have your name and alpha):

TIP: you will need to keep track of the number of rows and columns for
your image. In particular, your function that loads an image will need to
somehow provide this information back to main(), in
addition to the array that holds the data values.
Step 2: (5
pts. basic + 10 pts for submission for milestone) Add Menu
·
Add
a menu for the user to select an option of loading or saving a file, or
quitting the program. It should quit with input q.
·
If a
non-existent option is given, you should ask again.
·
You may assume that the user always successfully
opens a file before they try to do anything else (though error handling would
be a nice touch here).
·
Whatever the user picks, you should then call the
functions that you have already written to do the job of loading or saving a
file.
·
Test with “eog” that your
output file has been saved correctly.
·
Be sure to follow the given input format
exactly! (Lowercase L for load,
lowercase S for save, etc.).
·
Sample is below. Note: filenames to type are
f14.pgm and f14-2.pgm (all lowercase).

Step 3:
(30 pts.) Draw Pixel and Display.
1. Create a function called twoD2one() that converts a row and column pair
(the 2D representation) to the appropriate index for that pixel in your (one
dimensional) array. It should be useable as in the following example (where (row,col) are the coordinates of a pixel, and cols is the
number of columns in the image):
int i = twoD2one(row,col,cols); // compute index for (row,col)
image[i]=255; // set that cell to a white value
TIP: To figure out the right index
you need to know the number of columns in the image (e.g., the number of pixels
per row). Suppose there are 10
columns. Then here are some samples:
row=0, col=0 --> index is 0
row=0, col=3 --> index is 3
row=1, col=0 --> index is 10
row=1, col=4 --> index is 14
row=2, col=4 --> index is 24
2. Add a menu item that allows the user to
set the value of a pixel using your twoD2one function (see example below) .
3. Add a menu item that displays the image
directly. This can be done by (a) writing the image to a temp file (tmp.pgm)
and then (b) calling the eog image viewer directly
from your program, which you can do with this code:
#include <cstdlib>... string oname = "/usr/bin/eog tmp.pgm"; system(oname.c_str());
4. LAST REMINDER: For every step of this project, be sure to
define and use appropriate functions to do the primary work! Your main() function
should be fairly small, and mostly just call other functions to do the real
work.
5. Make your program work like the following example:
TIP: Don’t forget to save the temporary file before you invoke “eog”!
TIP: After using the display (d) option, your program will be frozen. Close the “eog”
image viewer program in order to continue.
Step 4:
(20 pts.) Drawing Lines
·
Add an option to draw
horizontal or vertical lines. The user should input:
a. the start location
b. the direction (h for horizontal, v for
vertical)
c. the length of the line, and
d. the intensity
·
Example: Starting
from (row 10, col 20), a horizontal line of length 50
should extend to (row 10, col 69).
Note: you may assume
that the user will only enter “good” values, so that the line stays inside the image.

Step 5:
(12 pts.) Flip the image.
·
Add a menu option (h) that
flips the image across the horizontal axis.
(The menu below also shows a (v) option to flip on the vertical axis, but this
is not required).
TIP: There are
many options, but the easiest solutions all involve creating and using a second
array to perform the flip.

Step 6: (8
pts.) Find an image within an image
·
This function should:

TIP: Wouldn’t this be much easier to
do if you had a function that could check for a match given a particular
starting (row,col) in the
larger image?
TIP: When finished, load
beirut.pgm, then try to find bf.pgm. The box
may be hard to spot, but use the coordinates written by your program to help
find the right area.
Step 7
(Extra Credit – max 5 pts.) Blur the Image.
·
Blurring
of an image is performed by averaging the values of pixel intensities. If there
is a pixel at location (R,C), then its blurred value
is: ((R-1,C) + (R+1,C) + (R,C-1) + (R,C+1) + (R,C))/5. Add an option to blur
the image using this averaging technique.
·
You
will have to think carefully about what to do at boundary cases (the edge of
the image).
·
When
computing the new value of a pixel, make sure that you are averaging the original
values of that pixels’ neighbors (not values that have
already been changed by blurring).

Step 8
(Extra Credit – max 5 pts.) rotate the image.
·
Add a menu option that
rotates the image 90 degrees clockwise.

Friendly
Reminder:
·
You MUST submit a working solution
for EACH of the above steps as you complete them. Submit just the
.cpp file (except for step 2 – see the milestone instructions
on page 1). It’s okay if you make some changes to a step after you submit it,
but we want to see the progression of your steps. The individual steps will not
be graded for style or functionality – as long as it looks reasonably like you
submitted the steps, what counts will be the style and functionality of the
final result (submit on Blackboard as such)
Important
grading points:
·
The default method of passing variables is pass
by value. You may only use pass
by reference when necessary.
·
Appropriate use of functions to implement this
program is critical to receiving the maximum possible score.
·
If your program does not compile as
submitted, you will
receive a zero.
·
Your program must read input and write
output in the exact format specified in this project description.
·
Your program’s source code must comply with
the Required Style Guide in order to maximize the grade you receive on this
project.
·
Your grade will also depend on the
reasonable use of C++ code. Don’t use 50 lines of code where 5 would do.
There will be
both a paper and an electronic part to your submissions. The paper submission
can be handed to your instructor or slid under their office door (but do not
put your project in their mailbox). For the purposes of any late penalties,
your project is not considered submitted until your instructor receives BOTH
the electronic and paper portions of your submission. Any disagreement
between your paper and electronic submissions will result in a grade reduction.
Electronic
submission:
Unless
otherwise specified by your instructor, your electronic submission should be
made via Blackboard. As you complete each step you should submit your
project2.cpp file. Submitting steps out of order is completely acceptable! Simply
note the out of order submission in the comments at the top of your code with
your name. i.e., “Submitting Step 6, step 5 has not yet been completed”.
When completely
finished, submit your project2.cpp file under the “Final submission” link on
Blackboard.
If you desire
to submit a revised solution to any completed step notify your instructor via
email so they can clear your previous submission. However, unless changes are
dramatic this is not required for intermediate steps (see “Friendly Reminder”
above) – the final submission is what is graded.
Paper
submission:
Staple in this order:
a. Cover sheet, with signed honor statement
NOTE: At top right of cover sheet, circle the number for EACH step that works.
b. Printout of your code. Make sure the
indentation shows correctly on the printout!
c. Printout of a single screenshot that
best shows off the abilities of your program. Make this screenshot look like the
examples shown above (use Ctrl-PrntScreen to capture
both your terminal AND the eog program displaying the
final image). To show off what you can
do, do this:
a. If all required steps work,
then load beirut.pgm, find bf.pgm in it, then flip the image, then
display it.
b. If find doesn’t work, load f14.pgm, flip
it, and display it.
c. If flip doesn’t work, then load f14.pgm, draw some lines
on it, then display it.
d. If none of these directly apply to you, show some
different sequence that best shows off what you can do. It’s okay if one run of
your program doesn’t show everything.
FINAL
TIPS:
·
Follow the Style Guide as
you go! It’s easier to indent and comment as you write than at the end, and you’ll
make it easier on yourself to write your program. And you’ll maximize your
grade by following the guidelines.
·
Compile often so you don’t
end up with a snake’s nest of errors all at once
·
Save backups of
project2.cpp in case your sponsor’s dog eats your X drive.
·
Start early! Allow time for you to get new ideas and
to see the instructor for help.
·
Remember that this project
is not to be discussed with anyone besides your instructor! Don’t defeat your
learning AND jeopardize the honor of yourself or your friends by talking to
them about it.
·
Remember you may not use
any online sources except the course website!