Friday, January 30, 2009

Making a Time-lapse Video with the Nikon D50 and gphoto2

Who said you cannot teach a 2-year-old digital camera new tricks?

I was really excited when I found out I could control my Digital SLR camera via the USB cable. Nikon produces a software called Camera Control Pro. The software is $170 USD, and there is no non-pro version that I know of. They give you a 30-day trial, so I thought I would check it out.

At first, my camera wouldn't connect. I had to use the menu on the camera to take the USB mode out of "Mass Storage" and into "PTP". The camera stopped bringing up iPhoto and started working in Camera Control. Life was good.

I made a time-lapse of the sunset through my 10.5mm fisheye lens, taking one frame per minute. I used ImageMagick to convert the JPEGs into an MPEG, although this method lacks a lot of the control that I expected: frame rate, bitrate, etc.

As I was looking for a free way to do this, since I was not going to pay almost $200; I have to eat too you know. I (almost by accident) came across gphoto2. I think I had already heard of this software as I was wondering how I could capture images from a webcam, if I had one. The gphoto2 software (available through YUM in Fedora) provides a command-line method to do what I was doing with Camera Control; taking time-lapse pictures. However, it doesn't provide an interface similar to the one on the camera in a GUI form for changing camera settings. No matter, since you can use the controls on the camera directly in PTP mode.

So I made an AT job:

at 6:00am
cd /home/ryan/Pictures/Timelapse/Sunrise
gphoto2 --capture-image --interval=15
[CTRL+D]
I quickly found out that I need to purchase the Nikon EH-5 AC adapter since the camera spends a lot of power in PTP mode and the battery died overnight. Replaced with a spare just in the nick of time and everything went as planned. I should have increased the rate to four times per minute (every 15 seconds), but I was scared after the battery died that with nearly continuous long-shutter shots the battery would die again. As soon as I have the adapter, I'll try going to four frames per minute (or more).

Then, I used a script that had taken some time to develop to compile the frames into video. There are three major steps:
  1. Down-sample the stills
  2. Crop the stills to some standard video format (here I chose to move the crop region 131 pixels (all the way down) since the earth was more interesting than the sky
  3. Use good old piping to massage the frames into an MPEG
The following script performs all this, and assumes that the captured images are named as gphoto2 names them, capt0000.jpg, capt0001.jpg, etc.

Here are the packages I needed:

  • netpbm-progs
  • mjpegtools



#!/bin/sh

echo "Resizing images to 720p (1280x720)..."
for JPG in capt????.jpg ;
do
TMPNAME=`echo $JPG | sed 's/capt/Mov/' | sed 's/\.jpg/\.ppm/'`;
if [ ! -f $TMPNAME ] ;
then
echo "$JPG";
CORRNAME=$JPG
# Resizing gives an image that is 1280x851, so I need to also crop and shift by 65 pixels (to crop the top and bottom equally)
convert -resize 1280x1280 -crop 1280x720+0+131 $CORRNAME $TMPNAME;
fi
done

echo "Compiling video...";
ls *.ppm | xargs cat | pamdepth 255 | ppmtoy4m -F 24:1 -S 420mpeg2 | yuvfps -s 4:1 -r 24:1 | mpeg2enc -f 12 -o timelapse.m1v


echo "Done!"
The last piping command
  • makes a list of all the PPM's (this could be more elegant),
  • makes them all arguments to cat (basically, sends them all to stdout),
  • decreases the PPM color depth to one byte (255 values),
  • translates the stream of PPM's to a Y4M stream using some standard MPEG settings (24 FPS, and 4:2:0 chroma subsampling mode),
  • repeats frames to make four distinct exposures per second but 24 video frames per second,
  • and finally compiles an MPEG using format 12 (ATSC 720p video).

And, finally, here is the fruit of my labor, which was originally 720p (1280x720 pixels), and 4 frames per second up-sampled to 24 frames per second. The framerate is a bit slow, so you might change the '-s' argument to 'yuvfps' to '8:1' to make it smoother, but with that I recommend to capture more frames per minute.


Yes, you can see my wall clock because a night-shift construction crew was lighting up my whole apartment.

For better results during daytime or night-time (not a transition between the two), I would recommend going to manual exposure control. This would make things a lot smoother.

So to recap, with gphoto2 you can:
  • Take more frames per minute, such as 4
  • Try making a scene using manual exposure control (like clouds or a tree)
  • Create a 1080p (1920×1080) video since your native resolution is probably higher

Watch more on YouTube: