Changing webcam-pixels to "nearest" color from color palette array

@jeremydouglass the beads should not be tracked as objects. What I want to do is to have a webcam be placed looking down on a perler bead and send an image with the correct colors to Runway to do SPADE-COCO generation, see https://github.com/runwayml/processing-library

So essentially what I want to do is change the colors of the picture, so that each bead (as seen through the webcam) gets converted into the nearest color from a predefined color palette. No tracking or anything like that.

This is what I have so far, and it is pretty decent, thanks for the help to @kll , but I am still sure there could be improvements? Speed is not the most important thing, it is more important to make it robust to light/shade/reflections thing things around it etc as you also mention.

import processing.video.*;
Capture video;

boolean applyBlur = true;
boolean findClosestColor = true;

color[] myColors = {
  #B8B1A6, 
  #273E56, 
  #334039, 
  #987113, 
  #5D0F12
};

void setup() {
  size(640, 360, P2D);
  video = new Capture(this, width, height);
  video.start();
}

void draw() {
  if (video.available()) {
    video.read();
  }
  if (applyBlur) video.filter(BLUR, 5.0);
  image(video, 0, 0);

  if (findClosestColor) {
    loadPixels();
    int count = width * height;
    for (int i = 0; i < count; i++) {
      color c = pixels[i];
      pixels[i] = color(closestColor(c));
    }
    updatePixels();
  } 
  fill(255);
  text("press 'b' to toggle blur and 'c' to toggle closestColor", 10, 10);
}

color closestColor(color c) {
  float recordDistance = 10000000;
  int index = 0;

  for (int i = 0; i<myColors.length; i++) {
    if (colorDistanceRGB(c, myColors[i]) < recordDistance) {
      recordDistance = colorDistanceRGB(c, myColors[i]);
      index = i;
    }
  }
  color returnColor = myColors[index];
  return returnColor;
}

float colorDistanceRGB(color a, color b) {
  float redDiff = red(a) - red(b);
  float grnDiff = green(a) - green(b);
  float bluDiff = blue(a) - blue(b);
  return sqrt( sq(redDiff) + sq(grnDiff) + sq(bluDiff) );
}

void keyPressed() {
  switch(key) {
  case 'b':
    applyBlur = !applyBlur;
    break;
  case 'c': 
    findClosestColor = !findClosestColor;
    break;
  }
}

1 Like