Night #8: Rendering an image sequence

How can one render a movie from a Processing sketch? In Processing 1.5.1, there is a class called MovieMaker which generates a Quicktime file directly. However, this class uses ye old Quicktime for Java and will be removed from Processing 2.0. Instead, 2.0 is going to introduce a MovieMaker “tool” which will generate a movie file from a directory containing an image sequence. So how do you get this image sequence? Easy:

void draw() {
  saveFrame("output/frames####.png");
}

This will create a folder called “output” in your sketch folder and for each frame of draw(), it will write a file — frames0001.png, frames0002.png, etc. The ‘#’ sign tells processing to auto-number the images.

There are a couple additional tricks included in this new example. First, it uses a boolean variable to turn rendering on and off and cycles the boolean in keyPressed() allowing recording to be stopped and started by pressing ‘r’.

void draw() {
  // If we are recording call saveFrame!
  if (recording) {
    saveFrame("output/frames####.png");
  }
}
 
void keyPressed() {  
  // If we press r, start or stop recording!
  if (key == 'r' || key == 'R') {
    recording = !recording;
  }
}

In addition, if you draw anything after saveFrame() it won’t actually appear in the output, but will be seen on screen. This is useful for debugging information that you don’t want included in the render.

void draw() {
 
  // Draw lots of stuff to be recorded!
 
  if (recording) {
    saveFrame("output/frames####.png");
  }
 
  // Draw our debugging stuff that won't be recorded!
}

Until 2.0 is released, I recommend you use 3rd party software to take the image sequence and turn it into a movie. The old Quicktime 7 will do the trick, as well as any number of video production applications like final cut, after effects, iMovie, etc. The nice thing about using a PNG sequence is that the images are uncompressed, but aren’t as large as say TIFFs. I don’t recommend saving JPGs because then you will likely be compressing twice (once when saving the image, once when exporting the movie file).

Source: SavingFrames.zip

Night #7: Nature of Code excerpts

For tonight’s post, I’m going to include three new examples from my upcoming Nature of Code book. I’ll also excerpt some of the text with these examples below.

This first example expands on the existing Recursive Tree example that comes with Processing.

Chapter 8: Recursion and Fractals

The recursive tree fractal is a nice example of a scenario in which adding a little bit of randomness can make the tree look more natural. Take a look outside and you’ll notice that branch lengths and angles vary from branch to branch, not to mention the fact that branches don’t all have exactly the same number of smaller branches. First, let’s see what happens when we simply vary the angle and length. This is a pretty easy one, given that we can just ask Processing for a random number each time we draw the tree.

void branch(float len) {	
  // Start by picking a random angle for each branch
  float theta = random(0,PI/3);  
 
  line(0, 0, 0, -len);
  translate(0, -len);
  len *= 0.66;
  if (len > 2) {
    pushMatrix();    
    rotate(theta);   
    branch(len);
    popMatrix();     
    pushMatrix();
    rotate(-theta);
    branch(len);
    popMatrix();
  }
}

In the above function, we always call branch() twice. But why not pick a random number of branches and call branch() that number of times?

void branch(float len) {	
 
  line(0, 0, 0, -len);
  translate(0, -len);
 
  if (len > 2) {
 
    // Call branch() a random number of times
    int n = int(random(1,4));		 
    for (int i = 0; i < n; i++) {	
 
      // Each branch gets its own random angle
      float theta = random(-PI/2, PI/2); 
      pushMatrix();     
      rotate(theta);
      branch(h);
      popMatrix();
    }
  }
}

The example below takes the above a few steps further. It uses Perlin noise to generate the angles, as well as animate them. In addition, it draws each branch with a thickness according to its level and sometimes shrinks a branch by a factor of two to vary where the levels begin.

TreeStochasticNoise.zip

Next up an excerpt from the Genetic Algorithm chapter.

Chapter 9: Evolution and Code

In 2009, Jer Thorp released a great genetic algorithms example on his blog entitled “Smart Rockets.” Jer points out that NASA uses evolutionary computing techniques to solve all sorts of problems, from satellite antenna design to rocket firing patterns. This inspired him to create a Flash demonstration of evolving rockets. Here is a description of the scenario:

A population of rockets launches from the bottom of the screen with the goal of hitting a target at the top of the screen (with obstacles blocking a straight line path).

