Why is Processing skipping frames - processing

This is a simple program in processing, all it does is draws four circles in the last four frames (My Graphics card's refresh rate is 60Hz, so it draws them once every second)
But sometimes for some reason it is skipping frames, so I don't see all the four circles. Why is that and what can I do to make it not skip frames.
int counter = 1;
void setup(){
fullScreen();
background(0);
fill(255);
}
void draw(){
background(0);
if(counter == 57){
ellipse(383,383,100,100);
}
else if(counter == 58){
ellipse(583,383,100,100);
}
else if(counter == 59){
ellipse(783,383,100,100);
}
else if(counter == 60){
ellipse(983,383,100,100);
counter = 0;
}
counter++;
}

Think about what happens each time the draw() function is called:
First you call background(0) to clear out old frames.
Then you check which frame it is, and possibly draw a circle.
What happens on frame 61? You're going to clear out the old frames (clearing out the circles you've drawn), and then not draw anything. So each circle is shown for 1/60th of a second, which is probably impossible for you to see.
To fix your problem, you need to think about what you want to happen each frame. Consider getting rid of the call to background() so old frames are not cleared out, or possible redrawing old circles every frame. It depends on exactly what you want your sketch to do.
Side note: you don't need to create your own counter variable. Processing provides a frameCount variable that does exactly this. More info can be found in the reference.

Related

Processing saveFrame every 40 msec

I'm trying to create a graphic synchronized with a video at 25 frames/sec. I'm trying to save one frame every 40 msec, but I can't get 25 frames per sec, but only one image.
Can someone help me?
int t1;
int count;
void setup(){
size(400,100);
background(0);
stroke(255);
fill(250);
line(10,0,10,100);
line(260,0,260,100);
for (int i=10;i<251;i+=10){
t1=millis();
while(millis()-t1 < 40) {
count++;
}
rect(10,50,i,10);
//saveFrame("line-####.png");
}
}
void draw(){}
The problem in your code is that the canvas is updated only after the end of a frame, which means that your rectangles do exist but are not displayed until your setup() ends. This is why, even tho your code correctly waits 40 milliseconds before drawing a new rectangle, nothing is shown until the for loop ends: before ending the frame, Processing is waiting to complete the for loop.
However, in Processing draw() is called a certain amount of times per second, this amount of times is specified by the function frameRate() (default is 60).
Thus you can just set frameRate to 25 and save an image each time draw() is called.
noLoop() is used to stop calling draw(), in this case, once the rectangles are all drawn.
int count;
void setup()
{
frameRate(25);
size(400,100);
background(0);
stroke(255);
fill(250);
line(10,0,10,100);
line(260,0,260,100);
}
void draw()
{
rect(10,50,count,10);
saveFrame("line-####.png");
count += 10;
if(count > 251)
{
noLoop();
}
}

Jumping realistic in Processing with PVectors

I tried to make a jump look realistic, while I watched through the Videos:
The Natur of Code - The Coding Train
I got into PVectors. I strongly recomend watching him. But to get to my question, everything seems to work, exept that it draws the rectangle (my PVector) the way I want.
void keyPressed() {
if (keyCode == UP) {
for (int i = 0; i < 16; i++) {
location.sub(velocity);
velocity.sub(acceleration);
h.display();
background(0);
}
velocity.set(0, 15);
}
}
That's the Code, I expect it to "jump", but nothing realy happens. You can see that the rectangle get's drawn again (on the same spot), but there's no movement. It's definitly an issue with the drawing of the background or something, I don't know what exaclty though.
The nature of your question is unclear. You mentioned issues regarding the background interfering with your rectangle after the UP arrow key is pressed. This is likely because background(0) is called immediately after h.display(). I would remove background(0) from your loop if it's a display issue.
Other than that, there seem to be other issues with the loop itself. When the UP key is pressed, h is affected by acceleration only for 16 frames. To make your object more realistic, gravity (or whatever acceleration you choose) should constantly be acting upon the object.
With that in mind, here's a solution for you.
void keyPressed() {
if (keyCode == UP) {
// Make the character 'jump' upwards when the UP arrow is pressed.
// Setting the velocity should be the only thing happening when the key is pressed.
velocity.set(0, -2);
}
}
void draw() {
// Reset the background each frame so rectangles don't overlap.
background(255);
// Always draw the rectangle AFTER resetting the canvas.
h.display();
// Change the object's location by it's velocity.
location.add(velocity);
// And chance the object's velocity by it's acceleration.
// Since acceleration is the acting force of gravity in this situation, acceleration need not be changed.
velocity.add(acceleration);
// Prevent the rectangle from falling through the bottom of the canvas.
if(location.y > height - 5) location.y = height - 5;
}
// You negleteced to define your variables in your code snippet. Here they are.
PVector location = new PVector(0, 0);
PVector velocity = new PVector(0, 0);
PVector acceleration = new PVector(0, 0.1); // Notice that acceleration's y-value is 0.01. This is so you can see the effect of gravity.
// Define your rectangle object.
Object h = new Object();
class Object {
Object() {} // Constructor.
void display() {
// Draw the rectangle at the x- and y-positions of the location vector.
// The '+ width/2' places it at the center of the screen.
rectMode(CENTER);
rect(location.x + width/2, location.y, 10, 10);
}
}

