uz_assignments/assignment1/solution.py

119 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import UZ_utils as uz
import numpy as np
import numpy.typing as npt
from matplotlib import pyplot as plt
#######################################
# EXCERCISE 1: Basic image processing #
#######################################
def excercise_one() -> None:
image = one_a()
one_b(image)
one_c(image)
one_d(100, 200, 50, 200, image) # needs to be fixed
one_e()
def one_a() -> npt.NDArray[np.float64]:
"""
Read the image from the file umbrellas.jpg and display it
"""
image = uz.imread('./images/umbrellas.jpg')
uz.imshow(image, 'Umbrellas')
return image
def one_b(image: npt.NDArray[np.float64]) -> None:
"""
Convert the loaded image to grayscale. A very simple way of doing this is summing
up the color channels and dividing the result by 3, effectively averaging the values.
The issue, however, is that the sum easily reaches beyond the np.uint8 range. We
can avoid that by casting the data to a floating point type. You can access a specific
image channel using the indexing syntax like red = I[:,:,0].
"""
grayscale_image = np.zeros(image.shape[:2])
for i in range(image.shape[0]):
for j in range(image.shape[1]):
grayscale_image[i, j] = (image[i, j, 0] + image[i,j, 1] + image[i, j, 2]) / 3
uz.imshow(grayscale_image, 'Umbrellas grayscale')
def one_c(image: npt.NDArray[np.float64]) -> None:
"""
Cut and display a specific part of the loaded image. Extract only one of the channels
so you get a grayscale image. You can do this by indexing along the first two axes,
for instance: cutout=I[130:260, 240:450, 1]. You can display multiple images in
a single window using plt.subplot().
Grayscale images can be displayed using different mappings (on a RGB monitor,
every value needs to be mapped to a RGB triplet). Pyplot defaults to a color map
named viridis, but often it is preferable to use a grayscale color map. This can be set
with an additional argument to plt.imshow, like plt.imshow(I, cmap=gray).
Question: Why would you use different color maps?
Answer:
"""
uz.imshow(image[50:200, 100:400, 2], "Just one piece of umbrellas")
def one_d(startx: int, endx: int, starty: int, endy: int, image:npt.NDArray[np.float64]) -> None:
"""
(height, width, color)
(x , y , color)
y ->
################# x
# # |
# # v
# #
# #
# #
#################
You can also replace only a part of the image using indexing. Write a script that
inverts a rectangular part of the image. This can be done pixel by pixel in a loop or
by using indexing.
Question: How is inverting a grayscale value defined for uint8 ?
Answer:
"""
inverted_image = image.copy()
for i in range(startx, endx):
for j in range(starty, endy):
inverted_image[i, j, 0] = 1 - image[i, j, 0]
inverted_image[i, j, 1] = 1 - image[i, j, 1]
inverted_image[i, j, 2] = 1 - image[i, j, 2]
uz.imshow(inverted_image, 'Few umbrellas inverted')
def one_e() -> None:
"""
Perform a reduction of grayscale levels in the image. First read the image from
umbrellas.jpg and convert it to grayscale. You can write your own function for
grayscale conversion or use the function in UZ_utils.py.
Convert the grayscale image to floating point type. Then, rescale the image values
so that the largest possible value is 63. Convert the image back to uint8 and display
both the original and the modified image. Notice that both look the same. Pyplot
tries to maximize the contrast in displayed images by checking their values and
scaling them to cover the entire uint8 interval. If you want to avoid this, you need
to set the maximum expected value when using plt.imshow(), like plt.imshow(I,
vmax=255. Use this to display the resulting image so the change is visible.
"""
grayscale_image = uz.imread_gray("./images/umbrellas.jpg")
upscaled_grayscale_image = (grayscale_image.copy() * 63).astype(np.uint8)
fig, (ax0, ax1) = plt.subplots(1, 2)
fig.suptitle("Lomberlini")
ax0.imshow(grayscale_image, cmap="gray")
ax1.imshow(upscaled_grayscale_image, vmax=255, cmap="gray")
ax0.set(title="Original grayscale image")
ax1.set(title="Upscaled grayscale image")
plt.show()
def main() -> None:
excercise_one()
if __name__ == "__main__":
main()