Lab 16: Image Processing

In this lab, you are going to practice working with the Python Imaging Library and using nested loops to manipulate images.

Installing the pillow module

In Thonny, install the Pillow package by selecting Tools$\rightarrow$Manage packages... then search for and install Pillow.

Displying an image with PIL in Python

Download the image griff.jpg, and move it to a directory where you keep your Python code. Then, run the following code to make sure you can open and display the file.

from PIL import Image

with Image.open("griff.jpg") as griff_image:
    griff_image.show()

Exercises

Exercise 1: Get Python to display some other image (a photograph you've taken, another image you found on the Internet, etc.).

Exercise 2: In the lecture, we were able to find the size of the image and look at the tuple for the color in the upper-left corner of the image with code like this:

print(griff_image.size)

pixels = griff_image.load()
    
print(pixels[0,0])

Note that griff_image.size[0] gives the width of the image in pixels, and griff_image.size[1] gives the height. Print out the tuple for the colors of all four corners of your image (note that you'll need to griff_image.size[0] and griff_image.size[1] for this - but remember that the pixel indices start counting at 0).

Exercise 3: In the lecture, we used a nested for loop to make a thick, black, horizontal line accross the Griff image. Write a nested for loop that makes a thick, green, vertical line somewhere down the middlel of your image. Adjust the width so it has a similar thickness in proportion to the size of your image.

from PIL import Image

with Image.open("griff.jpg") as griff_image:
    pixels = griff_image.load()
    
for p in range(griff_image.size[0]):
    for r in range(50,60):
        pixels[p,r] = (0,0,0)
    
    
    
griff_image.show()

Exercise 4: In the lecture, we wrote the following code to flip the Griff image horizontally. Write a nested for loop that will flip your image vertically.

from PIL import Image

with Image.open("griff.jpg") as griff_image:
    pixels = griff_image.load()
    
for c in range(griff_image.size[0]//2):
    for r in range(griff_image.size[1]):

    
        leftside = pixels[griff_image.size[0]-1-c,r]
        pixels[griff_image.size[0]-1-c,r] = pixels[c,r]
        pixels[c,r] = leftside
    
    
griff_image.show()

Exercise 5: In the lecture, we converted the Griff image to grayscale using the following code. Write a nested for loop that converts your image to grayscale.

from PIL import Image

with Image.open("griff.jpg") as griff_image:
    pixels = griff_image.load()
    
for c in range(griff_image.size[0]):
    for r in range(griff_image.size[1]):
        red = pixels[c,r][0]
        green = pixels[c,r][1]
        blue = pixels[c,r][2]
        
        average_pixel_color = (red+green+blue)//3
        
        pixels[c,r] = (average_pixel_color,average_pixel_color,average_pixel_color)
    
    
    
griff_image.show()

Exercise 6: Use nested for loops to apply some new kind of filter or effect to an image. You only have to do one thing, and the difficulty level doesn't matter as long as you're using nested for loops. Here are some ideas:

  • (Easy) Custom filter: Adjust the colors of your image to emphasize or de-emphasize each of the different color components to produce a neat effect.
  • (Easy) Color-blindness simulation: Some individuals have trouble distinguishing some shades of red and green (these types of color blindess are called Protanopia and Deuteranopia). One way to crudely simulate what a person with one of these conditions would see is to average the red and green values for each pixel, but leave the blue value as it was originally.
  • (Easy) Inverse filter: Change all color values to 255-original_value to see the inverse colors of the image.
  • (Medium) Classic filter: Look up the algorithm for a specific kind of color filter, and implement that (e.g., you can find a description of the Sepia algorithm here: https://dyclassroom.com/image-processing-project/how-to-convert-a-color-image-into-sepia-image )
  • (Medium) Red-eye remover: find any red pixel (say, where the red color value is greater than the sum of the blue and green color values), and change these pixels to black.
  • (Medium) Blurr effect: Make each pixel the average of the pixels around it (you can play around with how many pixels away you want to use in the average based on how blurry you want it to be)
  • (Hard) Green-screen effect: Replace all green pixels of one photograph with the corresponding pixel from a different image. (For images, try searching http://images.google.com for something like "green screen movie set")
  • (Hard) Pixel transformations: Pick a spot in the middle of the image, and move around the pixels to create a stretch, twist, bubble, etc. effect.