.py
files containing your work.This homework assignment must be submitted in Gradescope by Noon central time on Tuesday March 28, 2023. That's after spring break.
Collaboration is prohibited, and you may only access resources (books, online, etc.) listed below.
This homework is about numpy
.
Most relevant:
Less likely to be relevant, but also allowed:
This homework assignment has 2 problems, numbered 2 and 3. The grading breakdown is:
Points | Item |
---|---|
3 | Autograder |
6 | Problem 2 |
6 | Problem 3 |
15 | Total |
The part marked "autograder" reflects points assigned to your submission based on some simple automated checks for Python syntax, etc. The result of these checks is shown immediately after you submit.
Ask your instructor or TA a question by email, in office hours, or on discord.
Submit your answer to this problem in a file hwk10prob2.py
.
Write a function zero_border(sh,k,val)
that returns a matrix (2D numpy array) of shape sh
(a tuple of two integers) in which all entries are filled with value val
except for those that are k
steps or fewer from the edges of the edges of the matrix.
In doing so, follow these rules:
for
or while
loops that involve a number of steps that depends on either of the entries in sh
. That is, a call tozero_border( (100_000, 50_000), 3, 275)
for
or while
loops that run anywhere close to 50,000 times.sh
.The first of these rules is meant to force you to use numpy
constructions in an appropriate way, rather than relying on slower Python-based looping constructions.
Here's some sample output from the function.
zero_border( (5,5), 1, 12)
zero_border( (5,5), 2, 12)
zero_border( (5,5), 3, 12)
zero_border( (5,5), 200, 12)
zero_border( (5,5), 0, 12)
zero_border( (6,8), 1, 77)
zero_border( (6,8), 2, 77)
Method 1: Fill an array with val
, then add in the zeros:
import numpy as np
def zero_border(sh,k,val):
"""Returns numpy array of size `sh` with zeros on border of size `k` and `val` elsewhere"""
m = np.full(sh, val)
m[:k] = 0 # Top
m[-k:] = 0 # Bottom
m[ : , :k ] = 0 # Left
m[ : , -k:] = 0 # Right
return m
Method 2: Fill an array with zeros, then put in the given value everywhere except the border:
def zero_border(sh,k,val):
"""Returns numpy array of size `sh` with zeros on border of size `k` and `val` elsewhere"""
m = np.zeros(sh, dtype=int)
m[k:-k, k:-k] = val
return m
Submit your answer to this problem in a file hwk10prob3.py
.
Write a program that expects expects there to be two grayscale image files of the same dimensions in the current directory:
ws10_grayscale_onion.png
from worksheet 10 andphoto.png
The program should load these images into numpy arrays, and then use numpy functions and features to answer this question (printing the answer to the terminal):
photo.png
are brighter (larger grayscale value) than the corresponding pixel in ws10_grayscale_onion.png
?photo.png
is strictly brighter.As with the previous problem, avoid explicit iteration (for or while loops) where the number of steps is one of the image dimensions.
The output should look like this (replacing the pixel count and percentage with the actual values):
txt
Comparing ws10_grayscale_onion.png and photo.png.
Result:
photo.png has 1591 pixels that are brighter than the corresponding ones in ws10_grayscale_onion.png.
That corresponds to 1.33% of the pixels in photo.png being brighter.
You may copy the image-array conversion functions introduced in worksheet 10 into your solution and use them. Here they are for reference:
import PIL.Image
import numpy as np
def load_image_to_array(fn):
"Open image file with name `fn` and return as a numpy array`"
img = PIL.Image.open(fn)
return np.array(img)
def save_array_to_image(fn,A):
"Save 2D array `A` with dtype `uint8` to file named `fn`"
assert A.ndims == 2
assert A.dtype == np.dtype("uint8")
img = PIL.Image.fromarray(A)
img.save(fn)
For this example solution, let's use the image we made in Problem 2 of Worksheet 10 where the average brightness of pixels on each row was taken:
Using this image is convenient because it has the same dimensions as the original onion image. Let's save this as photo.png
. Then we can use the following code:
fn1 = "ws10_grayscale_onion.png"
fn2 = "photo.png" # Row-average image
onion = load_image_to_array(fn1)
photo = load_image_to_array(fn2)
# Number of pixels in `photo` brighter than in `onion`
num_brighter = np.sum(photo > onion)
# Percentage of pixels brighter
percent_brighter = 100 * num_brighter / onion.size
# Output
print("Comparing {} and {}.".format(fn1, fn2))
print("Result:")
print("{} has {} pixels that are brighter than the corresponding ones in {}".format(fn2, num_brighter, fn1))
print("That corresponds to {:.2f}% of the pixels in {} being brighter.".format(percent_brighter, fn2))