GithubHelp home page GithubHelp logo

pixelsort's Introduction

pixelsort

What is Pixel Sorting?

Have a look at this post or /r/pixelsorting

Dependencies

Should work in both Python 2 and 3, but Python 3 is recommended.

Usage

From the command line:

pip install pixelsort
python3 -m pixelsort %PathToImage% [options]

Tip: To replicate Kim Asendorf's original processing script, first sort vertically and then horizontally in threshold (default) mode:

python3 -m pixelsort %PathToImage% -a 90
python3 -m pixelsort %PathToSortedImage%

As a package:

>>> from pixelsort import pixelsort
>>> from PIL import Image
>>> a = Image.open("examples/image.jpg")
>>> a
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=576x324 at 0x7F8F6A2AC208>
>>> pixelsort(a)
<PIL.Image.Image image mode=RGBA size=576x324 at 0x7F8F66AA57B8>

Parameters:

Parameter Flag Description
Interval function -i Controls how the intervals used for sorting are defined. See below for more details and examples. Threshold by default.
Output path -o Path of output file. Uses the current time for the file name by default.
Randomness -r What percentage of intervals not to sort. 0 by default.
Threshold (lower) -t How dark must a pixel be to be considered as a 'border' for sorting? Takes values from 0-1. 0.25 by default. Used in edges and threshold modes.
Threshold (upper) -u How bright must a pixel be to be considered as a 'border' for sorting? Takes values from 0-1. 0.8 by default. Used in threshold mode.
Char. length -c Characteristic length for the random width generator. Used in mode random and waves.
Angle -a Angle at which you're pixel sorting in degrees. 0 (horizontal) by default.
External interval file -f Image used to define intervals. Must be black and white.
Sorting function -s Sorting function to use for sorting the pixels. Lightness by default.
Mask -m Image used for masking parts of the image.
Logging level -l Level of logging statements made visible. Choices include DEBUG, INFO, WARNING, ERROR, and CRITICAL. WARNING by default.

Interval Functions

Interval function Description
random Randomly generate intervals. Distribution of widths is linear by default. Interval widths can be scaled using char_length.
edges Performs an edge detection, which is used to define intervals. Tweak threshold with threshold.
threshold Intervals defined by lightness thresholds; only pixels with a lightness between the upper and lower thresholds are sorted.
waves Intervals are waves of nearly uniform widths. Control width of waves with char_length.
file Intervals taken from another specified input image. Must be black and white, and the same size as the input image.
file-edges Intevals defined by performing edge detection on the file specified by -f. Must be the same size as the input image.
none Sort whole rows, only stopping at image borders.

Sorting Functions

Sorting function Description
lightness Sort by the lightness of a pixel according to a HSL representation.
hue Sort by the hue of a pixel according to a HSL representation.
saturation Sort by the saturation of a pixel according to a HSL representation.
intensity Sort by the intensity of a pixel, i.e. the sum of all the RGB values.
minimum Sort on the minimum RGB value of a pixel (either the R, G or B).

Examples

python3 -m pixelsort examples/image.jpg -i random -c 20

random

python3 -m pixelsort examples/image.jpg -i edges -t .5

edges

  • file: Intervals taken from image specified with -f. Must be black and white.

python3 -m pixelsort examples/image.jpg -i file -f examples/intervals.png

file

(generated with elementary-ca)

file

  • mask: Mask taken from image specified with -m. Must be black and white.

python3 -m pixelsort examples/image.jpg -i random -c 20 -m examples/mask.png

file

file

Todo

  • Allow defining different intervals for different channels.

Based on https://gist.github.com/prophetgoddess/667c5554e5d9d9a25ae6

pixelsort's People

Contributors

abetusk avatar bernardzhao avatar casperkoning avatar delucks avatar dolorosus avatar madfatvlad avatar monuszko avatar reticivis-net avatar satyarth avatar thatch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pixelsort's Issues

maximum is completely redundant

While experimenting with pixelsort, I found that some sorting methods (-s) produce very similar results. Intensity is very similar to lightness, but it is actually different' so it's not too bad. maximum is much worse.

On all images I've tried, maximum produced identical output to lightness (default). This is easiest to observe if you run the app with none interval method, because it always behaves the same:

python3 pixelsort.py image.jpg -o test.png -i none -s maximum
python3 pixelsort.py image.jpg -o test.png -i none

