Just out of curiosity, I was playing with RGB coordinates and pixels of pictures. Then for some reason I decided to get all pixels of a picture, get the RGB coordinates/values of each pixel (eg. RGB(120, 30, 15)), add the coordinates together (eg. 120+30+15=165), and then sort the pixels in ascending order according to that number (the sum of the pixel's RGB coordinates/values).

So, to be able to visualize that, I "printed" the pixels to another image of the same dimensions as the original one, but with the re-arranged pixels as content. See an example below (and the Ruby code for it).

You will notice that the output picture has a very well defined pattern. I tried the same thing (re-arranging the pixels by R+G+B) with many different pictures, and there's always a similar pattern of repeating smaller versions of the same picture.

Why does that happen? What explains the pattern of the picture when the pixels are re-arranged?

Original picture: enter image description here

Picture with re-arranged pixels: enter image description here

# Ruby code
require 'rmagick'
include Magick

img = ImageList.new("images/test-image.jpg")
pixels = img.get_pixels(0,0,img.columns,img.rows)

# Sort pixels by total intensity
pixels = pixels.sort {|p| p.red + p.green + p.blue}

out_img = Magick::Image.new(img.columns, img.rows)
out_img.store_pixels(0,0, img.columns, img.rows, pixels)

@cthom06 figured it out in the comments. The above code is using sort instead of sort_by to sort the pixels array. Still curious about what sort is doing.

Someone answered the question over at dsp: How would you interpret the pattern in this picture? (generated by re-sorting pixels based on their RGB value)

When using sort_by, the output image looks like this: enter image description here

  • Wow, very cool. But what exactly do you mean by sorting and "printing"? By sorting the pixels by R+G+B, you get a "one-dimensional" ordering, don't you? But the picture is a two-dimensional array of pixels. So how are the pixels thrown back onto this array? – Kahovius Aug 13 '19 at 22:23
  • i'd like to see the used algorithm. logically, all same colored pixels should be adjacent, which they are not in your output. – ths Aug 13 '19 at 22:41
  • @Kahovius you are correct, the pixels are sorted in an array. Then the pixels are written out in order, using the same dimensions as the original file. So for example if the original file was 1024x768 pixels, then at the end I would have an array of 786,432 pixels, sorted by R+G+B, and then they would be written out starting at the top left of the image, 1024 pixels at a time (per row), 768 times. It's all done pretty automatically by the Ruby libraries. Code below. – Nico Brenner Aug 13 '19 at 23:05
  • 1
    @NicoBrenner im not confident in ruby, but i think you are using sort incorrectly. the docs say the order function should take two args. Did you want sort_by? – cthom06 Aug 13 '19 at 23:47
  • 1
    Since your problem appears to be associated with misuse of sort, perhaps code review would be helpful. – xiota Aug 14 '19 at 3:46