We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello there!
I have borrowed this code for a school project. It creates a bouncing ball which you can control with you webcam by movements. Sometimes it works just fine, but there seem to be a bug saying
** (java.exe:9372): WARNING **: gstvideo: failed to get caps of pad nat:sink
And then the webcam won't stream. I stumbled upon a discussion with a similar problem, saying using loadPixels() and updatePixels - yet it did not remove the warning.
Below is the code
BackgroundBouncer.pde:
import processing.video.*;
import gab.opencv.*;
import java.awt.Rectangle;
Capture video;
OpenCV opencv;
Ball b;
void setup() {
size(640,480, P3D); //setup screen size and uses OpenGL gfx driver
frameRate(30);
ellipseMode(RADIUS); //set ellipse mode to radius (center point)
video = new Capture(this, width/2, height/2);
opencv = new OpenCV(this, width/2, height/2);
b = new Ball();
video.start();
video.read();
opencv.startBackgroundSubtraction(50,3,0.5); //detects moving objects
}
void draw() {
clear();
scale(2);
loadPixels();
opencv.loadImage(video); //
opencv.flip(OpenCV.HORIZONTAL);
opencv.updateBackground();
opencv.calculateOpticalFlow(); //apparent motion between two frames caused by moving object or camera
opencv.dilate(); //makes the image wider and look at neighbour pixels shape over which minimum is taken
opencv.erode(); //erodes image and look at neighbour pixels shape over which minimum is taken
noFill();stroke(255,0,0);
strokeWeight(1);
image(opencv.getOutput(), 0, 0);
for (Contour c : opencv.findContours()) {
Contour hull = c.getConvexHull();
Rectangle box = hull.getBoundingBox();
b.strike(c, opencv);
}
b.move();
reflect(b);
drawBall(b);
updatePixels();
}
void keyPressed() {
b.position = new PVector(120, 120);
b.momentum = new PVector(0, 0);
}
void captureEvent(Capture c) {
c.read();
}
And the Ball.pde:
float decayRate = 0.9; //how much decay
float scalingFactor = 7; //how big a ball
PVector gravity = new PVector(0, 0.5); //how heavy
class Ball {
public Ball() {
size = 25;
shade = #FF0000; //red ball
position = new PVector(120, 120); //start position
momentum = new PVector(0, 0); //a moment of stillness
}
public PVector position;
public PVector momentum;
public float size;
public color shade;
public void move() {
position.add(momentum);
momentum.add(gravity);
momentum.mult(decayRate);
}
public void strike(Contour c, OpenCV opencv) {
for (PVector p : c.getPoints()) {
if (p.dist(position) <= size) {
Rectangle box = c.getBoundingBox();
PVector flow = opencv.getAverageFlowInRegion(box.x, box.y, box.width, box.height);
flow.mult(scalingFactor);
momentum.add(flow);
return;
}
}
}
}
void drawBall(Ball b) {
fill(b.shade);
ellipse(b.position.x, b.position.y,
b.size, b.size);
}
void reflect(Ball b) {
if (b.position.x - b.size <= 0) {
b.position.x = b.size;
b.momentum.x *= -1;
} else if (b.position.x + b.size > width/2) {
b.position.x = width/2 - b.size;
b.momentum.x *= -1;
}
if (b.position.y - b.size <= 0) {
b.position.y = b.size;
b.momentum.y *= -1;
} else if (b.position.y + b.size > height/2) {
b.position.y = height/2 - b.size;
b.momentum.y *= -1;
}
}
Any help or tips is welcomed! Thanks in advance.
Answers
Possibly removing the statement video.read() from the setup() procedure will fix it.