You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
3.2 KiB
Python

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]]