Video webcam motion detection troubles

Having difficulties with accessing webcam when using motion detection code.
Webcam works with other applications and when running Processing code, the viewing window is just dark. I tried to used the printArray Capture.list() to select the correct webcam and I do not receive any errors but only get a dark window.

// Exercise 16-7: Create a sketch that looks for the average location 
// of motion. Can you have an ellipse follow your waving hand?   

import processing.video.*;

// Variable for capture device
Capture video;
// Previous Frame
PImage prevFrame;

// How different must a pixel be to be a "motion" pixel
float threshold = 50;

void setup() {
  fullScreen(P2D, 2);
  //size(320, 240);
  // Using the default capture device
  // Capture camera list
  printArray(Capture.list());
  video = new Capture(this, Capture.list()[80]);
  width = 800;
  height = 600;
  video.start();

  // Create an empty image the same size as the video
  prevFrame = createImage(video.width, video.height, RGB);
}

// New frame available from camera
void captureEvent(Capture video) {
  // Save previous frame for motion detection!!
  prevFrame.copy(video, 0, 0, video.width, video.height, 0, 0, video.width, video.height);
  prevFrame.updatePixels();  
  video.read();
}


void draw() {
  background(0);

  // You don't need to display it to analyze it!
  image(video, 0, 0);


  loadPixels();
  video.loadPixels();
  prevFrame.loadPixels();

  // These are the variables we'll need to find the average X and Y
  float sumX = 0;
  float sumY = 0;
  int motionCount = 0; 

  // Begin loop to walk through every pixel
  for (int x = 0; x < video.width; x++ ) {
    for (int y = 0; y < video.height; y++ ) {
      // What is the current color
      color current = video.pixels[x+y*video.width];

      // What is the previous color
      color previous = prevFrame.pixels[x+y*video.width];

      // Step 4, compare colors (previous vs. current)
      float r1 = red(current); 
      float g1 = green(current);
      float b1 = blue(current);
      float r2 = red(previous); 
      float g2 = green(previous);
      float b2 = blue(previous);

      // Motion for an individual pixel is the difference between the previous color and current color.
      float diff = dist(r1, g1, b1, r2, g2, b2);

      // If it's a motion pixel add up the x's and the y's
      if (diff > threshold) {
        sumX += x;
        sumY += y;
        motionCount++;
      }
    }
  }

  // average location is total location divided by the number of motion pixels.
  float avgX = sumX / motionCount; 
  float avgY = sumY / motionCount; 

  // Draw a circle based on average motion
  smooth();
  noStroke();
  fill(255);
  ellipse(avgX, avgY, 16, 16);
}

I appreciate any support or advice on getting a webcam to work with processing.

1 Like

I think you need something like

video = new Capture (this, width, height);

And set the size of the sketch according the smallest configuration possible.

Thanks Noel, your feedback is greatly welcomed.
When trying your recommendation:
video = new Capture (this, width, height);
The video always goes to the default internal camera and not the external web camera. I also need the output to be fullScreen. Unfortunately I was not able to make it work with this recommendation.

Unfortunately I only have a tablet, thus I can’t test it. I have a working motion detection code for Android with the ketai lib. If you’r interested I’ll post it.

Thanks again noel and I would be happy to learn about the detection code for Android with the ketai lib. I look forward to your post and thanks again!

Here it is.
You have to give the CAMARA permission to run.
You can test it downloading the app APDE on play store. I’ll take just two minutes.

// Thanks to
// Daniel Shiffman
// http://www.learningprocessing.com
// Code for Android / Ketai by noel

import ketai.camera.*;
KetaiCamera cam;

PImage prevFrame;
float threshold = 50;

void setup() {
  size(320, 240);
  cam = new KetaiCamera(this, 320, 240, 31);
  //  cam.setCameraID(1); // If you want the front camara
  cam.start();
  prevFrame = createImage(cam.width, cam.height, RGB);
}


void onCameraPreviewEvent() {
  prevFrame.copy(cam, 0, 0, cam.width, cam.height, 0, 0, cam.width, cam.height);
  prevFrame.updatePixels();
  cam.read();
}


