diff --git a/ImageProcessor.py b/ImageProcessor.py new file mode 100644 index 0000000..3b7f71a --- /dev/null +++ b/ImageProcessor.py @@ -0,0 +1,119 @@ +import cv2 +import random + + +def glitchsort(filename: str, outputname: str, lower_canny: int=100, higher_canny: int=200, sorting_length=0, vertical: bool=True): + """ + Wrapper function for glitchsort_x and glitchsort_y + :param filename: + :param outputname: + :param lower_canny: + :param higher_canny: + :param sorting_length: + :param vertical: + :return: + """ + new_img = None + if vertical: + new_img = __glitchsort_x(filename, lower_canny, higher_canny, sorting_length) + else: + new_img = __glitchsort_y(filename, lower_canny, higher_canny, sorting_length) + + print("Writing output...") + cv2.imwrite(outputname, new_img) + print("Done!") + + +def __glitchsort_x(filename: str, lower_canny: int=100, higher_canny: int=200, sorting_length=0): + """ + Apply pixel sorting to the given image using canny edge detection to stop sorting. + + Sorting length varies a bit averaging around sorting_length (0 for endless) + :param filename: + :param lower_canny: + :param higher_canny: + :param sorting_length: + :return: + """ + img = cv2.imread(filename) + width, height, depth = img.shape + canny = cv2.Canny(img, lower_canny, higher_canny) + + new_img = img.copy() + + print("Sorting...") + for x in range(width): # search for first edge + for y in range(height): + if canny[x, y] == 255: + length = int(sorting_length+random.randint(-1, 1)*0.3) + + pixelsort(img, new_img, x, y, dx=0, dy=-1, length=length) + continue + + return new_img + + +def __glitchsort_y(filename: str, lower_canny: int=100, higher_canny: int=200, sorting_length=0): + """ + Apply pixel sorting to the given image using canny edge detection to stop sorting. + + Sorting length varies a bit averaging around sorting_length (0 for endless) + :param filename: + :param lower_canny: + :param higher_canny: + :param sorting_length: + :return: + """ + img = cv2.imread(filename) + width, height, depth = img.shape + canny = cv2.Canny(img, lower_canny, higher_canny) + + new_img = img.copy() + + print("Sorting...") + for y in range(height): # search for first edge + for x in range(width): + if canny[x, y] == 255: + length = int(sorting_length+random.randint(-1, 1)*0.3) + + pixelsort(img, new_img, x, y, dx=-1, dy=0, length=length) + continue + + return new_img + + +def pixelsort(img, new_img, x, y, dx=0, dy=1, length=-1): + """ + Pixelsort from point (x,y) in direction (dx,dy) for length long (-1 means until end of picture). + + :param img: + :param new_img: + :param x: + :param y: + :param dx: + :param dy: + :return: + """ + assert(dx != 0 or dy != 0) + + width, height, depth = img.shape + + pixels = [] + todo = length + while todo is not 0: + pixels.append([x, y]) + x += dx + y += dy + todo -= 1 + + if x >= width or x <= 0 or y >= height or y <= 0: # ran out of bounds + break + + + def get_value(pixel): + return img[pixel[0], pixel[1], 0] + + sorted_pixels = sorted(pixels, key=get_value) + + for i in range(len(pixels)): + new_img[pixels[i][0], pixels[i][1]] = img[sorted_pixels[i][0], sorted_pixels[i][1]] diff --git a/__main__.py b/__main__.py new file mode 100644 index 0000000..f8ea678 --- /dev/null +++ b/__main__.py @@ -0,0 +1,40 @@ +import ImageProcessor +import sys + +def print_usage(): + print(""" + Usage: {0} [sorting length] [sorting axis] + + Sorts pixel rows/collumns of the given image . + Each line of sorted pixels is [sorting_length] long and defaults to 0 for stopping at the picture ends. + [Sorting axis] toggles on which axis the sorting is done. Defaults to vertical. + """.format(sys.argv[0])) + + +if len(sys.argv) < 2: + print_usage() + exit(0) +if sys.argv[1] == "-h": + print_usage() + exit(0) + +input_file = sys.argv[1] +output_file = sys.argv[2] +sorting_length = 0 if len(sys.argv) < 4 else sys.argv[3] +sort_direction = True if len(sys.argv) < 5 else sys.argv[4] + + +assert(isinstance(input_file, str)) +assert(isinstance(output_file, str)) +assert(isinstance(sorting_length, int) and sorting_length >= 0) +assert(isinstance(sort_direction, bool) or isinstance(sort_direction, str)) + +if sort_direction.lower() == "true": + sort_direction = True +elif sort_direction.lower() == "false": + sort_direction = False +else: + print("Did not recognize parameter [sorting axis]! Defaulting to True for vertical.") + sort_direction = True + +ImageProcessor.glitchsort(input_file, output_file, sorting_length, sort_direction)