Digging into it, I read the Wikipedia article on HSV colorspace. "Lightness" sorting method actually returns the "value" of HSV colorspace. "maximum" sorting method of the app takes max(pixel[0], pixel[1], pixel[2]). But how is "lightness" defined in HSV ?

"In the HSV "hexcone" model, value is defined as the largest component of a color, our M above"
https://en.wikipedia.org/wiki/HSL_and_HSV#Lightness

What is "M" ?

M = max(R, G, B)
https://en.wikipedia.org/wiki/HSL_and_HSV#Hue_and_chroma

So, unless I'm missing something, maximum and lightness look identical to me because they are identical, to the point of having the same definition!

Rotation sorting issue

While trying to use the angle parameter, I've noticed that the pixels don't all stay together in the original dimensions during the sorting:

  • Immediately after rotation:
    1
  • After sorted pixels are placed:
    2
    This causes the result image, after it is rotated back, to have some blank pixels. The sorting seems to be chopping up the right side of the image in a patter, which if I had to guess has to do with the intervals spanning over into areas with no real pixels.

Crash when trying to pixelsort vertically

$ python3 pixelsort.py -a 90 examples/file.png 
Interval function:  threshold
Lower threshold:  0.25
Upper threshold:  0.8
Randomness:  0 %
Opening image...
Converting to RGBA...
Rotating image...
Getting data...
Getting pixels...
Determining intervals...
Defining intervals...
Sorting pixels...
Placing pixels in output image...
Rotating output image back to original orientation...
Crop image to apropriate size...
Saving image...
Traceback (most recent call last):
  File "pixelsort.py", line 56, in <module>
    main()
  File "pixelsort.py", line 50, in main
    output_img.save(argparams.output_image_path)
  File "/usr/lib/python3/dist-packages/PIL/Image.py", line 1646, in save
    self.load()
  File "/usr/lib/python3/dist-packages/PIL/Image.py", line 1961, in load
    self.im = self.im.crop(self.__crop)
TypeError: integer argument expected, got float

Missing files in sdist

It appears that the manifest is missing at least one file necessary to build
from the sdist for version 1.0.1. You're in good company, about 5% of other
projects updated in the last year are also missing files.

+ /tmp/venv/bin/pip3 wheel --no-binary pixelsort -w /tmp/ext pixelsort==1.0.1
Looking in indexes: http://10.10.0.139:9191/root/pypi/+simple/
Collecting pixelsort==1.0.1
  Downloading http://10.10.0.139:9191/root/pypi/%2Bf/86e/c9bbddb54a6ba/pixelsort-1.0.1.tar.gz (6.2 kB)
    ERROR: Command errored out with exit status 1:
     command: /tmp/venv/bin/python3 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-wheel-rdx7czpx/pixelsort/setup.py'"'"'; __file__='"'"'/tmp/pip-wheel-rdx7czpx/pixelsort/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-wheel-rdx7czpx/pixelsort/pip-egg-info
         cwd: /tmp/pip-wheel-rdx7czpx/pixelsort/
    Complete output (5 lines):
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-wheel-rdx7czpx/pixelsort/setup.py", line 6, in <module>
        with open('requirements.txt') as fh:
    FileNotFoundError: [Errno 2] No such file or directory: 'requirements.txt'
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

column of transparent pixels

When using your program with the option -a 90, the first column of pixels is always completely transparent. This is not observed when this argument is not present (i.e. horizontal mode).

Mask is not rotated and potentially gives errors when rotate and mask are both specified

I get the following error when trying to use the mask on a rotated pixel sort image:

$ python3 pixelsort.py examples/image.jpg -i random -a 120 -c 20 -m examples/mask.png 
Traceback (most recent call last):
  File "pixelsort.py", line 81, in <module>
    main(parse_args())
  File "pixelsort.py", line 33, in main
    pixels = get_pixels(data, mask, input_img.size)
  File "pixelsort.py", line 62, in get_pixels
    if not (mask and mask[x, y] == constants.black_pixel):
IndexError: image index out of range

After adding the following line:

    mask = Image.open(args["mask"]).convert('RGBA').rotate(args["angle"], expand=True).load() if args["mask"] else None

I get the following image as I would expect:

3vxZ7

I'll submit a PR with the fix unless you get to it before I do.

Issue when using external file for intervals.

For sake of testing this, I'm trying to sort this image:
pc

Using this external interval file:
mask

