diff --git a/GUI.py b/GUI.py index a48cdf92c6d267de75e66d1e03e2ef19adb76cfe..df928e488b97825a2b033ce473d2621d53dc2d60 100644 --- a/GUI.py +++ b/GUI.py @@ -91,7 +91,7 @@ class GUI(object): :return: None """ self.image_path: String = askopenfilename(initialdir='/', title='Select file', - filetypes=(('jpeg files', '*.jpeg'), ('all files', '*.*'))) + filetypes=[('jpeg files', '*.jpeg'), ('jpg files', '*.jpg')]) new_image = self.read_image(self.image_path) @@ -132,6 +132,11 @@ if __name__ == '__main__': Notice: The edited image will be saved in ./images/edited.py. Each new filter will overwrite this image. This may take a while. + It is not possible to edit *.png images since they are images with size NxMx4. + If the colors should be in a certain range e.g. [0, 255] feel free to checkout Filter. + + For the edges it is proofed if the H-element is in the image. This is done because otherwise the opposite site of + the image would be relevant within the filter region. """ root = Tk() root.resizable(False, False) diff --git a/editor.py b/editor.py index 762bd6b5a03ccaa73c5d5573adbcf7910e7e8402..aa4b7cefcd6febec7150b2e9cc73e59abcbee2c2 100644 --- a/editor.py +++ b/editor.py @@ -1,4 +1,3 @@ -import copy from tokenize import String from skimage import io @@ -27,12 +26,15 @@ class Editor(object): :return: None """ image = io.imread(fname=self.image_path) - edited_image = copy.deepcopy(image) # io.imread(fname=self.image_path) - height, width, _ = image.shape - + height, width, _ = image.shape # len(image), len(image[0, 0:, 0:]) wont work for .png-images. + edited_image = np.zeros((height, width, 3), dtype=np.float64) + edited_pixels = 0 for v in range(height): for u in range(width): pixel = Pixel(image, v, u) edited_image[v, u] = pixel.filter_with(option) + edited_pixels += 1 + if edited_pixels % 10000 == 0: + print('Finished with: ' + str(edited_pixels) + ' of ' + str(width * height)) io.imsave(arr=edited_image, fname=self.edit_path) diff --git a/filter.py b/filter.py index 58ca9cfbab9a9f4f449d6191bb05a673cb430535..32a13b12263e0e7870bb7269285dd9db522125db 100644 --- a/filter.py +++ b/filter.py @@ -13,10 +13,11 @@ from mask import * class Filter(object): - def __init__(self, image: imageio.core.util.Array, v: int, u: int) -> None: + def __init__(self, image: imageio.core.util.Array, v: int, u: int, color_range: List = None) -> None: """ This class edits a pixel in a image with a given filter. + :param color_range: If the image pixel should be in a certain range e.g. [0, 255]. :param image: The image in which the filter should be used. :param v: The v coordinate :param u: The u coordinate @@ -24,6 +25,10 @@ class Filter(object): self.image = image self.v = v self.u = u + self.color_range = color_range + if color_range: + self.min_color = np.min(self.color_range) + self.max_color = np.max(self.color_range) def use(self, option: String = FILTER.empty.value, linear: bool = True, dim: Tuple = (5, 5), f: function = np.min) -> List: @@ -41,6 +46,21 @@ class Filter(object): else: return self.non_linear_filter(f, dim) + def __keep_values_in_range(self, pixel): + if pixel[COLOR.red.value] > self.max_color: + pixel[COLOR.red.value] = self.max_color + if pixel[COLOR.green.value] > self.max_color: + pixel[COLOR.green.value] = self.max_color + if pixel[COLOR.blue.value] > self.max_color: + pixel[COLOR.blue.value] = self.max_color + + if pixel[COLOR.red.value] < self.min_color: + pixel[COLOR.red.value] = self.min_color + if pixel[COLOR.green.value] < self.min_color: + pixel[COLOR.green.value] = self.min_color + if pixel[COLOR.blue.value] < self.min_color: + pixel[COLOR.blue.value] = self.min_color + def linear_filter(self, option: String) -> List: """ This method is for filtering with linear filters. @@ -50,7 +70,7 @@ class Filter(object): :return: A modified rgb-pixel """ - height_I, width_I, _ = self.image.shape + height_I, width_I, _ = self.image.shape # len(self.image), len(self.image[0, 0:, 0:]) H = np.matrix(Mask().H[option]) divider = abs(H.sum()) @@ -68,6 +88,9 @@ class Filter(object): for color in COLOR: new_pixel[color.value] += self.image[self.v + j, self.u + i, color.value] * \ np.multiply(1 / divider, H[center_j + j, center_i + i]) + + if self.color_range: + self.__keep_values_in_range(new_pixel) return new_pixel def non_linear_filter(self, f: function, dim: Tuple = (5, 5)) -> List: @@ -91,9 +114,13 @@ class Filter(object): (self.v + j >= 0) and (self.v + j <= height_I - 1): for color in COLOR: colors_neighbors[color.value] += [self.image[self.v + j, self.u + i, color.value]] - - return [ + new_pixel = [ f(colors_neighbors[COLOR.red.value]), f(colors_neighbors[COLOR.green.value]), f(colors_neighbors[COLOR.blue.value]) ] + + if self.color_range: + self.__keep_values_in_range(new_pixel) + + return new_pixel diff --git a/images/edit.jpeg b/images/edit.jpeg index 60dc966838f446baf89a8d602d08a3b0f49ceb32..ce7f832cf7933c1dc34afe7f806b9ca686956cb4 100644 Binary files a/images/edit.jpeg and b/images/edit.jpeg differ