@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;
}
}