We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › Perfect Colour sorting
Page Index Toggle Pages: 1
Perfect Colour sorting (Read 1791 times)
Perfect Colour sorting
Feb 17th, 2010, 6:01pm
 
hi i've been playing around with colour sorting.
i found the example on the site here, not to be that accurate http://processing.org/learning/libraries/colorsorting.html
due to the fact that is used the sum of all the colours ad the basis for its formula: bright[count] = r*r + g*g + b*b;

so i used real brightness. then added two more checks into the loop to sort the hue and saturations. but it still doesn't seem 100% consistent visually. i know it is ideal to do hue first, but then a darker colour would show up in the middle of the palette.

here's an example of the output:
http://radarboy.com/george/palette.jpg

i know i'm probably being anal here. if you look at the bottom there's B223 on B235 which visually seem like they should belong further up the palette. but their HSB values say otherwise.

anyway, it's not too serious. just mildly puzzling. and here's at least a class for anyone who wants to extract and sort colours....


Code:


int boxSize=40;
int numberColours=128;
SampleColour colors;
PFont font;

void setup(){
size (800,600);
stroke(255);
//noStroke();
font = loadFont("Helvetica-9.vlw");
textFont(font, 9);
colors = new SampleColour(numberColours, "v.gif");
strokeWeight(4);
showColours();
//smooth();

}

void draw(){

}

void keyPressed(){
showColours();
}


void showColours(){
println("showcolours");
background(255);
int xpos=0;
int ypos=0;

for (int i=0; i< numberColours; i++) {
if (xpos >= width) {
xpos =0;
ypos+=boxSize+40;
}

color c = colors.colourNumber[i];
fill(c);

rect(xpos,ypos,boxSize,boxSize);
fill(100);
text("B:"+int(colors.bright[i]), xpos+2, ypos+boxSize+8);
text("H:"+int(colors.hues[i]), xpos+2, ypos+boxSize+20);
text("S:"+int(colors.saturations[i]), xpos+2, ypos+boxSize+32);
xpos+=boxSize;
}

}


//============== colour sampling
// sampling adapted http://abandonedart.org/
// color sort adapted from ben fry http://processing.org/


class SampleColour {
int numberColours;
color[] colourNumber;
PImage img;
// int[] bright;
float[] bright;
float[] hues;
float[] saturations;

SampleColour(int _numberColours, String _img) {
numberColours = _numberColours;
colourNumber = new color[numberColours];
//bright = new int[numberColours];
bright = new float[numberColours];
hues = new float[numberColours];
saturations = new float[numberColours];
img = loadImage(_img);
sampleColour();

}

void sampleColour() {
image(img,0,0);
int count = 0;
for (int x=0; x < img.width; x+=2){
for (int y=0; y < img.height; y+=2) {
color c = get(x,y);
if (checkDuplicates(c, count)) {
// println("Duplicate!");
continue;

}
int r = c >> 16 & 0xff;
int g = c >> 8 & 0xff;
int b = c & 0xff;
println(r);


if (count < numberColours) {
colourNumber[count]= c;
hues[count]= hue(color(r,g,b));
saturations[count]= saturation(color(r,g,b));
// bright[count] = r*r + g*g + b*b;
bright[count] = brightness(color(r,g,b));
//bright[count] = brightness(color(r,g,b))+hues[count];
//bright[count] = brightness(color(r,g,b))+hues[count]+saturations[count];
count++;
}
}

}

sortColours(numberColours, bright, colourNumber);
//sortColours(numberColours, hues, colourNumber);
//

sortHS(saturations,hues);
sortHS(hues,bright);
//
background(255);
println(count);
println(colourNumber.length);
}



// Functions to handle sorting the color data

void sortColours(int length, float[] a, color[] stuff) {
sortSub(a, stuff, 0, length - 1);
}

void sortSwap(float[] a, color[] stuff, int i, int j) {
//int T = a[i];
float T = a[i];
a[i] = a[j];
a[j] = T;

color v = stuff[i];
stuff[i] = stuff[j];
stuff[j] = v;
}

void sortSub(float[] a, color[] stuff, int lo0, int hi0) {
int lo = lo0;
int hi = hi0;
//int mid;
float mid;

if (hi0 > lo0) {
mid = a[(lo0 + hi0) / 2];

while (lo <= hi) {
while ((lo < hi0) && (a[lo] < mid)) {
++lo;
}
while ((hi > lo0) && (a[hi] > mid)) {
--hi;
}
if (lo <= hi) {
sortSwap(a, stuff, lo, hi);
++lo;
--hi;
}
}

if (lo0 < hi)
sortSub(a, stuff, lo0, hi);

if (lo < hi0)
sortSub(a, stuff, lo, hi0);
}
}

void sortHS(float[] sortable, float[] compare){
int hCount = 0;
int startCount = 0;
for (int i=1; i< numberColours; i++){
if (compare[i-1]==compare[i]){
hCount++;
} else {
// fire this once they're differnce, so we're now looking actually at i-1
if (hCount>0){
startCount = i-1-hCount;
sortSub(sortable, colourNumber, startCount, i - 1);
hCount = 0;
}
}
}
}

boolean checkDuplicates(color _c, int _count){
int duplicates = 0;
for (int i=0; i < _count; i++) {
if (colourNumber[i] == _c) {
duplicates++;
}
}
//println ("Duplicates: "+ duplicates);
if (duplicates>0) {
return true;
}
else {
return false;
}
}
}