How to get previous finger position in Leap Motion

Im a beginner at Leap Motion. I am wondering how to get the previous finger position of my hand. I am basically looking for the equivalent of pmouseX and pmouseY from Processing.
I'm not really familiar with Leap Motion, but assuming you have access to the current finger position, you could always track the previous position yourself. In Processing it would look something like this:
int previousMouseX;
int previousMouseY;
void draw(){
line(previousMouseX, previousMouseY, mouseX, mouseY);
previousMouseX = mouseX;
previouseMouseY = mouseY;
}
This is pretty much what Processing is doing for you with the pmouseX and pmouseY variables.

Processing function not working as intended

I've implemented a selection sort algorithm in Processing 3.0 and I would like to display the bars as they are being sorted. The code is as follow:
ArrayList<Bar> sort() {
int smallest;
for (int i = 0; i < sortedBars.size(); i++) {
smallest = indexOfMinimum(i);
swap(sortedBars, smallest, i);
background(0);
for (int i2 = 0; i2 < sortedBars.size(); i2++) {
sortedBars.get(i2).display(i2, 255);
}
}
return sortedBars;}
however, this code only displays some bars in the initial state and the final state, skipping everything in between.
On the other hand, if I use a similar function, but that runs only one time
ArrayList<Bar> sort(int i) {
int smallest = indexOfMinimum(i);
swap(sortedBars, smallest, i);
return sortedBars;}
And then call it multiple times inside draw() function, it works just fine.
Am I doing something wrong?
edit: Forgot to mention, this is the display function:
void display(int position, color col) {
stroke(col);
line(position, height, position, height - barSize);}
Also, the Bar class has an attribute called barSie.
This is exactly how Processing is intended to work.
Processing is double-buffered, which means that it draws everything to an off-screen buffer before it copies that buffer to the screen. Usually that's a good thing, as it makes animations smoother. But like you've discovered, it prevents the "in-between" frames from showing.
To solve your problem, there are two approaches I can think of:
Option one: instead of using a for loop to do your iteration, use each call to the draw() function as one "step" in your algorithm. That would allow you to show one step per frame.
Option two: instead of drawing to the screen, draw each step of your algorithm to its own buffer, which you can create using the createGraphics() function. Either save the frames to disc, or in their own data structure. Then when the algorithm completes, you'll have a set of frames that you can then display.
Which approach you take really depends on you and what your end goal is. Good luck.

Storing motion vectors from calculated optical flow in a practical way which enables reconstruction of subsequent frames from initial keyframes

