Can Streaming video be used in OpenCV?

I opened the example “backgroundSubstraction” and tried to replace movie file with streaming webcam video but no luck.

this line is the trouble:

opencv = new OpenCV(this, video);

The error says" Width(0) and height (0) cannot be <=0"

Here is the code I tried:

import gab.opencv.*;
import processing.video.*;
Capture video;
//Movie video;
OpenCV opencv;

void setup() {
  size(840, 660);
  
   String[] cameras = Capture.list();
  if (cameras == null) {
    println("Failed to retrieve the list of available cameras, will try the default...");
   video = new Capture(this, 800, 600);
  } 
  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } 
  
  video = new Capture(this, "name=iSight,size=640x480,fps=15");
  video.start();
  //video = new Capture(this, 640, 480);
 // video = new Movie(this, "name=iSight,size=640x480,fps=15");
  opencv = new OpenCV(this, video);
  
  opencv.startBackgroundSubtraction(5, 3, 0.5);
  
  //video.loop();
  //video.play();
}

void captureEvent(Capture video) {
  video.read();
}

void draw() {
  
  video.loadPixels();
  image(video, 0, 0);  
  opencv.loadImage(video);
  
  opencv.updateBackground();
  
  opencv.dilate();
  opencv.erode();

  noFill();
  stroke(255, 0, 0);
  strokeWeight(3);
  for (Contour contour : opencv.findContours()) {
    contour.draw();
  }
}

void movieEvent(Movie m) {
  m.read();
}
1 Like

Video can take some time to initialize. You should use it only when the height and width becomes non zero. You can wait until the video starts and only then create opencv. I didn’t test this code but something like this might work:

void setup() {
  ...
  // Start video here
  video = new Capture(...);
  ...
}

void captureEvent(Capture video) {
  video.read();
}

void draw() {
  if (opencv == null && video.width != 0 && video.height != 0) {
    // Video is ready
    // Create and config OpenCV here
    opencv = new OpenCV(...);
    ...
  }
  if (opencv != null) {
    // Video is ready and opencv was created
    // your draw code here
    opencv.loadImage(...);
    ...
  }
}
1 Like

Even better: Move the wait step to setup(): :bulb:

// ...
void setup() {
  // ...
  ( video = new Capture(Capture.list()[0]) ).start();
  while (video.height == 0)  delay(2);
  opencv = new OpenCV(this, video);
  // ...
}
1 Like

@GoToLoop This could work too. However, you might get a crash if you use OpenGL renderer and block setup like this, so I don’t usually recommend it.

1 Like

But OP is using JAVA2D. Nonetheless, I’ve tested all renderers using my ancient sketch “Efficient WebCam Capture” from the link below, and no crashes have happened so far: :upside_down_face:

1 Like

Totally agree with @Jakub and I made the exact same point the last time you advocated this - blocking setup() is a stupid idea for multiple reasons. Just because it works for you, with your camera on your system, doesn’t make it a good idea!

Thank you folks, That worked, I got streaming video.
However the I dont get contours and the OPENCV module does not work now.

I think it has to do with the function on the botom that referes to Movie, not streaming video.
What to do?
Thanks

Here is the code:

void draw() {

  video.loadPixels();
  image(video, 0, 0);  

  if (opencv == null && video.width != 0 && video.height != 0) 
  {
    opencv = new OpenCV(this, video);
  }
  if (opencv != null) 
  {
    opencv.loadImage(video);
    opencv.startBackgroundSubtraction(5, 3, 0.5);
    opencv.updateBackground();
    opencv.dilate();
    opencv.erode();
    noFill();
    stroke(255, 0, 0);
    strokeWeight(3);
    for (Contour contour : opencv.findContours()) 
    {
      contour.draw();
    }
  }
}

void movieEvent(Movie m) {
  m.read();
}
1 Like

For capture you need captureEvent() instead:

void captureEvent(Capture c) {
  c.read();
}
1 Like

@Jakub. Indeed Processing’s OpenGL renderers crash on setup() if we delay() it by 5 seconds! :cold_face:

Found that out when experimenting on the following hack sketch: :ghost:

It happened when I’d removed draw() and forced an “eternal” loop within setup()! :scream:

2 Likes

Jackub
I am using captureEvent already, the video loads fine. There is no background substraction like in the example.
If i move an object, nothing happens, no countours around it. So it is the OPENCV part that does not kick in,

Any ideas?
Thanks again