Re: Perfect Colour sorting
Reply #1 - Feb 17th, 2010, 6:44pm
 
you can check out eskimobloods colorlib. it has some nice colorsorting features http://code.google.com/p/colorlib/

also toxis colorutils has some "super flexible color sorting with many presets "
Re: Perfect Colour sorting
Reply #2 - Feb 18th, 2010, 3:49am
 
yea, thanks Cedric, colorLib looks cool. but a lot of the examples weren't working, will give it another bash though. this more more just an exercise in doing in myself.
Re: Perfect Colour sorting
Reply #3 - Feb 19th, 2010, 12:01pm
 
the sorting functions in eskimodblood's colorLib are based on (fragile) code i published on my blog years ago: http://toxi.co.uk/blog/2006/04/colour-code-snippets.htm

meanwhile i've developed a more comprehensive library for working with color simultaneously in multiple spaces (RGB, HSV & CMYK) and have also build an extensible system for creating and sorting lists of colors (incl. cluster sorting). The currently implemented comparators allow you to sort colors by:

* hue
* staturation
* brightness
* luminance
* alpha
* red, green, blue, cyan, magenta, yellow, black intensity
* proximity to a target color
* neighbour distance (again in RGB, HSV or CMYK space)

There're several demos bundled with the library showing how to use all these methods (and more). Have a look! Smiley

http://toxiclibs.org/

Dowload from (choose colorutils and toxiclibscore if you haven't got the latest version already):
http://code.google.com/p/toxiclibs/downloads/list
Re: Perfect Colour sorting
Reply #4 - Feb 19th, 2010, 1:28pm
 
good to know Smiley so i go with the toxiclib version if i ever need to sort some colors
Re: Perfect Colour sorting
Reply #5 - Feb 20th, 2010, 5:22am
 
Off-Topic replies have been moved to this Topic.
Re: Perfect Colour sorting
Reply #6 - Feb 23rd, 2010, 6:40am
 
Genius. Thanks Toxi. Just about to give it a spin.
cheers
Re: Perfect Colour sorting
Reply #7 - Feb 24th, 2010, 10:48pm
 
haven't dug into colorLib or toxiclibs yet, so dunno if this is addressed there, but i'm guessing you're running into issues with luma (aka luminance):
http://en.wikipedia.org/wiki/Luma_%28video%29

we humans see green more brightly than red or blue, so sorting strictly by RGB values will not necessarily give an appearance of correctly-sorted brightness.

just a guess; maybe you've already accounted for this in your code....
Re: Perfect Colour sorting
Reply #8 - Feb 24th, 2010, 11:58pm
 
you can sort by both the brightness channel of HSB/HSV or the computed luminance following CCIR 601 recommendation:

Code:
import toxi.colors.*;
import toxi.math.*;

ColorList cols=new ColorList(NamedColor.YELLOW,NamedColor.BLUE,NamedColor.GREEN);
// sorting by HSV brightness doesn't change anything in this case
// since all 3 colors have max. brightness already
cols.sortByCriteria(AccessCriteria.BRIGHTNESS,false);
// this sorts the list based on computed luma values and
// results in this order: blue, green, yellow
cols.sortByCriteria(AccessCriteria.LUMINANCE,false);


Hth!
Page Index Toggle Pages: 1