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.
Index › counting colors
 Pages: 1
 jazzpower counting colors Jun 9th, 2010, 11:33pm   Hey guys, i had to create a new account. My last one (jazz) didnt work anymore anyway, i have a little question, i am writing a program to calculate the average color of a webcam image. i will show you how i did that... Code:``` for (int i = 0; i < myCapture.pixels.length; i++) { r+= red(myCapture.pixels[i]); g+= green(myCapture.pixels[i]); b+= blue(myCapture.pixels[i]); } r= r/myCapture.pixels.length; g= g/myCapture.pixels.length; b= b/myCapture.pixels.length; average = color(r,g,b); ```this works fine, but i always get a brownish grey color. Ok, i know why, because i am calculating the average but i thought maybe it makes more sense to get the color that appears most often to get a nice color out of an image. but i have no idea how i could do that. i can not create an array for every 16.mil color available and count it up if it exists. what would be the best way to do it ? any ideas ?Thank you alot!
 PhiLho Re: counting colors Reply #4 - Jun 10th, 2010, 5:47am   OK, here is another approach. Code:```final int GRANULARITY = 16;class SmallColor{ final int r; final int g; final int b; SmallColor(int pr, int pg, int pb) { r = pr; g = pg; b = pb; } color GetColor() { return color(r, g, b); } int hashCode() { return (r * GRANULARITY + g) * GRANULARITY + b; } boolean equals(Object o) { SmallColor sc = (SmallColor) o; return r == sc.r && g == sc.g && b == sc.b; }}void setup(){ size(500, 500); background(255); println(GRANULARITY); colorMode(RGB, GRANULARITY); HashMap colors = new HashMap(GRANULARITY * GRANULARITY * GRANULARITY); PImage img = loadImage("D:/Dev/PhiLhoSoft/images/map.jpg"); image(img, 0, 0); for (int i = 0; i < img.pixels.length; i++) { SmallColor sc = new SmallColor( (int) red(img.pixels[i]), (int) green(img.pixels[i]), (int) blue(img.pixels[i])); Integer frequency = (Integer) colors.get(sc); if (frequency == null) { // Not in map yet Integer value = Integer.valueOf(1); colors.put(sc, value); } else { Integer value = Integer.valueOf(1 + frequency); colors.put(sc, value); } } int colorNb = colors.size(); println(colorNb + " colors ranges found"); ArrayList listOfColors = new ArrayList(colors.entrySet()); Collections.sort(listOfColors, new Comparator() { public int compare(Object o1, Object o2) { Map.Entry entry1 = (Map.Entry) o1; Map.Entry entry2 = (Map.Entry) o2; int val1 = (Integer) entry1.getValue(); int val2 = (Integer) entry2.getValue(); if (val1 == val2) return 0; if (val1 < val2) return 1; return -1; } }); final int diam = 20; noStroke(); fill(GRANULARITY); rect(width - 2 * diam, 0, 2 * diam, height); for (int i = 0; i < 10; i++) { Map.Entry me = (Map.Entry) listOfColors.get(i); SmallColor top = (SmallColor) me.getKey(); println((Integer) me.getValue() + " " + hex(top.GetColor())); fill(top.GetColor()); ellipse(width - diam, diam + i * diam * 2, diam, diam); }} ```I let Processing to do the color range reduction, you change the granularity to have broader or narrower ranges.
 toxi Re: counting colors Reply #5 - Jun 13th, 2010, 4:24pm   Hey, for sake of completeness (and since you mentioned my color lib earlier anyway), here's another old demo using toxiclibs (also supports tolerances): Code:```/** * RGBColorHistogram demo * @author toxi * * Dependencies: toxiclibscore-0015, colorutils-0003 * (or newer, available from: http://toxiclibs.org/ ) */import toxi.color.*;import toxi.math.*;void setup() {  size(1280,640);  background(255);  noStroke();  // load & show image  PImage img=loadImage("test2.jpg");  image(img,0,0);  // creates histogram:  // using only half the pixels (to retrieve cols from)  // 10% tolerance for grouping colors  // grouped colors are blended to form an average  ArrayList hist=createHistogramFromImage(img.pixels, img.pixels.length/2, 0.1, true);  // render histogram  float x=0;  float w=(float)width/hist.size();  for(Iterator i=hist.iterator(); i.hasNext() && x i=srcCols.iterator(); i.hasNext();) {    TColor c=i.next();    HistEntry existing=null;    for(Iterator j=hist.iterator(); j.hasNext();) {      HistEntry e=j.next();      if (e.col.distanceToRGB(c)maxFreq) maxFreq=existing.freq;    }    else {      hist.add(new HistEntry(c));    }  }  Collections.sort(hist);  // rescale frequencies  maxFreq=1f/srcCols.size();  for(Iterator i=hist.iterator(); i.hasNext();) {    HistEntry e=(HistEntry)i.next();    e.freq*=maxFreq;  }  return hist;}/** * A single histogram entry, a coupling of color & frequency * Implements a comparator to sort histogram entries based on freq. */class HistEntry implements Comparable {  float freq;  TColor col;  HistEntry(TColor c) {    col=c;    freq=1;  }  int compareTo(Object e) {    return -(int)(freq-((HistEntry)e).freq);  }  public String toString() {    return col.toHex()+": "+freq;  }} ```