We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello, I've made this color tracker based of the Simple Color Tracking code by Daniel Shiffman, although mine tracks quite a few neighboring pixels so the tracking is beter (see attachment)
this is my code:
import processing.video.*;
Capture cam;
boolean color_selected;
int cell_width = 21;
float diffrence;
int[] Baxis = new int[cell_width];
int[] Taxis = new int[cell_width];
int[] Xaxis = new int[cell_width];
int[] Yaxis = new int[cell_width];
void setup() {
size(640, 480);
String[] cameras = Capture.list();
cam = new Capture(this, width, height, cameras[1]);
cam.start();
}
void draw() {
if (cam.available() == true) {
cam.read();
}
image(cam, 0, 0, width, height);
if (color_selected == true) {
int closestX = 0;
int closestY = 0;
float closestDiff = 1000000.0f;
for ( int x = cell_width / 2; x < cam.width - cell_width / 2; x++) {
for ( int y = cell_width / 2; y < cam.height - cell_width / 2; y++) {
for ( int i = 0; i < cell_width; i++) {
int loc = x + (cell_width / 2 - i) + y * cam.width;
color currentColor = cam.pixels[loc];
int stored_color = Xaxis[i];
float g1 = green(currentColor);
float b1 = blue(currentColor);
float r1 = red(currentColor);
float g2 = green(stored_color);
float b2 = blue(stored_color);
float r2 = red(stored_color);
diffrence += dist(r1, g1, b1, r2, g2, b2);
}
for ( int i = 0; i < cell_width; i++) {
int loc = x + (y + (cell_width / 2 - i)) * cam.width;
color current_color = cam.pixels[loc];
int stored_color = Yaxis[i];
float g1 = green(current_color);
float b1 = blue(current_color);
float r1 = red(current_color);
float g2 = green(stored_color);
float b2 = blue(stored_color);
float r2 = red(stored_color);
diffrence += dist(r1, g1, b1, r2, g2, b2);
}
for ( int i = 0; i < cell_width; i++) {
int loc = (x + (cell_width / 2 - i)) + (y + (cell_width / 2 - i)) * cam.width;
color current_color = cam.pixels[loc];
int stored_color = Taxis[i];
float g1 = green(current_color);
float b1 = blue(current_color);
float r1 = red(current_color);
float g2 = green(stored_color);
float b2 = blue(stored_color);
float r2 = red(stored_color);
diffrence += dist(r1, g1, b1, r2, g2, b2);
}
for ( int i = 0; i < cell_width; i++) {
int loc = (x + (cell_width / 2 - i)) + (y + (cell_width / 2 - (cell_width - (i + 1)))) * cam.width;
color current_color = cam.pixels[loc];
int stored_color = Baxis[i];
float g1 = green(current_color);
float b1 = blue(current_color);
float r1 = red(current_color);
float g2 = green(stored_color);
float b2 = blue(stored_color);
float r2 = red(stored_color);
diffrence += dist(r1, g1, b1, r2, g2, b2);
}
if (diffrence < closestDiff) {
closestDiff = diffrence;
closestX = x;
closestY = y;
}
diffrence = 0;
}
}
fill(255);
ellipse(closestX, closestY, 16, 16);
drawColorThing();
}
}
void drawColorThing() {
pushMatrix();
rectMode(CENTER);
translate(height/2, height/2);
rotate(PI);
for (int i = 0; i < cell_width; i++) {
fill(Xaxis[i]);
int Xax = 10 * i;
rect(Xax, cell_width/2 * 10, 10, 10);
}
for (int i = 0; i < cell_width; i++) {
fill(Yaxis[i]);
int Xax = 10 * i;
rect(cell_width/2 * 10, Xax, 10, 10);
}
for (int i = 0; i < cell_width; i++) {
int Xax = 10 * i;
int Yax = 10 * i;
fill(Taxis[i]);
rect(Xax, Yax, 10, 10);
}
for (int i = 0; i < cell_width; i++) {
int Xax = 10 * (i);
int Yax = ( cell_width * 10) - 10 * (i + 1);
fill(Baxis[i]);
rect(Xax, Yax, 10, 10);
}
popMatrix();
}
void mousePressed() {
color_selected = true;
for ( int i = 0; i < cell_width; i++) {
int loc = mouseX + (cell_width / 2 - i) + mouseY * cam.width;
Xaxis[i] = cam.pixels[loc];
}
for ( int i = 0; i < cell_width; i++) {
int loc = mouseX + (mouseY + (cell_width / 2 - i)) * cam.width;
Yaxis[i] = cam.pixels[loc];
}
for ( int i = 0; i < cell_width; i++) {
int loc = (mouseX + (cell_width / 2 - i)) + (mouseY + (cell_width / 2 - i)) * cam.width;
Taxis[i] = cam.pixels[loc];
}
for ( int i = 0; i < cell_width; i++) {
int loc = (mouseX + (cell_width / 2 - i)) + (mouseY + (cell_width / 2 - (cell_width - (i + 1)))) * cam.width;
Baxis[i] = cam.pixels[loc];
}
}
I works just fine altough very very slow expecialy when I increase the number of neighbor pixels that are being checked. So does anybody have some code optimaztions tips?
Answers
???
ahould line 122 be Yaxis?
should line 82 be Baxis?
@koogs Sorry, attachment is now attached. Line 122 was indeed meant to be Yaxis and 82 should have been Baxis. I updated the post to correct it
There are much faster ways of extracting the red, green and blue values from the pixels using bit shifting.
Also, dist uses a relatively expensive sqrt call which I don't think you need here, you can add the squares of the distances together and that'll serve just as well.
The image resize in draw is terrible too.
@koogs Thank you for the response, by the image resize you mean this line right?
image(cam, 0, 0, width, height);
You mentioned bit shifting how does this work exactly? I couldn't find any sources explaining it
@schotsl-- re:
See:
https://processing.org/reference/color_datatype.html
https://processing.org/reference/rightshift.html
@jeremydouglass Thank you!
You mentioned adding the squires of the distances together as an alternative to the dist function, would this be an appropriate way to do it?
difference += sq((r2-r1) + (g2-g1) + (b2-b1));
Are you asking about whether to square the sum of the differences, or to square the x, y, and z components and then sum them?
in addition to what others has said the x loop should be the inner loop