Last active
December 28, 2019 20:21
-
-
Save Shiro-Raven/86db9796dee600c3c9f3ae98db6f6b27 to your computer and use it in GitHub Desktop.
Code for the second assignment of the Computer Vision course
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /.idea | |
| *.jpeg | |
| *.jpg | |
| !GUC.jpg |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import math | |
| import numpy as np | |
| from PIL import Image | |
| np.set_printoptions(linewidth=5000) | |
| def calculate_LoG_value(x, y, sigma): | |
| term = (x ** 2 + y ** 2) / (2 * (sigma ** 2)) | |
| value = (-1 / (math.pi * (sigma ** 4))) * (1 - term) * (math.e ** (-1 * term)) | |
| return value | |
| def compute_LoG_mask(sigma): | |
| kernel_size = 2 * math.ceil(3 * sigma) + 1 | |
| offset_tuple = (kernel_size // 2, kernel_size // 2) | |
| mask = np.ndarray(shape=(kernel_size, kernel_size)) | |
| iterator = np.nditer(mask, flags=['multi_index'], op_flags=['writeonly']) | |
| with iterator: | |
| while not iterator.finished: | |
| iterator[0] = calculate_LoG_value(iterator.multi_index[0] - offset_tuple[0], | |
| iterator.multi_index[1] - offset_tuple[1], sigma) | |
| iterator.iternext() | |
| return mask | |
| def calculate_mask_value(padded_image, mask, x, y): | |
| mask_width = mask.shape[0] | |
| mask_height = mask.shape[1] | |
| subarray = padded_image[x: x + mask_width, y: y + mask_height] | |
| return np.sum(np.multiply(subarray, mask)) | |
| def is_zero_crossing(result_image, x, y): | |
| """ | |
| We handle right and bottom border pixels as pad, and give them | |
| the same label as the pixels to the left/above them, respectively | |
| """ | |
| if x == result_image.shape[0] - 1: | |
| return is_zero_crossing(result_image, x - 1, y) | |
| elif y == result_image.shape[1] - 1: | |
| return is_zero_crossing(result_image, x, y - 1) | |
| window_pixels = np.array( | |
| [result_image[x][y], result_image[x + 1][y], result_image[x][y + 1], result_image[x + 1][y + 1]]) | |
| sum = int(np.sum(np.sign(window_pixels))) | |
| return not (sum == 4 or sum == -4) | |
| def apply_prewitt(image, threshold): | |
| hx = np.array([[-1, 0, 1], | |
| [-1, 0, 1], | |
| [-1, 0, 1]]) | |
| hy = np.array([[-1, -1, -1], | |
| [0, 0, 0], | |
| [1, 1, 1]]) | |
| image_array = np.array(image) / 255.0 | |
| # Pad the image | |
| padded_image = np.pad(image_array, (hx.shape[0] // 2, hy.shape[0] // 2), 'edge') | |
| edge_labels = np.ndarray(shape=image_array.shape, dtype=np.bool) | |
| for x in range(0, edge_labels.shape[0]): | |
| for y in range(0, edge_labels.shape[1]): | |
| delta_x = calculate_mask_value(padded_image, hx, x, y) | |
| delta_y = calculate_mask_value(padded_image, hy, x, y) | |
| edge_value = math.sqrt(delta_x ** 2 + delta_y ** 2) | |
| edge_labels[x][y] = edge_value >= threshold | |
| percent_done = 100 * ((x * edge_labels.shape[0] + y) / (edge_labels.shape[0] * edge_labels.shape[1])) | |
| print('Calculating Prewitt: ', round(percent_done, 2), '%', end='\r') | |
| return edge_labels | |
| def apply_LoG(image, mask, threshold): | |
| # Retrieve the image array | |
| image_array = np.array(image) | |
| # Pad the image | |
| padded_image = np.pad(image_array, (mask.shape[0] // 2, mask.shape[1] // 2), 'edge') | |
| # Initialise the result image | |
| result_image = np.ndarray(shape=image_array.shape) | |
| # Loop over the padded image and apply the LoG filter | |
| for x in range(0, result_image.shape[0]): | |
| for y in range(0, result_image.shape[1]): | |
| result_image[x][y] = calculate_mask_value(padded_image, mask, x, y) | |
| percent_done = 100 * ((x * image_array.shape[0] + y) / (image_array.shape[0] * image_array.shape[1])) | |
| print('Applying LoG mask: ', round(percent_done, 2), '%', end='\r') | |
| print() | |
| # Detect the zero-crossings | |
| edge_labels = np.ndarray(shape=result_image.shape, dtype=np.bool) | |
| for x in range(0, image_array.shape[0]): | |
| for y in range(0, image_array.shape[1]): | |
| edge_labels[x][y] = is_zero_crossing(result_image, x, y) | |
| percent_done = 100 * ((x * image_array.shape[0] + y) / (image_array.shape[0] * image_array.shape[1])) | |
| print('Detecting zero-crossings: ', round(percent_done, 2), '%', end='\r') | |
| print() | |
| # Collect first-derivative evidence | |
| first_derivative = apply_prewitt(image, threshold) | |
| # Calculating edges | |
| final_image = Image.fromarray((edge_labels & first_derivative).astype(int) * 255.0) | |
| return final_image.convert('L') | |
| if __name__ == '__main__': | |
| sigma = float(input('What is the sigma value? ')) | |
| img = Image.open('Cameraman.tif').convert('L').copy() | |
| mask = compute_LoG_mask(sigma) | |
| threshold = input('Enter the threshold value (default = 0.1): ') | |
| threshold = 0.1 if threshold is '' else float(threshold) | |
| result = apply_LoG(img, mask, threshold) | |
| result.save('LoG_' + str(int(sigma)) + '.jpeg', 'JPEG') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import numpy as np | |
| from PIL import Image | |
| from tqdm import tqdm | |
| def calculate_cornerness(image_array, x, y): | |
| min = np.inf | |
| image_subarray = image_array[x - 1:x + 2, y - 1:y + 2] | |
| for i in range(-1, 2): | |
| for j in range(-1, 2): | |
| if i == 0 and j == 0: | |
| continue | |
| window_subarray = image_array[x - 1 + i:x + i + 2, y - 1 + j:y + j + 2] | |
| diff_squared_sum = np.sum(np.power(np.subtract(image_subarray, window_subarray), 2)) | |
| min = diff_squared_sum if diff_squared_sum < min else min | |
| return int(min) | |
| def apply_nonmax_suppression(corner_labels, cornerness_values): | |
| result_labels = np.copy(corner_labels) | |
| x_s, y_s = np.where(corner_labels == True) | |
| for x, y in zip(x_s, y_s): | |
| window = cornerness_values[x - 1: x + 2, y - 1: y + 2] | |
| if np.max(window) > cornerness_values[x][y]: | |
| result_labels[x][y] = False | |
| return result_labels | |
| def apply_moravec(image, threshold=2000): | |
| image_array = np.array(image).astype(np.int32) | |
| cornerness_vals = np.zeros_like(image_array) | |
| for x in tqdm(range(2, image_array.shape[0] - 2)): | |
| for y in range(2, image_array.shape[1] - 2): | |
| cornerness_vals[x][y] = calculate_cornerness(image_array, x, y) | |
| corner_labels = cornerness_vals >= threshold | |
| pre_suppression = Image.fromarray(corner_labels.astype(float) * 255.0) | |
| final_image = apply_nonmax_suppression(corner_labels, cornerness_vals) | |
| post_suppression = Image.fromarray(final_image.astype(float) * 255.0) | |
| return pre_suppression, post_suppression | |
| if __name__ == '__main__': | |
| image = Image.open('./GUC.jpg') | |
| threshold = input('Threshold value (default = 2000): ') | |
| threshold = 2000 if threshold is '' else float(threshold) | |
| pre, post = apply_moravec(image, threshold) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import numpy as np | |
| from PIL import Image | |
| def calculate_mask_value(padded_image, mask, x, y): | |
| mask_width = mask.shape[0] | |
| mask_height = mask.shape[1] | |
| subarray = padded_image[x: x + mask_width, y: y + mask_height] | |
| return np.sum(np.multiply(subarray, mask)) | |
| def apply_unsharp(img, kernel, gamma=0.5): | |
| # Retrieve the image array | |
| image_array = np.array(img) | |
| # Pad the image | |
| padded_image = np.pad(image_array, (kernel.shape[0] // 2, kernel.shape[1] // 2), 'edge') | |
| # Initialise the edge values | |
| edge_values = np.ndarray(shape=image_array.shape) | |
| # Applying Mask | |
| for x in range(0, edge_values.shape[0]): | |
| for y in range(0, edge_values.shape[1]): | |
| edge_values[x][y] = calculate_mask_value(padded_image, kernel, x, y) | |
| percent_done = 100 * ((x * image_array.shape[0] + y) / (image_array.shape[0] * image_array.shape[1])) | |
| print('Applying mask: ', round(percent_done, 2), '%', end='\r') | |
| print() | |
| final_image = Image.fromarray(image_array + gamma * edge_values) | |
| return final_image.convert('L') | |
| if __name__ == '__main__': | |
| gamma = input('Enter the gamma value (default = 0.5): ') | |
| gamma = 0.5 if gamma is '' else float(gamma) | |
| img = Image.open('./Cameraman.tif') | |
| kernel = np.array([[-1, -1, -1], | |
| [-1, 8, -1], | |
| [-1, -1, -1]]) | |
| sharpened = apply_unsharp(img, kernel, gamma) | |
| sharpened.save('Sharpened.jpeg', 'JPEG') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