void draw() {
  background(255);

  // You don't need to display it to analyze it!
  image(cam, 0, 0);

  cam.loadPixels();
  prevFrame.loadPixels();

  // Start with a total of 0
  // These are the variables we'll need to find the average X and Y
  float sumX = 0;
  float sumY = 0;
  int motionCount = 0; 

  // Begin loop to walk through every pixel
  for (int x = 0; x < cam.width; x++ ) {
    for (int y = 0; y < cam.height; y++ ) {
      // What is the current color
      color current = cam.pixels[x+y*cam.width];

      // What is the previous color
      color previous = prevFrame.pixels[x+y*cam.width];

      // Step 4, compare colors (previous vs. current)
      float r1 = red(current); 
      float g1 = green(current);
      float b1 = blue(current);
      float r2 = red(previous); 
      float g2 = green(previous);
      float b2 = blue(previous);

      // Motion for an individual pixel is the difference between the previous color and current color.
      float diff = dist(r1, g1, b1, r2, g2, b2);

      // If it's a motion pixel add up the x's and the y's
      if (diff > threshold) {
        sumX += x;
        sumY += y;
        motionCount++;
      }
    }
  }

  // average location is total location divided by the number of motion pixels.
  float avgX = sumX / motionCount; 
  float avgY = sumY / motionCount; 

  // Draw a circle based on average motion
  smooth();
  noStroke();
  fill(255);
  ellipse(avgX, avgY, 16, 16);
  
}

This line is suspicious. Is your webcam really listed as camera 80?

Hi jeremey, thanks for the concern and according to my captureList, the proper camera format is 80.
If possible, can you dive more into your suspicions?

Help! I am trying to connect a usb webcam to android device but can’t seem to get my phone to read webcam input. How can I make this work? I’ll paste my code below.

import ketai.camera.*;

KetaiCamera cam;

import processing.sound.*;
SqrOsc soundRed;
Pulse soundGreen;
SinOsc soundBlue;
int gameState = 0;
int count = 0;
float rAmp = 0;
float gAmp = 0;
float bAmp = 0;
boolean sounds = false;
float tempRed = 0;
float tempGreen = 0;
float tempBlue = 0;
float mapRed = 0;
float mapGreen = 0;
float mapBlue = 0;
float soundSpace = 0;
int countThruCameras;
void setup() {

textSize(20);
fullScreen();
orientation(PORTRAIT);
imageMode(CENTER);
soundRed = new SqrOsc(this);
soundRed.amp(0.05);
soundGreen = new Pulse(this);
soundGreen.amp(0.05);
soundBlue = new SinOsc(this);
soundBlue.amp(0.2);

cam = new KetaiCamera(this, 1000, 1500, 60);
cam.setCameraID(80);
textAlign(CENTER, CENTER);
}

void draw() {

if(gameState == 0){
count++;
if(count >= 200){
gameState = 1;
cam.start();
}
background(255);
}

if (gameState==1) {

print(cam.getCameraID());
soundRed.amp(rAmp);
soundGreen.amp(gAmp);
soundBlue.amp(bAmp);


background(0);

translate(width/2, height/2);
pushMatrix();
rotate(HALF_PI);
image(cam, 0,0);
popMatrix();
tempRed = red(get(width/2, height/2));
tempGreen = green(get(width/2, height/2)); 
tempBlue = blue(get(width/2, height/2));
mapRed = map(tempRed, 0, 255, 1, 200);
mapGreen = map(tempGreen, 0, 255, 0, 450);
mapBlue = map(tempBlue, 0, 255, 1, 500);
rAmp = map(mapRed, 0, 200, 0, .05);
gAmp = map(mapGreen, 0, 450, 0, .05);
bAmp = map(mapBlue, 0, 200, 0, .07);
//soundSpace = (mapRed+mapGreen+mapBlue)/3;


soundRed.freq(mapRed);
soundGreen.freq(mapGreen);
soundBlue.freq(mapBlue);
stroke(255);
strokeWeight(2);
noFill();
ellipse(0, 0, 40, 40);
if (sounds) {
  soundRed.play();
  soundGreen.play();
  soundBlue.play();
} else {
  soundRed.stop();
  soundGreen.stop();
  soundBlue.stop();
  fill(0, 0, 0, 180);
  stroke(0);
  //rect((-width/2)-5, 170, width+5, 60);
  fill(0, 200, 255);
  text("Click screen to hear color", 0, (height/3)+(height/13));
  stroke(255);
}
text(cam.getNumberOfCameras(),0,100);

}
}

void onCameraPreviewEvent()
{
cam.read();

}

void mousePressed() {

if(gameState==1){
sounds = !sounds;

}
}