2022-10-15 17:07:41 +02:00
|
|
|
|
import UZ_utils as uz
|
|
|
|
|
import numpy as np
|
2022-10-15 18:20:50 +02:00
|
|
|
|
import numpy.typing as npt
|
2022-10-15 20:58:42 +02:00
|
|
|
|
from matplotlib import pyplot as plt
|
2022-10-15 17:07:41 +02:00
|
|
|
|
|
2022-10-15 17:12:38 +02:00
|
|
|
|
#######################################
|
|
|
|
|
# EXCERCISE 1: Basic image processing #
|
|
|
|
|
#######################################
|
|
|
|
|
|
|
|
|
|
def excercise_one() -> None:
|
|
|
|
|
image = one_a()
|
|
|
|
|
one_b(image)
|
2022-10-15 19:44:51 +02:00
|
|
|
|
one_c(image)
|
2022-10-15 21:40:39 +02:00
|
|
|
|
one_d(100, 200, 50, 200, image) # needs to be fixed
|
2022-10-15 20:58:42 +02:00
|
|
|
|
one_e()
|
2022-10-15 17:12:38 +02:00
|
|
|
|
|
2022-10-15 18:20:50 +02:00
|
|
|
|
def one_a() -> npt.NDArray[np.float64]:
|
2022-10-15 19:57:58 +02:00
|
|
|
|
"""
|
|
|
|
|
Read the image from the file umbrellas.jpg and display it
|
|
|
|
|
"""
|
|
|
|
|
image = uz.imread('./images/umbrellas.jpg')
|
2022-10-15 20:11:55 +02:00
|
|
|
|
uz.imshow(image, 'Umbrellas')
|
2022-10-15 18:20:50 +02:00
|
|
|
|
return image
|
2022-10-15 17:07:41 +02:00
|
|
|
|
|
2022-10-15 18:20:50 +02:00
|
|
|
|
def one_b(image: npt.NDArray[np.float64]) -> None:
|
2022-10-15 19:57:58 +02:00
|
|
|
|
"""
|
|
|
|
|
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].
|
|
|
|
|
"""
|
2022-10-15 18:20:50 +02:00
|
|
|
|
grayscale_image = np.zeros(image.shape[:2])
|
2022-10-15 17:07:41 +02:00
|
|
|
|
|
2022-10-15 18:20:50 +02:00
|
|
|
|
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
|
|
|
|
|
|
2022-10-15 19:57:58 +02:00
|
|
|
|
uz.imshow(grayscale_image, 'Umbrellas grayscale')
|
2022-10-15 19:44:51 +02:00
|
|
|
|
|
|
|
|
|
def one_c(image: npt.NDArray[np.float64]) -> None:
|
2022-10-15 19:57:58 +02:00
|
|
|
|
"""
|
|
|
|
|
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:
|
|
|
|
|
"""
|
2022-10-15 20:11:55 +02:00
|
|
|
|
uz.imshow(image[50:200, 100:400, 2], "Just one piece of umbrellas")
|
2022-10-15 19:44:51 +02:00
|
|
|
|
|
|
|
|
|
def one_d(startx: int, endx: int, starty: int, endy: int, image:npt.NDArray[np.float64]) -> None:
|
2022-10-15 19:57:58 +02:00
|
|
|
|
"""
|
2022-10-15 20:11:55 +02:00
|
|
|
|
(height, width, color)
|
2022-10-15 21:40:39 +02:00
|
|
|
|
(x , y , color)
|
|
|
|
|
y ->
|
|
|
|
|
################# x
|
2022-10-15 20:11:55 +02:00
|
|
|
|
# # |
|
|
|
|
|
# # v
|
|
|
|
|
# #
|
|
|
|
|
# #
|
|
|
|
|
# #
|
|
|
|
|
#################
|
2022-10-15 19:57:58 +02:00
|
|
|
|
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()
|
2022-10-15 19:44:51 +02:00
|
|
|
|
|
2022-10-15 21:40:39 +02:00
|
|
|
|
for i in range(startx, endx):
|
|
|
|
|
for j in range(starty, endy):
|
2022-10-15 19:57:58 +02:00
|
|
|
|
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]
|
2022-10-15 19:44:51 +02:00
|
|
|
|
|
2022-10-15 21:50:46 +02:00
|
|
|
|
fig, (ax0, ax1) = plt.subplots(1, 2)
|
|
|
|
|
fig.suptitle("Lomberlini")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ax0.imshow(image, cmap="gray")
|
|
|
|
|
ax1.imshow(inverted_image, vmax=255, cmap="gray")
|
|
|
|
|
|
|
|
|
|
ax0.set(title="Original image")
|
|
|
|
|
ax1.set(title="Inverted image")
|
|
|
|
|
|
|
|
|
|
plt.show()
|
2022-10-15 17:07:41 +02:00
|
|
|
|
|
2022-10-15 19:57:58 +02:00
|
|
|
|
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.
|
|
|
|
|
"""
|
2022-10-15 20:58:42 +02:00
|
|
|
|
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()
|
|
|
|
|
|
2022-10-15 18:20:50 +02:00
|
|
|
|
|
2022-10-15 21:50:46 +02:00
|
|
|
|
############################################
|
|
|
|
|
# EXCERCISE 2: Thresholding and histograms #
|
|
|
|
|
############################################
|
2022-10-15 20:58:42 +02:00
|
|
|
|
|
2022-10-15 17:12:38 +02:00
|
|
|
|
def main() -> None:
|
|
|
|
|
excercise_one()
|
2022-10-15 17:07:41 +02:00
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
main()
|