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