# Run this function
def check(result, expected):
if expected != result:
print(
f"Function should return the value {expected}, it is returning the value {result}.")
else:
print(f"Congratulations, the test case passed!")
from simpleimage import SimpleImage
We've seen in class how we can use filters to transform real and interesting images. In this exercise we are going to write more of our own fun filters.
To start, let's load up a simple image from class
einstein = SimpleImage("images/magazine.png")
einstein.show(400)
Let's convert the colors in this image to sepia. Sepia is a reddish-brown color like that of old photographs. Here is an example:
Normal | Sepia |
---|---|
Here we will be inverting each color individually, we will use this formula to convert the color each pixel.
pixel = image.get_rgb(x, y)
old_red = pixel[0] # This is the current value for red in this pixel
old_green = pixel[1] # This is the current value for green in this pixel
old_blue = pixel[2] # This is the current value of blue in this pixel
new_red: (old_red * .393) + (old_green *.769) + (old_blue * .189)
new_green: (old_red * .349) + (old_green *.686) + (old_blue * .168)
new_blue: (old_red * .272) + (old_green *.534) + (old_blue * .131)
image.set_rgb(x, y, new_red, new_green, new_blue)
# Work out how to get new_green and new_blue yourself!
def apply_sepia(image):
width = image.width
height = image.height
new_image = SimpleImage.blank(width, height)
for x in range(width):
for y in range(height):
pixel = image.get_rgb(x, y)
old_red = pixel[0]
old_green = pixel[1]
old_blue = pixel[2]
# TODO: WRITE YOUR CODE HERE
new_red = ???
new_green = ???
new_blue = ???
new_image.set_rgb(x, y, new_red, new_green, new_blue)
return new_image
apply_sepia(einstein).show(400)
# # For reference, here's the red_gradient_filter from the lecture
def red_gradient_filter(image):
width = image.width
height = image.height
new_image = SimpleImage.blank(width, height)
for x in range(width):
for y in range(height):
pixel = image.get_rgb(x, y)
# You want to change the next 3 lines -->
red = min(255, pixel[0] + x)
green = pixel[1]
blue = pixel[2]
new_image.set_rgb(x, y, red, green, blue)
return new_image
Cell In[9], line 14 new_red = ??? ^ SyntaxError: invalid syntax
In order to solve this problem. Use an averaging the RGB (Red, Green, Blue) values of each pixel with its surrounding pixels, including diagonals.
As we apply the blur filter, we must be cautious not to go beyond the image boundaries. Some pixels near the edges won't have all the neighboring pixels.
To avoid errors, we'll create a function that checks if a given pixel is within the image boundaries.
To implement the blur function, we follow these steps:
# Step 1: Create a function is_inbound(i, j, rows, cols) that checks if a pixel
# at row i and column j is within the rows and cols boundaries of the image.
def check_borders(x, y, width, height):
# TODO: WRITE YOUR CODE HERE
check(check_borders(0, 0, 2, 3), True)
check(check_borders(4, 0, 2, 3), False)
Cell In[10], line 7 check(check_borders(0, 0, 2, 3), True) ^ IndentationError: expected an indented block after function definition on line 4
def apply_blur(image):
width = image.width
height = image.height
new_image = SimpleImage.blank(width, height)
# Step 2: Now, iterate through each pixel in the image.
for x in range(width):
for y in range(height):
# Step 3: For each pixel, gather the RGB values of its neighboring pixels that are within the image boundaries.
# then calculate the average RGB values independently (average down) to get the new color for the current pixel.
# TODE: WRITE YOUR CODE HERE
new_red = ???
new_green = ???
new_blue = ???
# Step 4: Update the current pixel's color with the newly computed color.
new_image.set_rgb(x, y, new_red, new_green, new_blue)
return new_image
nature_image = SimpleImage("images/nature.jpg")
apply_blur(nature_image).show(500)
To make the image more blurred, you can apply the blurring process multiple times. Each iteration will further average out the RGB values of the pixels, leading to a stronger blurring effect. The more iterations you apply, the smoother and more blurred the image will become.
def apply_blur_multiple(image, iterations):
width = image.width
height = image.height
new_image = SimpleImage.blank(width, height)
# Repeat the above code that applies the blur effect multiple time here
# TODO: WRITE YOUR CODE HERE
return new_image
nature_image = SimpleImage("images/nature.jpg")
apply_blur_multiple(nature_image, 3).show(500)
To apply the blur effect only to a selected part of the image, you'll need to modify the apply_blur_multiple
function to specify the region you want to blur. One way to achieve this is by passing the coordinates of the selected region as input parameters to the function.
we will introduce a new function blur_selected_region
, which takes the original image, the number of iterations to apply the blur effect, the coordinates of the top-left corner of the selected region, the coordinates of the bottom-right corner of the selected region.
def apply_blur_multiple_with_selected_area(image, iterations, top_left, bottom_right):
width = image.width
height = image.height
tl_i, tl_j = top_left
br_i, br_j = bottom_right
new_image = SimpleImage.blank(width, height)
# TODO: WRITE YOUR CODE HERE
return new_image
nature_image = SimpleImage("images/nature.jpg")
width = nature_image.width
height = nature_image.height
top_left = (width // 8, height // 8)
bottom_right = ((3 * width) // 4, (3 * height) // 4)
apply_blur_multiple_with_selected_area(nature_image, 3, top_left, bottom_right).show(500)