Suppose that you had a camera set up on a tripod and you were trying to photograph a certain scene. However, every time you took the picture someone or something entered the scene and "ruined" the shot for you! For example, consider the 9 images presented below (downloadable off the class Canvas pages) where attempts are being made to photograph the sculpture in the middle of the frame.
Figure: see image.
If you look closely, you can see that the most of sculpture is visible in each image. The man walking only blocked part of the sculpture, and since he was in a different position in each photo, he usually blocked a different part of the sculpture each time. Might there be a way to combine all of these photos in such as to "remove" the man from the overall photo?
It turns out that there is using a technique called a median filter. This is a method for removing noise - or a man in this case from a set of similar images.
In the median filter we compare individual pixels from each image. We start out by making the assumption that most of the pixels in each image at a specific coordinate (x, y) are same color or very close in value. These are the colors we want. Sometimes, at a particular pixel in a particular image, that pixel will be part of the tourist and that pixel will have a very different color from the other pixels at the same coordinate in the other images. These different colored values are the noise we are looking for and trying to remove.
In order to pick the correct color for the pixel at each (x, y) coordinate, we can read the color value for that particular coordinate in all the images at the same time, placing them into an array. We can then sort those values, and pick the middle value, i.e. the median value for that list of numbers. Once we know that median value we write it out to our filtered image file. If most of the pixels are the same we will in effect filter out the 'noise'.
We will use the PPM image format for our images in this project (see below). In this format each pixel will consist of three values - a value for red, green, and blue. So for each pixel we will need to find three median values in order to find the pixel color values for our final image. If we do the above process for each pixel (i.e. we do it for the red, green, and blue value in each pixel), then the final result will create a good photo without that pesky man.
You are to write a C program that inputs several images, applies the median filter to these images, and then writes a resultant image file to the disk with the 'noise' removed. You have been given 9 PPM files on the class web site. You of course may use your own, and any number. The images are or should be all the same height and width.
Once you at ready to process the images, you will access all the values for the red, green, and blue values for a single pixel from the files, one integer at a time. The first value in the first file, the first value in the second file, the first value in the third file, and so on up to the first value in the last file. Calculate the median, and write this median value to the result image. Continue on doing this for the red, green, and blue values for every pixel triplet in the file. Your result image should be noise (person) free!
The input file prefix should be entered on the command line along with the number of images you wish to process (see the sample run). For example if your input file prefix is image your input files should be named image001.ppm, image002.ppm, . . . , image009.ppm and your filtered output file should be named image.ppm . Example files are provided for you on the class web pages. You should divide your program into a series of function calls from main, each function performing, more or less, a single task (e.g. input, output, compute some value(s), etc). As a rough estimate your main function should be 30 lines or less of executable code (i.e. not counting declarations). In addition you may not use any global variables (other than preprocessor definitions as needed); all data that must be shared by various functions should be declared in main and then passed to the functions as needed.
The portable pixmap format (PPM) is a method for storing images as regular ASCII text files. PPM files contain some image information followed by each pixel of the image represented as a triplet (for red, green and blue (RGB)) of integers each in the range of 0-255. Each file consists of the following in this order:
1. The letter P followed immediately by a "magic number" indicating the type of PPM file. We will only use files of type P3.
2. The width and height of the image
3. The maximum color value in the image; this will always be 255 in our data files
4. All the RGB pixel data follows as (width x height) number of triplets (i.e. one RGB triplet defines one pixel)
Note that all numbers are integers, and that all values are separated by white space. Pixel data is stored in the file in row-major form.
Here is a partial example:
P3 <- "magic number"
200 200 <- width, height of image
255 <- maximum color value
18 18 122 <- (width x height) # of RGB triplets
22 0 0
0 255 255
45 90 200
.
.
.
Note that a PPM file is valid if the "magic number"is P3, the width and height are greater than 0, 0 <= maxColor <= 255, and the image contains width x height number of pixels.
A PPM file viewer (as an HTML file) is provided on the class web pages. Note however that many if not most modern browsers will display PPM images directly.
Here is a sample run using the images shown above. You must output all of this information but you need not format it exactly as shown here.
Figure: see image.
Resultant image: see image.