Each rocket is equipped with five thrusters of variable strength and direction. The thrusters don’t fire all at once and continuously; rather, they fire one at a time in a custom sequence. In this example, we’re going to evolve our own simplified Smart Rockets, inspired by Jer Thorp’s. You can leave implementing some of Jer’s additional advanced features as an exercise.

Our rockets will have only one thruster, and this thruster will be able to fire in any direction with any strength in every single frame of animation. This isn’t particularly realistic, but it will make building out the framework a little easier. (We can always make the rocket and its thrusters more advanced and realistic later.)

Source: SmartRockets.zip

And here’s a short excerpt from the beginning of the chapter on neural networks, as well as the example that closes out the chapter demonstrating how to visualize the flow of information through a network.

Chapter 10: The Brain

Computer scientists have long been inspired by the human brain. In 1943, Warren S. McCulloch, a neuroscientist, and Walter Pitts, a logician, developed the first conceptual model of an artificial neural network. In their paper, “A logical calculus of the ideas imminent in nervous activity,” they describe the concept of a neuron, a single cell living in a network of cells that receives inputs, processes those inputs, and generates an output.

Their work, and the work of many scientists and researchers that followed, was not meant to accurately describe how the biological brain works. Rather, an artificial neural network (which we will now simply refer to as a “neural network”) was designed as a computational model based on the brain that can solve certain kinds of problems.

It’s probably pretty obvious to you that there are certain problems that are incredibly simple for a computer to solve, but difficult for you. Take the square root of 964,324, for example. A quick line of code produces the value 982, a number Processing computed in less than a millisecond. There are, on the other hand, problems that are incredibly simple for you or me to solve, but not so easy for a computer. Show any toddler a picture of a kitten or puppy and they’ll be able to tell you very quickly which one is which. Say hello and shake my hand one morning and you should be able to pick me out of a crowd of people the next day. But need a machine to perform one of these tasks? People have already spent careers researching and implementing complex solutions.

The most common application of neural networks in computing today is to perform one of these easy-for-a-human, difficult-for-a-machine” tasks, often referred to as pattern classification. Applications range from optical character recognition (turning printed or handwritten scans into digital text) to facial recognition. We don’t have the time or need to use some of these more elaborate artificial intelligence algorithms here, but if you are interested in researching neural networks, I’d recommend the books Artificial Intelligence: A Modern Approach by Stuart J. Russell and Peter Norvig and AI for Game Developers by David M. Bourg and Glenn Seemann.

In this chapter, we’ll instead begin with a conceptual overview of the properties and features of neural networks and build the simplest example possible of one (a network that consists of a singular neuron). Afterwards, we’ll examine strategies for building a “Brain” object that can be inserted into our Vehicle class and used to determine steering. Finally, we’ll also look at techniques for visualizing and animating a network of neurons.

Source: NetworkAnimation.zip

Night #6: Image Sequence Object (with variable speed)

I have an example from Learning Processing which demonstrates how to package a “pre-made” animation (i.e. sequence of images) into an object in Processing so that it can be duplicated many times on screen. For tonight’s example, I’m going to make a new version that improves a few key points.

First, in the original example the the image files are loaded in the class itself. This is problematic. Sure, if you make one object then you are loading files from the hard drive once. However, if you make many objects, then you are loading the same images over and over again which is totally unnecessary (and can cause problems like using too much memory, stuttering if objects are made during draw(), taking too long to start up, etc.).

We can fix this by loading an array of images in setup() and passing it to the object.

Animation a;
 
void setup() {
  // Load the image sequence first!
  PImage[] seq = new PImage[40];
  for (int i = 0; i < seq.length; i++) {
    seq[i] = loadImage("stick/stick"+nf(i+1,2)+".png"); 
  }
 
  // Now when you make the animation object, you pass it the image array!
  a = new Animation(seq);  
}

The class then receives the array in the constructor and passes it to its own array.

class Animation {
  // The array of images
  PImage[] images;
 
