Simple Pixel Sorter - Grey Screen Only?

Dear All,

I’m trying to experiment with very simple pixel sorter. My code has been sourced from The Coding Train. I plug it into Processing 4, and have adjusted the screen size for the image which is 600 x 400 pixels. Nothing is happening on my screen and I get a grey rectangle. Can anyone help me with this beginner issue? I would like to take the base code and learn how to do other things but I can’t get past step one… :face_with_diagonal_mouth:

PImage img;
PImage sorted;

void setup() {
  size(600, 300);
  
  img = loadImage("freud600400.jpg");
  sorted = img.get();
  sorted.loadPixels();

  // Selection sort!
  for (int i = 0; i < sorted.pixels.length; i++) {
    float record = -1;
    int selectedPixel = i;
    for (int j = i; j < sorted.pixels.length; j++) {
      color pix = sorted.pixels[j];
      // Sort by hue
      float b = hue(pix);
      if (b > record) {
        selectedPixel = j;
        record = b;
      }
    }

    // Swap selectedPixel with i
    color temp = sorted.pixels[i];
    sorted.pixels[i] = sorted.pixels[selectedPixel];
    sorted.pixels[selectedPixel] = temp;
  }

  sorted.updatePixels();
}

void draw() {
  background(0);
  image(img, 0, 0);
  image(sorted, 300, 0);
}
1 Like

If the original image is greyscale then nothing will happen because the hue of any shade of grey including white and black is 0.0

Your code works for a colour image :+1:

img0

img1

Welcome to the forum :smile:

1 Like

Thanks for the quick reply! I am using an RGB image and I even tried the jpg provided on the Coding Train. Maybe the problem is my computer? I’m on a Mac…This is really puzzling :frowning_with_open_mouth:

This is my jpeg, pixel size is 600 by 400:

Freud600400

And this is the screen I get:

I used your image and your code and ran it on my iMac and it worked see the image below.

I have a reasonably powerful machine and it still took 159s for the result to appear which is not surprising because

  1. the array has 240000 elements
  2. the selection sort is a n^2 algorithm and for this size array would require 28.8 billion comparisons

So although it works I suggest that you look for another sort algorithm e.g. Quicksort.

3 Likes

Hmmm…interesting. Thank you so much for running it. I left it for about 10 mins and then I got the spinning colour wheel of death. Thanks again. :grinning:

OK the sketch code below does the same as your code but rather than use your own sort algorithm it uses one supplied by Java.

I got the same visual output but it took just 0.1 second instead of 159 seconds :smile: Another advantage is that it makes it easy to sort by other criteria.

Some of the code will be very new to you but most of it can be used without any changes. If you have questions about the code then ask here.

import java.util.Arrays;

PImage img, sorted;

void setup() {
  size(600, 800);
  img = loadImage("plants.jpeg"); // replace with your filename
  sorted = img.get();
  int time = millis();
  sortOnValue(sorted);
  println((millis() - time) + "ms");
}

void draw() {
  background(0);
  image(img, 0, 0);
  image(sorted, 0, 400);
  noLoop();
}

/*
 This calculates the sorting value for each pixels and then
 rearranges the pixels in sorted order.
 */
void sortOnValue(PImage img) {
  img.loadPixels();
  int[] array = img.pixels;
  int len = array.length;
  // Create the array that will be sorted
  Pixel[] arrayForSorting = new Pixel[len];
  for (int i = 0; i < len; i++) {
    // Changing the next line allows the user to sort by different criteria
    float sortValue = hue(array[i]);  // use hue as the sort criteria
    arrayForSorting[i] = new Pixel(array[i], sortValue);
  }
  // Sort the array
  Arrays.sort(arrayForSorting);
  // Store the sorted pixel colours
  for (int i = 0; i < len; i++) {
    array[i] = arrayForSorting[i].clr;
  }
  img.updatePixels();
}

/*
 This class stores the pixel colour value and a computed value
 for sorting.
 */
class Pixel implements Comparable {

  int clr; // Pixel colour
  float sortValue;

  Pixel(int clr, float sortValue) {
    this.clr = clr;
    this.sortValue = sortValue;
  }

  int compareTo(Object obj) {
    float osv = ((Pixel)obj).sortValue;
    return sortValue > osv ? -1 : sortValue < osv ? +1 : 0;
  }
}
3 Likes

Amazing - thank you :partying_face:

Hello,

Adding to the topic…

I found this reference useful in understanding and explaining the Comparable and Comparator interfaces:

:)