August 2nd, 2010 - Code!

I have been writing some code to get this concept working and I have a prototype. The code takes the live video input from a camera and measures each pixel against a .csv file filled with RGB goodness.

The algorithm is very simple so that we can maintain a high framerate when running the sketch. I am using RGB colors and presorting them into a list. Ryan does the measurement to LAB and then does a conversion to RGB. I take the list and put it in a .csv file then I run this command on it so it sorts the list.

sort -g -n -r -t ',' -k 1,1 myfile.csv

Then I am calculating the distance from the Red value of the pixel from the camera to the nearest red value in the list of colors.

Why did I do this? Well, RGB is the native format for the hardware. I did a rough calculation and if we run the simulation at 30fps at 640×480 we do about 10,000,000 calculations per second. Every conversion we do from one representation to the next is going to multiply this number, as does the number of colors we compare. If we choose 100 colors then we do 1,000,000,000 calculations a second and then if we do color conversion we do about 4 times that much… it could get hairy.

I have included a small .csv file below that contains a subset. If you download the Processing code below you will need to call this set smallset.csv.


227,194,46
221,159,57
216,120,61
190,144,132
190,80,97
187,81,136
176,52,66
147,181,61
119,87,74
118,128,177
97,65,113
92,183,168
91,113,70
83,124,157
62,144,71
56,102,174
38,79,152

import processing.video.*;

int numberOfColors;
color mycolors[] ;
int numPixels;
Capture video;

void setup() {
  size(640, 480,P3D); // Change size to 320 x 240 if too slow at 640 x 480
  strokeWeight(5);
  // Uses the default video input, see the reference if this causes an error
  video = new Capture(this, width, height, 24);
  numPixels = video.width * video.height;

  loadColors("smallset.csv");

  noCursor();
  smooth();
}

void draw() {

  if (video.available()) {
    background(0);
    video.read();
    video.loadPixels();

    loadPixels();

    for (int i = 0; i < numPixels; i++) {

     float measure = red(video.pixels[i]);
     int whichcolor = 0;
       for (int j = 0 ; j < mycolors.length; j++){
         if(measure <= red(mycolors[j]) ){
             whichcolor++;
         }
         else{
                pixels[i] = mycolors[whichcolor];
                break;
         }
       }//iterate through colors

    }// iterate through pixels

    updatePixels();

  }// if video available
}

void loadColors(String filename){
  // laod the csv file
  String[] lines = loadStrings(filename);
  // one color per line so use that to set the length of destination color array
  mycolors = new color[lines.length];

  for ( int i = 0 ; i < lines.length; i++){
    String[] rgbvals = split(lines[i], ',');
    // assume it all worked out and there are only 3 values per row
    // no alpha or b/w pixels for now
    mycolors[i] = color ( int(rgbvals[0]) , int(rgbvals[1]) , int(rgbvals[2]) );
  }
}

Write a Comment