Table of contents
A timelapse is an animation technique that consists in shooting frames at a certain speed and playing them back much faster, giving a greatly accelerated video effect. This allows to see happen in a few seconds phenomenon that normaly take hours, days, or months. It's great fun to watch, and with a little equipment and some patience, it can be quite easy to make your own.
I wanted to use only my point and shoot camera to take the shoots and free software to do the processing on the computer. I used a Canon Digital IXUS 750 (also known as SD550) camera with the CHDK firmware.
You need a camera capable of taking shots at periodic, programmable intervals to take the pictures. Most newer, higher-end cameras have the feature built-in, but you can do it too with a low-end Canon camera provided you install the CHDK firmware. It doesn't actually modify the firmware of the camera, so there is no risk to "brick" your camera and you can go back to the original firmware at any time.
A great feature of CHDK is that it can interpret BASIC or LUA script directly, which allows to completely automate the camera and add features normally only available on the higher-end models. I made a simple LUA script to take pictures at regular intervals. You can copy it below, and save it as timelapse.lua on your memory card (put it in the /CHDK/SCRIPTS/ directory). I only tested it with my Canon IXUS 750, and some features are not available, or behave differently on different cameras, so some tweaking may be in order. However for the most part it should be the same :
--[[ @title Time Lapse @param n Number of frames @default n 0 @param m Number of frames x100 @default m 1 @param i Interval in seconds @default i 5 @param d Delay before start @default d 3 @param r Refocus each frame (1=yes) @default r 0 ]] totalFrames = (n > 0 and n or 0) + (m > 0 and m or 0) * 100 interval = i > 0 and i*1000 or 1000; delay = d > 0 and d*1000 or 0; refocus = r == 1 and true or false print( "Shooting "..totalFrames.." frames every "..(interval/1000).."s for "..(totalFrames*interval/1000).."s." ) if delay > 0 then print( "Starting in "..(delay/1000).."s" ); sleep( delay ) end if not refocus then press( "shoot_half" ) sleep( 2000 ) -- Allow a little time to focus end nextTick = get_tick_count() + interval for i = 1, totalFrames do print( "Frame "..i.."/"..totalFrames ) if refocus then press( "shoot_half" ) sleep( 2000 ) end click( "shoot_full" ) if refocus then release( "shoot_half" ) end sleep( nextTick - get_tick_count() ) nextTick = nextTick + interval end if not refocus then release( "shoot_half" ) end
The script parameters are :
Example configuration :
You can then start the script :
Once the script ends, you'll hopefuly end up with a few thousand pictures. Now you need to process them into a movie. First copy everything in a temporary folder on your hard drive.
Avistynth is a very nice piece of software with allows to process videos through text scripts. It's extremely powerful, but the particular feature we're interested in is that it can use images as a video source.
If you've got a Canon camera like me you should have a directory structure with each directory containing a couple thousand pictures. Assuming you put the pictures in "e:/tmp/lapse/images/", here's what the Avisynth script could look like :
ImageSource(file = "e:/tmp/lapse/images/123CANON/IMG_%04d.jpg", start = 2001, end = 4000, fps = 30) +\ ImageSource(file = "e:/tmp/lapse/images/124CANON/IMG_%04d.jpg", start = 4001, end = 6000, fps = 30) +\ ImageSource(file = "e:/tmp/lapse/images/125CANON/IMG_%04d.jpg", start = 6001, end = 7000, fps = 30) # If you wish, you can also resize the images at this step. LanczosResize(800, 600) # You can crop too. Make sure the final dimensions are multiples of 8. Crop(20,20,760,560) # This last step is needed to make sure the image data is in a format friendly to the encoder. ConvertToYV12()
Since I'm lazy I made a small Python script to create the ImageSource part of the Avisynth script for me. It's pretty much a hack and works only if the images are named IMG_1234.jpg like on my camera. I'm not quite fluent in Python either, but it works. Change the path as needed :
import os base = "e:/tmp/lapse/images" folders = sorted(os.listdir(base)) for f in range(len(folders)): images = sorted(os.listdir(base+"/"+folders[f])) start = images[0][4:8] end = images[-1][4:8] print( "ImageSource(file = \""+base+"/"+folders[f]+"/"+"IMG_%04d.jpg\", start = "+start+", end = "+end+", fps = 30)", f!=len(folders)-1 and "+\\" or "" );
Avisynth does the frame processing, but not the actual encoding. The last tool we'll need for this last step is MeGUI. It's a very complete x264 encoding suite, and is intended to work with Avisynth scripts. Launch the tool and load our script :
Choose encoding settings suitable to your source images and the final video quality. There are many presets built-in but you can make your own if you want. Next click the "Enqueue" Button, and click on the "Queue" tab :
I chose a 2-pass encoding so there are 2 jobs. Now click start to launch the jobs. A progress window will pop up and after a while the final video will be generated.
Troubleshooting : if the job ends immediately with an error check the following :
Here is a sample video I made. Number of frames : 5000 (2s interval). Speedup factor : 60 (30 fps). Location : Paris, over the Parc Montsouris. Shoot date : 2009-06-11.
You can download the video files directly below :
Comments
9,10 $ pour un paquet de Kamel.
Jamais plus, le squelette de Renescure...
Marie qui me dit : il ne doit plus y avoir grand chose à enlever, hein Jean-Pierre !
Et les copains à Hervé qui, par un trou de la palissade, disaient : Ca respire...
Et enfin, Nathalie qui a dit : jamais de culotte, je l'ai vu.
J'ignorais qu'elle parlait de moi à ses amis.
Ben oui, j'aime ça, rien sous le short.
J'ai compris maintenant que j'étais visé.
Very Nice.
I finally have the script working on my A480 but even though refocusing is on 0, it does refocus every time before a photo is made..
I've copied the script and used VIM so I'm not missing any 'invisible code'.
Could you possibly help out?
Thanks!
keartan@gmail.com