HW11: Image Processing II

25 points; due Mon 5/12 @ 9am.

Goals

The goal of this assignment is to get more comfortable with interacting with images.

Setup and Requirements

Create a directory named image2 that will contain your code for this project. Copy files over from your directory for the last homework assignment:

You may also start from a clean slate with photolab2.py if you'd like, or from last assignment's starter code. Your grade on this assignment will not be affected at all by the presence, absence, or functionality of the functions you wrote for the last assignment (unless they somehow break the code that is supposed to work for this assignment).

Your task will be to add several functions to this program, and then change the main function. Make sure that you read the documentation for imageManip before you start, and refer back to it while you're working; there are methods in there that will be useful to you.

This is an individual assignment.

Task 1: Chroma Key

Background

Movies, particularly action movies that use a lot of special effects, often use a technique called chroma key (sometimes commonly known as “green-screening”). The idea is that actors can perform in front of a background that has a uniform and unusual color (usually bright green or blue). Later on, after the scene has been filmed, the special effects people remove that color from the scene and replace it with something more interesting: a dinosaur, the white house, etc.

You will use the same technique to insert pictures of two CS professors into different scenes.

The images named background*.jpg in the images folder depict some sort of scenery, while dave.jpg and amy.jpg are just Dave Musicant and Amy Csizmar-Dalal standing against a (somewhat) solid-colored background.

Write the following functions:

replaceWallWithColor(image, color)

Creates and returns a new image with all of the “wall” pixels replaced by the color specified (an RGB triplet). (By “wall” pixel, I mean the pixels in the image that make up the wall in the background.)

replaceWallWithImage(orig_img, replacement_img)

Creates and returns a new image with all of the “wall” pixels replaced by the replacement image. (That is, each wall pixel would get replaced by the pixel at the same position in the replacement image.) You may assume that orig_img and replacement_img are the same size, or you can check that at the beginning of your function.

Identifying which pixels are in the wall is the trickiest part of this assignment. Here's a starting point that might not get everything: many wall pixels have intensities of at least 100 in both the red and green channels, and the difference between the intensities in any pair of channels (red, green, or blue) is less than 30. Note that filtering by intensity values is not the only way to determine whether a pixel is part of the wall or not.

This one is kinda tricky, so don't hesitate to ask questions of me, the prefect, lab assistants, or anyone!

Task 2: Rotating

Write the following function:

rotate_left(image)

Creates and returns a new image that is rotated 90 degrees to the left (counterclockwise) from the image given. (To do this rotation, you'll have to think about the relationship between your original image's dimensions and the rotated image's dimensions, and where a particular pixel $(x,y)$ in your original image should go in your new image.

Task 3: Blurring

Write the following function:

blur(image, radius)

Creates and returns a new image that is a blurred copy of the image given. For each pixel $(x,y)$, average together all the pixels wihtin a square centered on $(x,y)$ with the given “radius”. By “radius“ of a square, I mean the number of pixels between the edge of the square and the edge of the center pixel. So, for example, a square of radius 2 is 5 pixels wide and 5 pixels tall: the center pixel (1) plus two pixels on either side (2 + 2).

Make sure to put all of your results into a new image as you go, and return that new image. Also, make sure you're reading the intensity values from your original image; otherwise, the blur will build up as you go along.

Dealing with the edge of the image (pixels within radius pixel-widths of the edge) — the source square goes outside the image! You can choose one of two ways to deal with this. You can either just average together the pixels in the source square that actually fall within the area of the image, or you can just not blur near the edge, and instead copy over each pixel directly from the original image.

You’ll want to work with a small image when testing this function, since blurring can take a long time. Some approaches to this problem run a lot faster than others. While we won’t be grading on speed of your solution, we do require that your algorithm takes less than one minute to blur a small image with a radius of 3.

Task 4: Scaling

Write the following function:

rescale(image, scale)

Scales your image by the given scaling factor. If scale is 2, for example, each side of your new image should be twice the length of the original. If scale is 0.25, each side should be a quarter the length of the original. If scaling is less than or equal to 0, return None. Otherwise, return the new scaled image.

Hint 1: You’ve got a choice to make. Do you loop over all pixels in the old image, and figure out where they belong in the new image? Or do you loop over all pixels in the new image, and figure out where it should be copied from in the old image? One of these approaches is easier than the other.

Hint 2: For this assignment, you do not need to blend pixel values in any way. The value in each pixel in the result should just be a copy of the value in some pixel in the input image. What if the new image is bigger than the old one? Then multiple pixels in the output may be copies of the same pixel in the input.

Test it, too!

main()

Use all your functions in the main method, to demonstrate that they work correctly, just as in the last assignment. Just as in the last assignment, don't directly call your main function; instead, put it in an “import guard” block like we talked about in class:

if __name__ == "__main__":
    main()

Grading and Submission

Remember to put your name at the top of your source code!

Submit your program, photolab2.py, via Moodle.

Good luck, and have fun! Remember that lab assistants are available in the evenings in the CMC to help out if you need it.

This assignment originally designed by Dave Musicant, with modifications by Sherri Goings and Andy Exley (and then me, of course). It takes a village...