  Animation(PImage[] images_) {
    images = images_;
  }

This way (as you'll see in the example) if we make an array of objects, each one uses the same array of images (which we loaded only once). Another feature of this improvement is that the Animation object is more generic, and can be created with any arbitrary array of images.

The original example demonstrated how to have the sequences start at different images so that they didn't all appear to be perfectly in sync. However, the question I usually get is instead: "How can the sequences play back at variable speeds?"

The original example used an integer to keep track of the current "frame" of the animation.

int index = 0;
 
void next() {
  index = (index + 1) % images.length;
}

Here, you see that we move one spot in the array each frame, and the animation is then shown at the frame rate of our sketch. So in theory, you could change the above to "index = index + 2" to, say, double the speed. A more flexible way to vary the rate of the animation, however, is to use a float for the index in the array, i.e.

float index = 0;
float speed = random(1,5);
 
void next() {
  // Move the index forward in the animation sequence
  index += speed;
  // If we are at the end, go back to the beginning
  if (index >= images.length) {
    // We could just say index = 0
    // but this is slightly more accurate
    index -= images.length;
  } 
}

Of course, you can't actually use this float when you go to look up an image in the array -- indices must be integers! So we simply convert it to an int when the time comes to draw the image.

void display() {
  int imageIndex = int(index);
  image(images[imageIndex], x, y);
}

Here is the example.

Download source: AnimationExample.zip

Revisiting Flight404 Particles

In February 2008, Robert Hodgin published a series of Particle System examples that demonstrated many of the techniques behind his amazing work (i.e.: Magnetosphere). The examples, however, use some advanced GL calls (accessing JOGL directly) and no longer work in Processing 1.0. I would say a student comes to ask me about updating these examples several times a semester and I usually respond by pretending I know what I’m talking about and pointing the student some vague openGL direction. It’s time for me to bit the bullet and figure this out myself.

Step 1 is simply to recreate the examples using Processing’s core drawing functions sans fancy GL. Now, they run a great deal slower than Robert’s original examples because they are no longer using display lists.

Check out the source or download flight404.zip.

Step 2 is to use the wonderful Andrés Colubri‘s GLGraphics library to optimize for performance. Stay tuned.

UPDATE: Step 1a is to create OPENGL textures directly like so:

particleTex = TextureIO.newTexture(new File(dataPath("particle.png")), true);

(Thanks to Jeff Gentes and Ben Hosken for chiming in)

Asteroids Spaceship

One of the “trignometry + forces” exercises from my upcoming Nature of Code book is to implement in Processing the spaceship from asteroids. Here’s a solution!

Source: _03_asteroids.zip

Nature of Code book: PVector Spring example

I’m working this week on Chapter 3 of my upcoming Nature of Code book. For the most part, if you are looking to connect particles with springs, I recommend the wonderful verlet physics of toxiclibs, and I have some examples for that here. Nevertheless, I am including an elementary implementation of a single “bob” connected to an “anchor” point via a “spring” force. The example implements Hooke’s Law (Spring Force = -k * displacement) with the PVector class, using the Euler integration model of all my other examples. Here it is below.

Source: _03spring.zip

Updated Kinect Library for Processing

A quick post to announce an updated Kinect library for Processing on github. This new library uses the most recent libfreenect drivers (mac os x only still) and builds off of the existing JNI Java Wrapper. Links:

Download library and example:
openkinect.zip

Source:
https://github.com/shiffman/libfreenect/tree/master/wrappers/java/processing

My tests show 30 FPS no problem for either the depth or RGB image, if you request both images, however, I’m only currently getting about 20 FPS. The update fixes a few bugs, exposes the raw depth data and includes a point cloud demo (see above video).

I have a list of “to-do” items here:

https://github.com/shiffman/libfreenect/issues
(a shortened version of the very long list in my head)

Kinect and Processing

Kinect Processing Library in Action

This is all very preliminary, but here is a first pass as a Processing Kinect library:

http://www.shiffman.net/p5/kinect.zip
(Mac OSX only for now, sorry!)
UPDATE (12/18/10): New version of the library can be downloaded from github:

openkinect.zip.

Source: https://github.com/shiffman/libfreenect/tree/master/wrappers/java/processing

None of this would have been possible without the heroic efforts of Hector Martin, the OpenKinect project, and various members of the openFrameworks community. There’s a great thread with discussion and code here:

http://www.openframeworks.cc/forum/viewtopic.php?f=14&t=4947

Video in action here:

Processing code looks like:

 
import shiffman.kinect.*;
 
PImage img;
PImage depth;
 
 void setup() {
  size(640,240);
  NativeKinect.init();
  img = createImage(640,480,RGB);
  depth = createImage(640,480,RGB);
}
 
 void draw() {
  NativeKinect.update();
  img.pixels = NativeKinect.getPixels();
  img.updatePixels();
 
  depth.pixels = NativeKinect.getDepthMap();
  depth.updatePixels();
 
  image(img,0,0,320,240);
  image(depth,320,0,320,240);
}