Video Processing with a Rasperry Pi

Hello there. I have been working on a CV project with a raspberry pi for a Robotics Competition. I am not really experienced within the field of CV though (Working more on the electronics in general). So I am seeking your help. I did some research and found out some pieces of code and merged them together (not always the best idea apparently). Basically, I got the code from that video: https://www.youtube.com/watch?v=nCVZHROb_dE&index=2&list=PLRqwX-V7Uu6aG2RJHErXKSWFDXU4qo_ro and used gohai’s Video library to adapt the whole thing with my Raspberry. My code is that one over here:

import gohai.glvideo.*;
GLCapture video;
color trackColor; 
float threshold = 25;

void setup() {
  size(320, 200, P2D);

  String[] devices = GLCapture.list();
  println("Devices:");
  printArray(devices);
  if (0 < devices.length) {
    String[] configs = GLCapture.configs(devices[0]);
    println("Configs:");
    printArray(configs);
  }
  video = new GLCapture(this);

  video.start();
  trackColor = color(255, 0, 0);
}

void draw() {
  background(0);
  if (video.available()) {
    video.read();
  }
  image(video, 0, 0, width, height);
  threshold = 80;

  float avgX = 0;
  float avgY = 0;

  int count = 0;

  for (int x = 0; x < video.width; x++ ) {
    for (int y = 0; y < video.height; y++ ) {
      int loc = x + y * video.width;
      color currentColor = video.pixels[loc];
      float r1 = red(currentColor);
      float g1 = green(currentColor);
      float b1 = blue(currentColor);
      float r2 = red(trackColor);
      float g2 = green(trackColor);
      float b2 = blue(trackColor);

      float d = distSq(r1, g1, b1, r2, g2, b2); 

      if (d < threshold*threshold) {
        stroke(255);
        strokeWeight(1);
        point(x, y);
        avgX += x;
        avgY += y;
        count++;
      }
    }
  }

  if (count > 0) { 
    avgX = avgX / count;
    avgY = avgY / count;
    // Draw a circle at the tracked pixel
    fill(255);
    strokeWeight(4.0);
    stroke(0);
    ellipse(avgX, avgY, 24, 24);
  }
}

float distSq(float x1, float y1, float z1, float x2, float y2, float z2) {
  float d = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) +(z2-z1)*(z2-z1);
  return d;
}

void mousePressed() {
  int loc = mouseX + mouseY*video.width;
  trackColor = video.pixels[loc];
}

I keep getting a “ArrayOutOfBoundsException” here “color currentColor = video.pixels[loc];”.
I am really seeking an experienced man’s help here (what do you expect from a newbie like me anyways).
Thank you for your time!

Hi dimpap5555,

Please edit your previous post and format your code. The icon look like this: </>

The error that you get basically told you that you try to access an element that is not in the array: video.pixels in your case. It means that at some points, the loc variable is too big and point outside of your array.

Now, looking at how you compute loc, everything should be alright. My guess is that when you launch the program, the first time you enter to draw() function, you get no available frame from your camera so you don’t read any picture so your video variable stays empty: explaining the error you get.

Try putting everything in between your if statement and see if it works. If that’s the case, then my guess is correct. Otherwise, we will need to dig deeper =)

Ugh, it did not work unfortunately. I put all the draw() code on the “if availiable” condition. Nothing though. Same error.

Omg… I know why…

You did not load the pixels so the pixel array is never updated: https://processing.org/reference/loadPixels_.html

If you don’t want to do that you can still use the get() function but it will be slower:

Alright seems legit. What should I do exactly though? Sorry for that, as said I am not that experienced. I know coding but it’s my first time working with CV and processing.

Nevermind. I tinkered a bit by myself and made it work! I really appreciate your help! Thank you very much!