Pixelsorting using Canny Edge detection
Using summed up pixel values and canny edge detection as key and border for pixelsort.master
parent
b07c795be8
commit
78189e4b1d
@ -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]]
|
@ -0,0 +1,40 @@
|
|||||||
|
import ImageProcessor
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def print_usage():
|
||||||
|
print("""
|
||||||
|
Usage: {0} <image> <destination> [sorting length] [sorting axis]
|
||||||
|
|
||||||
|
Sorts pixel rows/collumns of the given image <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)
|
Loading…
Reference in New Issue