The operation:
λ python pixelsort.py "pclips/pclips.png" -of pclips -a 45 -f "pclips/mask.png" -i file

Returns the following:

Interval function:  file
Randomness:  0 %
Opening image...
Converting to RGBA...
Rotating image...
Getting data...
Getting pixels...
Determining intervals...
Cleaning up edges...
Traceback (most recent call last):
  File "pixelsort.py", line 56, in <module>
    main()
  File "pixelsort.py", line 31, in main
    intervals = argparams.interval_function(pixels, argparams)
  File "C:\Users\justi\Code\pixelsort\interval.py", line 117, in file_mask
    if file_pixels[y][x] == constants.black_pixel and file_pixels[y][x - 1] == constants.black_pixel:
IndexError: list index out of range

I have also tested this on couple other bitmap mask files -- is there something I'm missing? Black pixels too close to the edge?

Extra interval function file_edges?

The README lists only 5 real interval functions, but a sixth interval function file_edges is defined in interval.py. Is this a discrepancy in the README or is this a vestigial function? This is probably more of a question for @satyarth.

Syntax warning

Hello!
If i try to run the script i get the following:

pixelsort.py:43: SyntaxWarning: "is not" with a literal. Did you mean "!="?
  if args["angle"] is not 0:

It doesn't stop the script from doing its job, though
Python version: 3.8.0

Runtime errors when trying to run examples

I'm getting SyntaxErrors when trying to run the examples with the latest build (953a38c):

$ python3 pixelsort.py examples/image.jpg -i random -c 20
Traceback (most recent call last):
  File "pixelsort.py", line 6, in <module>
    from argparams import parse_args, verify_args
  File "/home/abe/git/github/satyarth/pixelsort/argparams.py", line 88
    logging.info(f"Interval function: {args['interval_function']}")
                                                                 ^
SyntaxError: invalid syntax

It looks like spurious fs got inserted on various lines from 88 to 100.

Removing those extra characters and I can run the example files.

A pull request will follow unless you get to it before me.

Pixelsorting on Curves [Feature Request]

This is a feature request to add "curvy" pixel sorting options.

For some examples, austinhein_1 on Reddit has some posts that show the effect here and here.

In theory this should be simple to do but there are many details that might be a bit subtle. There's also the question of how to specify the curves which I don't have a good idea of what people should expect.

Algorithmic Idea

However the curve is specified, walk along the curve in the original image, filling in an array of pixels, then pixel sort as normal, providing the same threshold and sorting option as before.

The subtlety comes in doing sub pixel sampling and knowing how to sample and realize the pixels in the destination image.

Maybe I'm overthinking it and forcing the curve to only pick a single pixel at any given point, ignoring aliasing effects, is reasonable.

Curve Specification

I can think of a few different methods:

  • Algebraic: Provide an explicit equation, maybe in the form of a complex equation
  • Flow Field: Provide a file that has "velocity" (v_x,v_y) positions at key points, potentially at a lower sample rate than the input picture, and then trace curves over that flow field. This can be used in conjunction with a mask to make sure only the desired pixels get sorted
  • Normal Map: somehow use a normal map image, interpreting the (r,g,b) -> (x,y,z) normal in some way and considering it a vector/flow field (?)

There might be some subtlety here with curves needing to be non-constant width when sorting pixels, because it might be hard to find "stacked" curves that only need on pixel.


Anyway, I'm not exactly sure how to implement this but it would be a cool feature.

TypeError: 'int' object is not subscriptable

Hi
I got an error

$ python36 pixelsort.py test.png 
Interval function:  threshold
Lower threshold:  0.25
Upper threshold:  0.8
Randomness:  0 %
Opening image...
Converting to RGBA...
Rotating image...
Getting data...
Getting pixels...
Determining intervals...
Defining intervals...
Traceback (most recent call last):
  File "pixelsort.py", line 56, in <module>
    main()
  File "pixelsort.py", line 31, in main
    intervals = argparams.interval_function(pixels, argparams)
  File "/home/clone/repos/pixelsort/interval.py", line 60, in threshold
    if util.lightness(pixels[y][x]) < args.bottom_threshold or util.lightness(pixels[y][x]) > args.upper_threshold:
  File "/home/clone/repos/pixelsort/util.py", line 11, in lightness
    return rgb_to_hsv(pixel[0], pixel[1], pixel[2])[2] / 255.0  # For backwards compatibility with python2
TypeError: 'int' object is not subscriptable

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.