How To Capture Time-Lapse Photography With Your Raspberry Pi and DSLR or USB Webcam

James Bruce 25-09-2013

Watch the clouds move or a seedling grow. Time-lapse photography can really give you a sense of how the world works on a macroscopic level, beyond anything conceivable to the normal human experience of time. Or other words: it can turn watching paint dry into something quite interesting. Unfortunately, professional time-lapse equipment – whilst adding the ability to rotate or move your camera – like the Genie can cost up to $1000. Today, we’ll make a basic time-lapse controller with no movement – for DSLR or a USB webcam – with just a Raspberry Pi.


Be sure to check out all our other great Raspberry Pi projects too.


As usual, all our work with the Pi will be done over an SSH command line, and we can grab the files using SFTP with the same credentials if you’ve stored them on Pi instead of the camera. If you’re not sure what the IP address of your Pi is, log on to your router and view the list of currently connected devices – it should be reporting itself correctly.


Begin by installing some essential software:

sudo apt-get install gphoto2
sudo apt-get install imagemagick

GPhoto2 is a command line utility to directly interface with supported DSLR cameras (view the full list here). I used a Canon Rebel T4i / 650D Canon Rebel T4i dSLR Review and Giveaway Canon has just released their new Rebel T4i – their first (of hopefully many) adventures into the touchscreen dSLR world. This camera is a step up from the Canon Rebel T3i (also making it the third... Read More . Now, connect your camera to the Pi via USB.


Since I’ve used automatic ISO values and AV mode, the setup is relatively simple and we can capture the series using just the command line – the utility includes built-in time lapse parameters. Here’s the most basic command you can use to test the capabilities:

gphoto2 --capture-image-and-download

which will transfer the file to your Pi, or

gphoto2 --capture-image

to keep the image on the camera. At 8 MB a pop, it’s possibly best to keep them on the camera and perform the movie stitching after the fact from a PC or Mac.

Important: By default, images are saved to SD-RAM, not the memory card in the camera. Meaning you will lose them all (I speak from experience). To ensure they actually save, we need to first set the capture target:

gphoto2 --get-config /main/settings/capturetarget

Look at the list it outputs and set the target as follows, replacing 1 with whichever is shown as your card.

gphoto2 --set-config /main/settings/capturetarget=1

To capture in time-lapse mode, append -F and -I to specify the total number of frames you want to capture, and the time interval between each one. In this example, capturing once every 30 seconds for a total of 1440 frames, which when made into a 24 FPS movie will equal about a minute. I don’t think my camera’s battery will last this long anyway, but I’ll see how many I get.

gphoto2 --capture-image -F 1440 -I 30

One quirk to bear in mind; after the command completes, the camera may turn off and becomes unresponsive – you will need to manually cycle the power switch (at least, on my model it did). This shouldn’t be a problem out in the field when in use, but for testing purposes it gets quite annoying. If you know a fix for this, let me know in the comments, please!



Making a Movie

Transfer the files to your desktop computer for processing. On a Mac, I’ve found the easiest is to use the command line, but you’ll need XCode, Homebrew, and MPlayer installed first. To do this, first download Xcode from the App Store (it’s free), then from the Preferences -> Downloads tab, enable Command Line Tools.


Then run (one at a time):

ruby <(curl -fsSkL
brew doctor
brew install mplayer



You should now have the necessary encoding components installed. Run the following commands to first create a list of the captured .jpg files, then feed that list into mencoder, a utility used to create videos. Change the FPS value if you’d prefer the movie go faster.

cd <directory with your time-lapse photos>
ls *.jpg > list.txt
mencoder -nosound -ovc lavc -lavcopts vcodec=mpeg4:aspect=16/9:vbitrate=8000000 -vf scale=640:480 -o timelapse.avi -mf type=jpeg:fps=24 mf://@list.txt

Here’s what I ended up with, using 24 FPS from 330 frames shot every minute from morning to mid-afternoon. The weather is Britain really is that bad, from sunny to overcast in 5 minute intervals throughout the day. Sigh.

To encode a movie in Windows, or if you prefer using a GUI, download Avidemux, and follow the video tutorial below. Make sure your photos are numbered sequentially.

Using a USB Webcam

Of course, not everyone has a DSLR, but rather than buying an expensive official camera module for the Raspberry Pi, you can also perform time-lapse photography using an off-the-shelf USB webcam – in my case, a PS3 Eye which is usually quite a hassle to get working on PC or Mac, but works out of the box on the Pi. You may need to use a powered USB hub, and camera support is sketchy.

First, check if your webcam has been detected correctly.

ls -l /dev/video*

Hopefully, you’ll see /dev/video0 listed like this:


Then we can go ahead with installing the webcam capture software, and take a test shot.

sudo apt-get install fswebcam
fswebcam -d /dev/video0 -r 640x480 test.jpeg

Delete the file with:

rm test.jpg

Take a few test shots to enable you to position the camera appropriately, then we’ll get on with the time-lapse script.

mkdir timelapse
nano runtimelapse

Paste in the following:

# Timelapse controller for USB webcam


while [ $x -le 1440 ]; do

filename=$(date -u +"%d%m%Y_%H%M-%S").jpg

fswebcam -d /dev/video0 -r 640x480 $DIR/$filename

x=$(( $x + 1 ))

sleep 10;


For testing purposes, I’ve set the wait time between shots as 10 seconds. When you actually start capturing, you might want to change that to every minute instead. Change the following line to determine how many frames to capture, in the example it’s set as 1440:

while [ $x -le 1440 ]; do

To make the script executable, use:

chmod 755 runtimelapse

Then run it using:



Making a Movie

Still on the SSH command line, we’ll try stitching the movie directly on the Pi – if you’ve taken thousands of shots and your webcam is higher resolution, you may find this is appallingly slow, in which case scroll up to the movie instructions for DSLR, and transfer the files to your PC using SFTP.


cd timelapse
ls *.jpg > list.txt
sudo apt-get install mencoder
mencoder -nosound -ovc lavc -lavcopts vcodec=mpeg4:aspect=16/9:vbitrate=8000000 -vf scale=640:480 -o timelapse.avi -mf type=jpeg:fps=24 mf://@list.txt

If it all seems well but you get a 0 KB file output, it means there’s not enough space on your devices temp folder. I solved this with a clean installation and expanding the root system again – it seems BTSync had messed up some temp files.

Here’s the finished scene from a USB webcam, from late afternoon to dark.

This was far easier than I thought it would be – and I wouldn’t be surprised to find someone in the comments detailing an even easier method! Give it a go for a fascinating view of life that’s otherwise difficult to comprehend, and share a link to your creations in the comments or other time lapse videos you’ve found particularly inspiring.

Related topics: Photography, Raspberry Pi.

Affiliate Disclosure: By buying the products we recommend, you help keep the site alive. Read more.

Whatsapp Pinterest

Leave a Reply

Your email address will not be published. Required fields are marked *

  1. John
    April 8, 2017 at 3:46 am

    Sorry, but how do you edit the file to add more seconds to the script as you mentioned in your write up? Guess you simply recreate the file, making the changes in seconds to elapse between shots, then make it executable and run 'er again. Just a guess at this time. Also, could you show us (or point us an example you have already done) showing running this executable as a chron job? Thanks! Excellent and useful example of how this all works.

    One thing I found out when using a Logitech HD camera. They work great, but you gotta have a good 5volt power supply for your little Pi. The HD camera apparently likes power and the pi started re-booting when I initiated the script. Was running it off a TV USB port, so figured that one out pretty quick.

    • James Bruce
      April 14, 2017 at 7:28 am

      Hi John, just increase the number of second specified in:

      sleep 10;

      to 60, for a minute between shots.

      This is quite old now, I'm afraid I don't have an example of it running as a CRON anymore. Here's an example of the CRON being used for another Python script you might be able to tweak though: //

  2. Jitesh
    January 25, 2017 at 1:18 pm


    We are trying to use raspberry pi to click photos at a shorter interval than 1 sec.

    gphoto2 --capture-image -F 2 -I 1

    We used this command, but if we go for interval less than 1 second it does not work, all i get is one click.

    Is there a way we can get photos at interval of 250 ms or so?

    I am using Canon 6D

    • James Bruce
      April 14, 2017 at 7:29 am

      Unlikely. This is the same as you pressing the shutter button on your camera. You can't press it that quickly!

  3. Brian
    January 28, 2014 at 12:49 am

    Can someone give instructions how to do this with an IP camera ?

  4. jussi
    December 25, 2013 at 5:25 pm


    I took test shot with my webcam but it's black and has date in center of it. Weird.

  5. drew
    December 7, 2013 at 2:28 pm

    Thank you so much. After a few small tests, I am running my first timelapse photography now (webcam).

    The pictures are coming out as expected although when a JPEG is created, I get a "corrupt JPEG data: 1 extraneous byte before marker 0xd1". Again, I can open them with the Pi, so I don't know how corrupt the files actually are. Will this be a problem when I try to make a movie?

    Thanks again,

  6. laxx
    November 20, 2013 at 10:58 pm

    Great work, James! This helps me a lot to get in touch with my new Raspberry Pi, working with networks cams and OpenCV/SimpleCV with Python.
    Everything works perfect for me.

    Greetings from good'ol' Germany.


  7. Tharun
    November 16, 2013 at 6:06 am

    I am getting following error:

    Error opening file for output: /
    fopen: Is a directory

    I am unable to figure out the reason behind this error. I just bought raspberry and I am new to programming as well. Please help. Thanks

    • James B
      November 16, 2013 at 9:58 am

      Given how generic that is, you'd need to post more information. At which step did this occur? Did you start again from the beginning and double check every step?

      • Edmon
        December 8, 2016 at 12:54 am

        On the output part of "./runtimelapse". Displaying the "Error opening file for output: /
        fopen: Is a directory"

        thanks for your response.

        • James Bruce
          December 8, 2016 at 10:00 am

          Since fopen isn't in my part of the code, it would appear to be coming from the fswebcam software. It's possible they've changed the command needed to run it - check the documentation for that and adjust accordingly.

  8. Tim
    November 12, 2013 at 2:17 am

    That's really helpful. I'm definitely going to use it! Thanks.

  9. Dr Hitchcock
    November 5, 2013 at 12:10 am

    Great write up!

    Did you ever have any trouble with the error:
    gd-jpeg: JPEG library reports unrecoverable error: Not a JPEG file: starts with 0xff 0x80

    I've posted it over in the official Raspberry Pi forum as well:

    Many thanks,
    Dr Hitchcock