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
Jakub
December 5, 2018, 8:20am
2
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() :
// ...
void setup() {
// ...
( video = new Capture(Capture.list()[0]) ).start();
while (video.height == 0) delay(2);
opencv = new OpenCV(this, video);
// ...
}
processing:master
← processing:shiffman-getting-started-capture
Matching canvas' **size()** w/ **Capture**'s _width_ & _height_ is a good soluti… on IMO.
Here's a simplified version from Processing's forum:
http://forum.Processing.org/two/discussion/11528/why-are-the-actual-camera-fps-different-from-captured-fps
``` Processing
import processing.video.Capture;
Capture cam;
static final int FPS_ADJUST = 5, CAM = 1;
void setup() {
initFeed();
size(cam.width, cam.height, JAVA2D);
float canvasFPS = cam.frameRate + FPS_ADJUST;
frameRate(canvasFPS);
println("Cam's FPS:", cam.frameRate, "\t\tCanvas's FPS:", canvasFPS);
print("Cam's size:", cam.width, 'x', cam.height, '\t');
println("Canvas's size:", width, 'x', height);
}
void draw() {
background(cam);
frame.setTitle( str(round(frameRate)) );
}
void captureEvent(Capture c) {
c.read();
}
void initFeed() {
if (cam != null) return;
String[] cams = Capture.list();
printArray(cams);
println("\nChosen Cam #" + CAM + ':', cams[CAM]);
( cam = new Capture(this, cams[CAM]) ).start();
while ( (cam.width & cam.height) == 0 ) delay(5);
}
```
1 Like
Jakub
December 5, 2018, 3:09pm
4
@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:
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
Jakub
December 6, 2018, 5:32pm
8
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!
Found that out when experimenting on the following hack sketch:
Although it’s pretty much a hack, here’s the workaround I’ve come up w/:
/**
* Threaded PGraphics II (v1.0.1)
* GoToLoop (2018/Dec/07)
*
* https://Discourse.Processing.org/t/
* problems-when-trying-to-draw-to-a-p3d-pgraphics-
* when-called-from-a-thread/6301/4
*
* https://Forum.Processing.org/two/discussion/25799/
* how-to-draw-a-rect-in-a-thread#Item_2
*/
static final int W = 250, H = 200, FPS = 10;
Layer layer;
void settings() {
size(W, H, JAVA2D);
smooth(3);
}
v…
It happened when I’d removed draw() and forced an “eternal” loop within setup() !
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