def apply_contra_harmonic_mean(img, filter_size, q): filter_size = util.format_filter_size(filter_size) obtained, original = util.get_empty_image_with_same_dimensions(img) if len(img.shape) == 2: for i in range(len(original)): for j in range(len(original[0])): neighbors = ImageFilter.__get_neighbors_matrix( filter_size, i, j, original) obtained[i][j] = ImageFilter.get_contra_harmonic_mean( neighbors, q) else: R = ImageFilter.apply_contra_harmonic_mean(img[:, :, 0], filter_size, q) G = ImageFilter.apply_contra_harmonic_mean(img[:, :, 1], filter_size, q) B = ImageFilter.apply_contra_harmonic_mean(img[:, :, 2], filter_size, q) output = np.zeros((R.shape[0], R.shape[1], 3), dtype=np.uint8) output[:, :, 0] = R output[:, :, 1] = G output[:, :, 2] = B obtained = output return obtained
def compress(self): initial_bytes_amount = self.__read_bytes_amount(self.filename) img = util.read_image(self.filename) img = self.apply_bilinear_interpolation(img, 0.8) scaled_filename = self.__format_scaled_filename(self.filename) util.save_image(scaled_filename, img) compressor = Huffman(scaled_filename) compressor.compress() return compressor.compress_filename, initial_bytes_amount, compressor.final_bytes_amount
def decompress(self): compressor = Huffman(self.filename) compressor.decompress() img = util.read_image(compressor.decompress_filename) img = self.apply_bilinear_interpolation(img, 1.2) scaled_filename = compressor.decompress_filename.replace( "small", "big") util.save_image(scaled_filename, img) return scaled_filename
def apply_laplacian(img): kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]]) obtained = ImageFilter.apply_convolution(img, kernel) norm_obtained = util.normalize_image(obtained) sharpened = img + norm_obtained norm_sharpened = util.normalize_image(sharpened) return norm_obtained, norm_sharpened
def apply_geometric_mean(img, filter_size): filter_size = util.format_filter_size(filter_size) obtained, original = util.get_empty_image_with_same_dimensions(img) for i in range(len(original)): for j in range(len(original[0])): neighbors = ImageFilter.__get_neighbors_matrix( filter_size, i, j, original) obtained[i][j] = ImageFilter.get_geometric_mean(neighbors) return obtained
def apply_gradient(img, filter_matrix): ''' Apply gradient using a single filter_matrix (3x3). ''' # filter_height, filter_width = util.get_dimensions( # filter_matrix) # assert filter_height != 3, "Filter Matrix must have height = 3 instead of " + \ # str(filter_height) # assert filter_width != 3, "Filter Matrix must have width = 3 instead of " + \ # str(filter_width) height, width = util.get_dimensions(img) # define image with 0s new_gradient_image = np.zeros((height, width), np.uint8) if len(img.shape) == 2: for i in range(1, height - 1): for j in range(1, width - 1): grad = ImageFilter.apply_gradient_core( filter_matrix, img, i, j) new_gradient_image[i - 1, j - 1] = abs(grad) else: R = ImageFilter.apply_gradient(img[:, :, 0], filter_matrix) G = ImageFilter.apply_gradient(img[:, :, 1], filter_matrix) B = ImageFilter.apply_gradient(img[:, :, 2], filter_matrix) output = np.zeros((R.shape[0], R.shape[1], 3), dtype=np.uint8) output[:, :, 0] = R output[:, :, 1] = G output[:, :, 2] = B new_gradient_image = output return new_gradient_image
def get_bilinear_pixel_interpolation(self, img, posX, posY): out = [] # Get integer parts of positions modXi = int(posX) modYi = int(posY) # Get fractional parts of positions modXf = posX - modXi modYf = posY - modYi # To avoid going over image bounderies height, width = util.get_image_dimensions(img) modXiPlusOneLim = min(modXi + 1, width - 1) modYiPlusOneLim = min(modYi + 1, height - 1) # Get pixels in four corners for channel in range(img.shape[2]): bottom_left = img[modYi, modXi, channel] bottom_right = img[modYi, modXiPlusOneLim, channel] top_left = img[modYiPlusOneLim, modXi, channel] top_right = img[modYiPlusOneLim, modXiPlusOneLim, channel] # Calculate interpolation obtained_bottom = modXf * bottom_right + (1. - modXf) * bottom_left obtained_top = modXf * top_right + (1. - modXf) * top_left new_channel = modYf * obtained_top + (1. - modYf) * obtained_bottom out.append(int(new_channel + 0.5)) return out
def apply_median(img, filter_size): filter_size = util.format_filter_size(filter_size) obtained, original = util.get_empty_image_with_same_dimensions(img) if len(img.shape) == 2: for i in range(len(original)): for j in range(len(original[0])): obtained[i][j] = ImageFilter.get_median( filter_size, i, j, original) else: R = ImageFilter.apply_median(img[:, :, 0], filter_size) G = ImageFilter.apply_median(img[:, :, 1], filter_size) B = ImageFilter.apply_median(img[:, :, 2], filter_size) output = np.zeros((R.shape[0], R.shape[1], 3), dtype=np.uint8) output[:, :, 0] = R output[:, :, 1] = G output[:, :, 2] = B obtained = output return obtained
def apply_sepia(img): height, width = util.get_image_dimensions(img) obtained, img = util.get_empty_image_with_same_dimensions(img) r_matrix, g_matrix, b_matrix = rgb.get_rgb_layers(img) for i in range(height): for j in range(width): r, g, b = r_matrix[i][j], g_matrix[i][j], b_matrix[i][j] tr = int(0.393 * r + 0.769 * g + 0.189 * b) tg = int(0.349 * r + 0.686 * g + 0.168 * b) tb = int(0.272 * r + 0.534 * g + 0.131 * b) r = ColorFilter.__normalize_max_value(tr, r) g = ColorFilter.__normalize_max_value(tg, g) b = ColorFilter.__normalize_max_value(tb, b) obtained[i][j] = [r, g, b] return obtained
def show_histogram(self): a = filter.histogram(self.current_image) f = plt.figure() _ = plt.hist(a, bins='auto') # arguments are passed to np.histogram plt.title("Histogram") self.update_memory_images(self.current_image) return util.fig2img(f)
def apply_bilinear_interpolation(self, img, scale): if scale <= 0: return img imHeight, imWidth = util.get_image_dimensions(img) enlargedShape = list( map(int, [imHeight * scale, imWidth * scale, img.shape[2]])) enlargedImg = np.empty(enlargedShape, dtype=np.uint8) enlargedHeight, enlargedWidth = util.get_image_dimensions(enlargedImg) rowScale = float(imHeight) / float(enlargedHeight) colScale = float(imWidth) / float(enlargedWidth) for row in range(enlargedHeight): for col in range(enlargedWidth): oriRow = row * rowScale # Find position in original image oriCol = col * colScale enlargedImg[row, col] = self.get_bilinear_pixel_interpolation( img, oriCol, oriRow) return enlargedImg
def create_gaussian_kernel(filter_size, sigma): """ Creates a 2D gaussian kernel using filter_size and sigma """ filter_size = util.format_filter_size(filter_size) ax = np.linspace(-(filter_size - 1) / 2., (filter_size - 1) / 2., filter_size) xx, yy = np.meshgrid(ax, ax) kernel = np.exp(-0.5 * (np.square(xx) + np.square(yy)) / np.square(sigma)) return kernel / np.sum(kernel)
def adjust_brightness(img, br): """ 0 < br < 1: decrease brightness br = 1: no changes br >: increase brightness """ height, width = util.get_dimensions(img) obtained = np.zeros((height, width, 3), np.uint8) for i in range(height): for j in range(width): for k in range(img.shape[2]): b = img[i][j][k] * br if b > 255: b = 255 obtained[i][j][k] = b return obtained.astype(np.uint8)
def get_nearest_neighbour_pixel_interpolation(self, img, posX, posY): out = [] # Get integer parts of positions modXi = int(posX) modYi = int(posY) # Get fractional parts of positions modXf = posX - modXi modYf = posY - modYi # To avoid going over image bounderies height, width = util.get_image_dimensions(img) modXiPlusOneLim = min(modXi + 1, width - 1) modYiPlusOneLim = min(modYi + 1, height - 1) for channel in range(img.shape[2]): target = img[modYi, modXi, channel] out.append(int(target + 0.5)) return out
def add_background(background, img, coord=(0, 0)): img = img_as_ubyte(img) x_size, y_size = util.get_image_dimensions(img) (y_begin, x_begin) = coord x_end = x_begin + x_size y_end = y_begin + y_size background_crop = background[ x_begin:x_end, y_begin:y_end, :] pixel_preserve = (img[:, :, 3] > 10) background_crop[pixel_preserve] = img[pixel_preserve] background[x_begin:x_end, y_begin:y_end, :] = background_crop return background
def apply_sobel(img): # Horizontal sobel matrix horizontal = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) # Vertical sobel matrix vertical = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]]) height, width = util.get_dimensions(img) # define images with 0s new_horizontal_image = np.zeros((height, width), np.uint8) new_vertical_image = np.zeros((height, width), np.uint8) new_gradient_image = np.zeros((height, width), np.uint8) if len(img.shape) == 2: # # define images with 0s # new_horizontal_image = np.zeros((height, width), np.uint8) # new_vertical_image = np.zeros((height, width), np.uint8) # new_gradient_image = np.zeros((height, width), np.uint8) for i in range(1, height - 1): for j in range(1, width - 1): horizontal_grad = ImageFilter.apply_gradient_core( horizontal, img, i, j) new_horizontal_image[i - 1, j - 1] = abs(horizontal_grad) vertical_grad = ImageFilter.apply_gradient_core( vertical, img, i, j) new_vertical_image[i - 1, j - 1] = abs(vertical_grad) # Edge Magnitude new_gradient_image[i - 1, j - 1] = np.sqrt( pow(horizontal_grad, 2.0) + pow(vertical_grad, 2.0)) else: R = ImageFilter.apply_sobel(img[:, :, 0]) G = ImageFilter.apply_sobel(img[:, :, 1]) B = ImageFilter.apply_sobel(img[:, :, 2]) output = np.zeros((R.shape[0], R.shape[1], 3), dtype=np.uint8) output[:, :, 0] = R output[:, :, 1] = G output[:, :, 2] = B new_gradient_image = output return new_gradient_image
def apply_piecewise_linear(img, coordinates_x, coordinates_y): """Apply Piecewise Linear filter on an image basead on an group of coordinates. Parameters ---------- img : numpy array The target image where the filter would be applied coordinates_x : array The coordinates X from all points to the interpolated already in the desired order. coordinates_y : array The coordinates Y from all points to the interpolated already in the desired order. Returns ------- numpy array an array representing the obtained image after apply the filter """ x = np.array(range(0, _MAX_PIXEL + 1), dtype=np.uint8) interp = np.interp(x, coordinates_x, coordinates_y) obtained = img.copy() height, width = util.get_dimensions(obtained) if len(img.shape) == 2: for i in range(height): for j in range(width): index = int(np.round(obtained[i][j])) obtained[i][j] = interp[index] else: R = ImageFilter.apply_piecewise_linear(img[:, :, 0], coordinates_x, coordinates_y) G = ImageFilter.apply_piecewise_linear(img[:, :, 1], coordinates_x, coordinates_y) B = ImageFilter.apply_piecewise_linear(img[:, :, 2], coordinates_x, coordinates_y) output = np.zeros((R.shape[0], R.shape[1], 3), dtype=np.uint8) output[:, :, 0] = R output[:, :, 1] = G output[:, :, 2] = B obtained = output return obtained
def adjust_hue (img, factor): ''' Adjust image hue using a mulplication factor. Input: image and factor in [0.0, 1.0]. Output: image with hue adjusted ''' height,width = util.get_dimensions(img) obtained = np.zeros_like(img) for row in range(height): for col in range(width): r = img[row][col][0] g = img[row][col][1] b = img[row][col][2] h,s,i = converter.rgb_to_hsi(r,g,b) new_hue = h * factor #Hue value is [0, 360] if new_hue > 360: new_hue = 360 r,g,b = converter.hsi_to_rgb(new_hue,s,i) obtained[row][col][0] = r obtained[row][col][1] = g obtained[row][col][2] = b return obtained
def adjust_intensity (img, factor): ''' Adjust image hue using a mulplication factor. Input: image and factor in [0.0, 1.0]. Output: image with intensity adjusted ''' height,width = util.get_dimensions(img) obtained = np.zeros_like(img) for row in range(height): for col in range(width): r = img[row][col][0] g = img[row][col][1] b = img[row][col][2] h,s,i = converter.rgb_to_hsi(r,g,b) new_intensity = i * factor #Intensity value is [0, 1] if new_intensity > 1: new_intensity = 1 r,g,b = converter.hsi_to_rgb(h,s,new_intensity) obtained[row][col][0] = r obtained[row][col][1] = g obtained[row][col][2] = b return obtained
def openImage(self, image): img = util.read_image(image) if len(img.shape) == 2: img = converter.rgb_to_gray(self.original_image) return img
def get_arithmetic_mean(neighbors): sum_value = np.sum(neighbors) height, width = util.get_dimensions(neighbors) return sum_value / (height * width)
def test_format_negative_size(): original_size = -5 expected = 3 obtained = util.format_filter_size(original_size) assert obtained == expected
def test_format_odd_size(): original_size = 7 expected = original_size obtained = util.format_filter_size(original_size) assert obtained == expected
def test_format_even_size(): original_size = 4 expected = original_size + 1 obtained = util.format_filter_size(original_size) assert obtained == expected
def test_format_min_size(): original_size = 3 expected = 3 obtained = util.format_filter_size(original_size) assert obtained == expected
def test_format_low_positive_size(): original_size = 1 expected = 3 obtained = util.format_filter_size(original_size) assert obtained == expected
def test_format_size_zero(): original_size = 0 expected = 3 obtained = util.format_filter_size(original_size) assert obtained == expected
def get_geometric_mean(matrix): prod_value = np.prod(matrix) height, width = util.get_dimensions(matrix) counter = height * width result = prod_value**(1.0 / counter) return np.around(result, decimals=3)