Lecture 38 - Image Manipulation

Lecture Date: Friday, April 22

More image manipulation algorithms today!

Our main algorithms for the day will be:

  • Image Negative (see previous day’s lecture notes)
  • Grayscale
  • Resizing
  • Green Screen

Grayscale

The basic idea here to get the overall intensity of the color by adding up the red, green, and blue values and then taking the average. Remember that for a pixel to be gray (or black or white), all three RGB values have to be the same.

1
2
3
4
5
6
# Here we define a method that will take a pixel
# and return a pixel that is the right intensity of gray
def negative_pixel(old_pixel):
    intensity = (old_pixel.getRed() + old_pixel.getGreen() + old_pixel.getBlue()) // 3
    new_pixel = Pixel(intensity, intensity, intensity)
    return new_pixel

Resizing

With resizing, we will either be taking a fraction of the pixels (to make the image smaller) or duplicating pixels (to make the image bigger). We begin by creating a new image at the new size. Then, as we adjust the looping through our original image based on the scaling factor - we either skip pixels to make a smaller image or grab the same pixel multiple times to enlarge it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from cImage import *

# Open an image
old_image = FileImage('rotunda.gif')

image_window_old = ImageWin("Original", old_image.width, old_image.height)

# Draw the image on the window
old_image.draw(image_window_old)

scale = float(input("Scale?: "))

new_image = EmptyImage(int(old_image.width* scale), int(old_image.height* scale))

image_window_new = ImageWin("Scaled", int(old_image.width* scale), int(old_image.height* scale))

for row in range(int(old_image.height*scale)):
    for col in range(int(old_image.width*scale)):
        old_pixel = old_image.getPixel(int(col/scale), int(row/scale))
        new_image.setPixel(col, row, old_pixel)

new_image.draw(image_window_new)

image_window_new.exitOnClick()
image_window_old.exitOnClick()

Green Screen

Take two pictures, one in which the background is completely one solid color that you wouldn’t normally find in a “typical” picture. (This is one reason TV weathermen don’t wear green…) Then, as you loop through both pictures, pick the pixels from the background image if the matching pixel from the foreground image is green. Otherwise, take the pixel from the foreground image. Here are two images we can work with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from cImage import *

def isGreen(greenPixel):
    if greenPixel.getGreen() > greenPixel.getRed() + greenPixel.getBlue():
        return True
    return False

green_image = FileImage('ninja.gif')
background_image = FileImage('mtn.gif')
image_window = ImageWin("Green Screen", green_image.width * 3, green_image.height)
green_image.draw(image_window)
background_image.setPosition(green_image.width + 1, 0)
background_image.draw(image_window)

combined_image = EmptyImage(green_image.width, green_image.height)

for row in range(green_image.height):
    for col in range(green_image.width):
        if isGreen(green_image.getPixel(col, row)):
            new_pixel = background_image.getPixel(col, row)
            combined_image.setPixel(col, row, new_pixel)
        else:
            new_pixel = green_image.getPixel(col, row)
            combined_image.setPixel(col, row, new_pixel)

combined_image.setPosition(background_image.width + green_image.width + 1, 0)
combined_image.draw(image_window)

image_window.exitOnClick()