I am trying to store the motion detected from optical flow for frames in a video sequence and then use these stored motion vectors in order to predict the already known frames using just the first frame as a reference. I am currently using two processing sketches - the first sketch draws a motion vector for every pixel grid (each of width and height 10 pixels). This is done for every frame in the video sequence. The vector is only drawn in a grid if there is sufficient motion detected. The second sketch aims to reconstruct the video frames crudely from just the initial frame of the video sequence combined with information about the motion vectors got from the first sketch.
My approach so far is as follows: I am able to determine the size, position and direction of each motion vector drawn in the first sketch from four variables. By creating four arrays (two for the motion vector's x and y coordinate and another two for its length in the x and y direction), every time a motion vector is drawn I can append each of the four variables to the arrays mentioned above. This is done for each pixel grid throughout an entire frame where the vector is drawn and for each frame in the sequence - via for loops. Once the arrays are full, I can then save them to a text file as a list of strings. I then load these strings from the text file into the second sketch, along with the first frame of the video sequence. I load the strings into variables within a while loop in the draw function and convert them back into floats. I increment a variable by one each time the draw function is called - this moves on to the next frame (I used a specific number as a separator in my text-files which appears at the end of every frame - the loop searches for this number and then increments the variable by one, thus breaking the while loop and the draw function is called again for the subsequent frame). For each frame, I can draw 10 by 10 pixel boxes and move then by the parameters got from the text files in the first sketch. My problem is simply this: How do I draw the motion of a particular frame without letting what I've have blitted to the screen in the previous frame affect what will be drawn for the next frame. My only way of getting my 10 by 10 pixel box is by using the get() function which gets pixels that are already drawn to the screen.
Apologies for the length and complexity of my question. Any tips would be very much appreciated! I will add the code for the second sketch. I can also add the first sketch if required, but it's rather long and a lot of it is not my own. Here is the second sketch:
import processing.video.*;
Movie video;
PImage [] naturalMovie = new PImage [0];
String xlengths [];
String ylengths [];
String xpositions [];
String ypositions [];
int a = 0;
int c = 0;
int d = 0;
int p;
int gs = 10;
void setup(){
size(640, 480, JAVA2D);
xlengths = loadStrings("xlengths.txt");
ylengths = loadStrings("ylengths.txt");
xpositions = loadStrings("xpositions.txt");
ypositions = loadStrings("ypositions.txt");
video = new Movie(this, "sample1.mov");
video.play();
rectMode(CENTER);
}
void movieEvent(Movie m) {
m.read();
PImage f = createImage(m.width, m.height, ARGB);
f.set(0, 0, m);
f.resize(width, height);
naturalMovie = (PImage []) append(naturalMovie, f);
println("naturalMovie length: " + naturalMovie.length);
p = naturalMovie.length - 1;
}
void draw() {
if(naturalMovie.length >= p && p > 0){
if (c == 0){
image(naturalMovie[0], 0, 0);
}
d = c;
while (c == d && c < xlengths.length){
float u, v, x0, y0;
u = float(xlengths[a]);
v = float(ylengths[a]);
x0 = float(xpositions[a]);
y0 = float(ypositions[a]);
if (u != 1.0E-19){
//stroke(255,255,255);
//line(x0,y0,x0+u,y0+v);
PImage box;
box = get(int(x0-gs/2), int(y0 - gs/2), gs, gs);
image(box, x0-gs/2 +u, y0 - gs/2 +v, gs, gs);
if (a < xlengths.length - 1){
a += 1;
}
}
else if (u == 1.0E-19){
if (a < xlengths.length - 1){
c += 1;
a += 1;
}
}
}
}
}
Word to the wise: most people aren't going to read that wall of text. Try to "dumb down" your posts so they get to the details right away, without any extra information. You'll also be better off if you post an MCVE instead of only giving us half your code. Note that this does not mean posting your entire project. Instead, start over with a blank sketch and only create the most basic code required to show the problem. Don't include any of your movie logic, and hardcode as much as possible. We should be able to copy and paste your code onto our own machines to run it and see the problem.
All of that being said, I think I understand what you're asking.
How do I draw the motion of a particular frame without letting what I've have blitted to the screen in the previous frame affect what will be drawn for the next frame. My only way of getting my 10 by 10 pixel box is by using the get() function which gets pixels that are already drawn to the screen.
Separate your program into a view and a model. Right now you're using the screen (the view) to store all of your information, which is going to cause you headaches. Instead, store the state of your program into a set of variables (the model). For you, this might just be a bunch of PVector instances.
Let's say I have an ArrayList<PVector> that holds the current position of all of my vectors:
ArrayList<PVector> currentPositions = new ArrayList<PVector>();
void setup() {
size(500, 500);
for (int i = 0; i < 100; i++) {
currentPositions.add(new PVector(random(width), random(height)));
}
}
void draw(){
background(0);
for(PVector vector : currentPositions){
ellipse(vector.x, vector.y, 10, 10);
}
}
Notice that I'm just hardcoding their positions to be random. This is what your MCVE should do as well. And then in the draw() function, I'm simply drawing each vector. This is like drawing a single frame for you.
Now that we have that, we can create a nextFrame() function that moves the vectors based on the ArrayList (our model) and not what's drawn on the screen!
void nextFrame(){
for(PVector vector : currentPositions){
vector.x += random(-2, 2);
vector.y += random(-2, 2);
}
}
Again, I'm just hardcoding a random movement, but you would be reading these from your file. Then we just call the nextFrame() function as the last line in the draw() function:
If you're still having trouble, I highly recommend posting an MCVE similar to mine and posting a new question. Good luck.

Resources