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

  1. You must submit your work on Blackboard as you go (after completing each step) -- not just the final product.
  2. You must write and use multiple appropriate functions for each step, where those functions do the bulk of the work.
  3. In particular, you should define and use at least one new function for every step below.
  4. You should also re-use functions where appropriate. If you have already written the code to do something useful, use that code (as a function) where possible instead of repeating the same code.
  5. Your program must use a one-dimensional array to store the data. (Later we will learn about two-dimensional arrays, but don’t use those for this project.)
  6. For full credit, you must fully process the contents of the array as appropriate (e.g., if there are 100 pixels, you must process all 100, not 99!), and not access any invalid array indices (e.g., going beyond the end of the array).
  7. You will need to pass some variables by reference. Pass only those variables by reference. If a variable does not need to be passed by reference, it must be passed by value.
  8. Style/comments are important and will form a portion of your grade.
  9. If you know what a “global” variable is – don’t use them!  If you don’t, ignore this comment.
  10. A “segmentation fault” error means that you tried to make some invalid memory access – normally trying to access an array that doesn’t exist, or an invalid index of an array.

 

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):

part1.png

 

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!