Project 1: Green Screen (Due 2359, 2/15)

Almost certainly, you're familiar with green screening, where a plain green background is replaced with some other image. The most common example is weather maps on the news - you'll never see a weather person wearing green clothes, or they would disappear.

In this project, we're going to do some green screening, combining a background from one picture with a foreground from another. For example, consider this picture of Bill the Goat.

He deserves to be someplace nice. So, every pixel that is green, we'll replace it with the corresponding pixel from this image:

Giving us this:

To do this, we're going to use a horribly space-inefficient file format called "plain PPM." Here is a bunch of ppm images for download. Untar the images with the command tar xzf ppms.tgz. If you open one up in a text editor, you'll see something that looks like this:

P3
1280 960
255
0 255 0 125 255 5 0 255 0...

The P3 is the "magic number" or file header, that tells the computer what the format is (remember this from SI110?). 1280 is the width of the image, in pixels, 960 is the height of the image in pixels, and 255 is the largest possible value of all the trailing numbers. The remainder describe the red, green, and blue values of each pixel in turn. The first three numbers after the max value are 0 255 0, meaning no red, the strongest possible green, and no blue. The second pixel is (125, 255, 5), and so on.

Every PPM file must be in this format. To view a PPM image on your Linux machine, use the command eog thepicture.ppm.

In our green screened images, every pixel in the background is 0 255 0.

Take care that your programs accept input in the order requested in the instructions.

Step 1: Grayscale an image (25/100)

To get used to the PPM format, let's not worry about greenscreening yet and just make an image grayscale (black and white). Write a program in a file called gray.cpp which prompts the user first for the filename of an existing PPM image, then for the filename the user would like his grayscale version to be called. The program then creates the new image, which is the gray version of the one read in. To find the gray value of a pixel, take the r, g, and b values, average them, and set all three values to that number. So, the gray version of (5, 100, 15) would be (40, 40, 40).

As an example, running this program on our picture of flowers gives us this:

If the file to be read in does not exist, the program should print an error message and gracefully exit.

Submit this program with the command submit proj1 gray.cpp

Step 2: Combine images (80/100)

In this step, we'll do the part described in the introduction. Your program should prompt the user first for the foreground image (our picture of Bill, with the green), then the background image (the flowered hillside), and finally the filename of the produced, combined image. If the foreground and background images are not the same size, your program should output an error message, rather than trying to create the new file.

Your program should be in a file called green.cpp.

The pictures in the tarball are all 1280x960, but your program should work for any two images that are the same size as each other.

A one-pixel wide green border around your foreground subject is fine.

If one of the two files to be read in don't exist, the program should print an error message and gracefully exit.

Submit this program with the command submit proj1 gray.cpp green.cpp

Step 3: Offset foreground image (100/100)

The problem with our program so far is that it only accepts pictures that are the same size. What if we want Bill somewhere other than in the middle of the picture?

Two of the pictures in the tarball you downloaded are cropped, so we should be able to put them anywhere in a picture that is at least as big as they are.

For this step, you'll write a program in a file called greenShift.cpp that prompts the user for a foreground image, a background image, an x shift, and a y shift. The x shift is how many pixels over horizontally from the left side the foreground image should be placed. The y shift is how many pixels down vertically from the top of the background picture the foreground image should be placed.

For example, the three pictures below have an (x-shift, y-shift) of (0, 0), (900, 0), and (0,200), respectively.

If the given x-shift or y-shift is so large that the foreground image would extend past the background image, an error message should be given, and no output image created.

If one of the two images input does not exist, the program should print an error message and gracefully exit.

Submit with the command submit proj1 gray.cpp green.cpp greenShift.cpp

Making your own pictures

To turn a picture in some other format into a plain ppm on your VM, first install the needed software by running: sudo apt-get install imagemagick. When it asks for your password, this is your VM password. The lab machines already have this software installed.

Once you have this software, if you have a picture somePic.jpg (or any other image format), you can convert it to a PPM with: convert -compress none somePic.jpg somePic.ppm. If you want it to be a particular size (like 640x480), you would run: convert -compress none -resize 640x480\! somePic.jpg somePic.ppm

Cutting out a foreground picture and putting it in front of a green screen requires Photoshop or its open-source equivalent GIMP, and the process is googleable, but longer than is appropriate for this page.