Skip to content
Snippets Groups Projects
Commit 93e69faf authored by Sebastian Zimmermann's avatar Sebastian Zimmermann
Browse files

Added Exercise 1 files

parent 9e83aca3
No related branches found
No related tags found
No related merge requests found
File added
Exercise_1/data/contrast.jpg

342 KiB

Exercise_1/data/hello.png

136 KiB

Exercise_1/data/hello_gaussian.png

318 KiB

Exercise_1/data/hello_poisson.png

334 KiB

Exercise_1/data/hello_salt_pepper.png

158 KiB

Exercise_1/data/hello_uniform.png

327 KiB

Exercise_1/data/kitty.png

185 KiB

Exercise_1/data/runes.png

1.46 MiB

import numpy as np
import cv2
import matplotlib.pyplot as plt
def load_image(path: str) -> np.ndarray:
# Load the image using CV2 and return it.
loaded_image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
if loaded_image is None:
raise FileNotFoundError(f"Cannot load image at {path}")
return loaded_image
def compute_histogram(image: np.ndarray) -> np.ndarray:
# ToDo: Create a histogram for the given image (256 values).
# ToDo: Don't use functions like np.histogram.
# ToDo: It is easier if you flatten your image first.
histogram = np.zeros(0)
return histogram
def compute_cdf(histogram: np.ndarray) -> np.ndarray:
# ToDo: Compute the CDF.
# ToDo: Don't forget to normalize it (turn it into a distribution).
cdf = np.zeros(0)
return cdf
def equalize_image(image: np.ndarray, cdf: np.ndarray) -> np.ndarray:
# ToDo: Apply histogram equalization to the given image.
# ToDo: Hint: Flatten the image first and reshape it again in the end.
equalized_image = np.zeros(0)
return equalized_image
def save_image(image: np.ndarray, path: str) -> None:
# Save the image to the given folder.
cv2.imwrite(path, image)
def show_images(original_image: np.ndarray, equalized_image: np.ndarray) -> None:
# ToDo: Display the original and the equalized images next to each other.
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(original_image, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.subplot(1, 2, 2)
plt.imshow(equalized_image, cmap='gray')
plt.title('Equalized Image')
plt.axis('off')
plt.tight_layout()
plt.show()
def histogram_equalization(input_path: str, output_path: str) -> None:
# ToDo: Combine the different functions into one.
loaded_image = load_image(input_path)
histogram = compute_histogram(loaded_image)
cdf = compute_cdf(histogram)
equalized_image = equalize_image(loaded_image, cdf)
save_image(equalized_image, output_path)
if __name__ == '__main__':
# Load the images and perform histogram equalization.
input_image_path = 'data/hello.png'
output_image_path = 'data/kitty.png'
histogram_equalization(input_image_path, output_image_path)
# Show the images next to each other.
original = load_image(input_image_path)
equalized = load_image(output_image_path)
show_images(original, equalized)
import numpy as np
import cv2
import matplotlib.pyplot as plt
def load_image(file_path: str) -> np.ndarray:
# Load the image (either gray or colour).
loaded_image = cv2.imread(file_path, cv2.IMREAD_UNCHANGED)
if loaded_image is None:
raise FileNotFoundError(f"Cannot load image at {file_path}")
return loaded_image
def save_image(image: np.ndarray, file_path: str) -> None:
# Save the image.
cv2.imwrite(file_path, image)
def add_gaussian_noise(image: np.ndarray, mean: float = 0.0, sigma: float = 10.0) -> np.ndarray:
# ToDo: Generate gaussian noise and add it to the image.
# ToDo: Hint: Look at the options among np.random to generate the noise.
# ToDo: Hint: Don't forget to clip the values.
return image
def add_salt_and_pepper_noise(image: np.ndarray, salt_prob: float = 0.01, pepper_prob: float = 0.01) -> np.ndarray:
# ToDo: Generate random salt and pepper noise based on the provided probabilities.
# ToDo: Hint: Look at the options among np.random to generate the noise.
return image
def add_poisson_noise(image: np.ndarray) -> np.ndarray:
# ToDo: Add poisson noise to the image.
# ToDo: Hint: Look at the options among np.random to generate the noise.
return image
def add_uniform_noise(image: np.ndarray, low: float = -20.0, high: float = 20.0) -> np.ndarray:
# ToDo: Add uniform noise to the image, which is sampled uniformly from the available values.
# ToDo: Hint: Look at the options among np.random to generate the noise.
return image
def display_images(original: np.ndarray, processed: np.ndarray, title: str) -> None:
# Transform the colour image (BGR) into an RGB image.
def to_rgb(image):
return cv2.cvtColor(image, cv2.COLOR_BGR2RGB) if image.ndim == 3 else image
adapted_original_image = to_rgb(original)
adapted_noise_image = to_rgb(processed)
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(adapted_original_image, cmap=None if adapted_original_image.ndim == 3 else 'gray')
plt.title('Original')
plt.axis('off')
plt.subplot(1, 2, 2)
plt.imshow(adapted_noise_image, cmap=None if adapted_noise_image.ndim == 3 else 'gray')
plt.title(title)
plt.axis('off')
plt.tight_layout()
plt.show()
if __name__ == '__main__':
# Example usage
input_file = 'data/hello.png'
gaussian_file = 'data/hello_gaussian.png'
salt_pepper_file = 'data/hello_salt_pepper.png'
poisson_file = 'data/hello_poisson.png'
uniform_file = 'data/hello_uniform.png'
original_image = load_image(input_file)
# Apply noise to the images.
gaussian = add_gaussian_noise(original_image)
save_image(gaussian, gaussian_file)
salt_pepper = add_salt_and_pepper_noise(original_image)
save_image(salt_pepper, salt_pepper_file)
poisson = add_poisson_noise(original_image)
save_image(poisson, poisson_file)
uniform = add_uniform_noise(original_image)
save_image(uniform, uniform_file)
# Display the images side by side.
display_images(original_image, gaussian, 'Gaussian Noise')
display_images(original_image, salt_pepper, 'Salt & Pepper Noise')
display_images(original_image, poisson, 'Poisson Noise')
display_images(original_image, uniform, 'Uniform Noise')
import numpy as np
import cv2
import matplotlib.pyplot as plt
def compute_histogram(image: np.ndarray) -> np.ndarray:
# ToDo: Compute a grayscale histogram with 256 bins.
histogram = np.zeros(0)
return histogram
def p_helper(prob: np.ndarray, theta: int) -> tuple[float, float]:
# ToDo: Compute the class probabilities p0 and p1 for the current threshold theta.
p0 = 0.0
p1 = 0.0
return p0, p1
def mu_helper(prob: np.ndarray, theta: int, p0: float, p1: float) -> tuple[float, float]:
# ToDo: Compute the class means mu0 and mu1 for the current threshold theta.
mu0 = 0.0
mu1 = 0.0
return mu0, mu1
def otsu_threshold(histogram: np.ndarray) -> int:
# ToDo: Compute Otsu's threshold from a histogram using p_helper and mu_helper.
# ToDo: Normalize the histogram to its probabilities (PDF).
prob = histogram.astype(np.float64)
# ToDo: Iterate over all possible thresholds, select the best one.
# ToDo: Hint: Skip invalid splits (p0 == 0 or p1 == 0).
max_variance = 0.0
best_threshold = 0
return best_threshold
def otsu_binarize(image: np.ndarray) -> tuple[np.ndarray, int]:
# ToDo: Binarize the threshold image.
# ToDo: Simply combine the existing functions.
theta = 0
new_image = np.zeros(0)
return new_image, theta
def custom_binarization(image: np.ndarray, theta: int) -> tuple[np.ndarray, int]:
# ToDo: Binarize the image with a custom value.
new_image = np.where(image > theta, 255, 0).astype(np.uint8)
return new_image, theta
if __name__ == '__main__':
# Load grayscale image.
loaded_image = cv2.imread('data/runes.png', cv2.IMREAD_GRAYSCALE)
if loaded_image is None:
raise FileNotFoundError("Cannot load the image.")
# Compute Otsu's binarization or perform a custom binarization. Comment out one of the options.
# binarized_image, threshold = otsu_binarize(loaded_image)
binarized_image, threshold = custom_binarization(loaded_image, 180)
# Display the original and the binarized image next to each other.
plt.figure(figsize=(8, 4))
plt.subplot(1, 2, 1)
plt.imshow(loaded_image, cmap='gray')
plt.title('Original')
plt.axis('off')
plt.subplot(1, 2, 2)
plt.imshow(binarized_image, cmap='gray')
plt.title(f"Otsu Binarization (t={threshold})")
plt.axis('off')
plt.tight_layout()
plt.show()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment