I really liked this article which showed how to use a Raspberry Pi to create a stunning timelapse video, of course filming in a fantastic location helped. Having read it I wondered if it was possible to do the same thing with any linux machine and a USB webcam.
I have to admit that with the cheap webcams I tried the results are not as good. Though you can use a web camera with any linux system if you have a Raspberry Pi the Camera module is quite a bit better, my own notes on setting one up are here.
As with any camera it probably is worth paying close attention to things like lighting and so on in order to get decent results. In particular I found that the webcams I tried did not cope well with scenes that had a lot of contrast between light and dark and were easily saturated by any bright light source or reflections (a polaroid filter might help). Also do not forget that when recording images over a long period of time the direction that the light is coming from will change.
Sorting out the hardware is as simple as plugging in your USB webcam (you can check which ones are supported on the Raspberry Pi here) and pointing it at something interesting that isn’t going to move much – a sleeping cat is ideal.
Next to capture an image from a webcam we need to install the required software. I tried both uvccapture and fswebcam on both the Raspberry Pi and my PC and after some experimentation I decided that the results were more consistent when using fswebcam, probably due to the capability of the software to skip the initial frames when capturing an image. This seems to give the cameras I used more time to settle and work out what the correct exposure should be for the current lighting conditions. I also found that compiling fswebcam on the old version of Debian I use on my desktop PC was a doddle (OK I admit it – I’m still running a very very old version!).
To install anything you need to be running as root.
$ su Password:
$ sudo -i Password:
Then just grab the required packages from the repository.
# apt-get install fswebcam Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: libfreetype6 libgd2-noxpm Suggested packages: libgd-tools The following NEW packages will be installed: fswebcam libfreetype6 libgd2-noxpm 0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded. Need to get 0 B/674 kB of archives. After this operation, 1,457 kB of disk space will be used. Do you want to continue [Y/n]? Y : : : # apt-get install mencoder Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: esound-common libaudiofile1 libesd0 libgif4 liblircclient0 liblzo2-2 libsdl1.2debian libsvga1 libvdpau1 libx86-1 mplayer Suggested packages: pulseaudio-esound-compat lirc nvidia-vdpau-driver vdpau-driver mplayer-doc ttf-freefont netselect fping The following NEW packages will be installed: esound-common libaudiofile1 libesd0 libgif4 liblircclient0 liblzo2-2 libsdl1.2debian libsvga1 libvdpau1 libx86-1 mencoder mplayer 0 upgraded, 12 newly installed, 0 to remove and 0 not upgraded. Need to get 5,251 kB of archives. After this operation, 11.5 MB of additional disk space will be used. Do you want to continue [Y/n]? Y : : : #
If the fswebcam package isn’t available you will need to down load it and compile it from the current source, to avoid problems later install the prerequisites first.
# apt-get install libgd2-noxpm-dev Reading package lists... Done Building dependency tree Reading state information... Done The following NEW packages will be installed: libgd2-noxpm-dev 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 357kB of archives. : : : # exit
Download fswebcam-20110717.tar.gz and unpack the source code.
$ tar -xf fswebcam-20110717.tar.gz
Configure the environment.
$ cd fswebcam-20110717 $ ./configure --prefix=/usr checking for gcc... gcc checking whether the C compiler works... yes : : : Buffer type ........... 16 bit PNG support ........... yes JPEG support .......... yes Freetype 2.x support .. yes V4L1 support .......... yes V4L2 support .......... yes configure: creating ./config.status config.status: creating Makefile config.status: creating config.h
If configure does not report any errors then use make to compile the program.
$ make gcc -g -O2 -DHAVE_CONFIG_H -c fswebcam.c -o fswebcam.o : : :
Finally install it to make it available to all users.
$ su Password: # make install mkdir -p /usr/bin mkdir -p /usr/share/man/man1 install -m 755 fswebcam /usr/bin install -m 644 fswebcam.1.gz /usr/share/man/man1 #
Next we need to create a couple of scripts to do the hard work for us – I’ve assumed that we will be saving the images in the same folder as the web root. I’ve assumed that this will be /home/httpd, but you can change it to what ever you want.
The first script uses fswebcam (or uvccapture) to update the current image at regular intervals, this then calls the second script to save this image in the same folder with a filename that includes a timestamp allowing the images to be combined later to produce a time lapse video.
On the Raspberry Pi I found that the capturing one image every four seconds was about as fast as could be achieved reliably, particularly when using resolutions higher than 640×480.
/usr/local/bin/update.sh #!/bin/bash # # Usage: update # # Updates an image every few seconds and saves it in a # folder, typically the web root so it can be accessed # remotely using a web browser. Each time the image is # updated a second script is invoked to copy the image # and save it with filename that includes a time stamp # so that the images can be combined later producing a # time lapse video. # width=640 height=480 interval=4 output=/home/httpd/webcam.jpg capture=/usr/local/bin/capture.sh # # Uncomment the following lines if using uvccapture. # # brightness=96 # saturation=32 # contrast=32 # gain=16 # exec uvccapture -v -m -t$((interval)) \ # -B$brightness -S$saturation -C$contrast -G$gain \ # -c$capture \ # -x$width -y$height -o$output # # Comment out the following lines if using uvccapture. # font=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf exec fswebcam --quiet --skip 14 \ --font $font \--timestamp '%d %b %y %H:%M:%S (%Z)' \ --no-title -r $height\x$width \ --banner-colour '#FF000000' \ --line-colour '#FF000000' \ --exec $capture \ --loop $interval $output #
/usr/local/bin/capture.sh #!/bin/bash # # Usage: capture # # Copy the current image and saves with a timestamp to # allow the images can be combined to later to produce # a time lapse video. # # Any parameters are ignored allowing the script to be # work regardless of whether uvccapture of fswebcam is # used. # timestamp=$(date -u +"%y%m%d-%H:%M:%S") image=/home/httpd/webcam.jpg output=/home/httpd/capture-$timestamp.jpg cp $image $output #
To have the Raspberry Pi start capturing images automatically when it boots edit the local start up script.
# vi /etc/rc.local
Insert the line shown below.
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the # execution bits. # # By default this script does nothing. /usr/local/bin/update.sh || true & exit 0
It is a wrap
That is about all there is to it really, having captured your images all you need to do is to encode them using mencoder. You may need to change the values for the height and width if your images are a different size, and you can adjust the value for the crf (Constant Ratefactor) – lower values will produce a larger, higher quality video.
The default is 23 but I found that using a value of 16 produced a better quality result that was not so large as the be unmanageable.
$ mencoder -nosound \ > mf://*.jpg -mf w=640:h=480:type=jpg:fps=20 \ > -ovc x264 -x264encopts pass=1:crf=16 \ > -lavfopts format=mp4 \ > -o time-lapse-video.mp4
The ‘video’ above is actually an animated GIF (the best I can do using WordPress), the frame rate on the actual video is a lot higher and appears much smoother.
Raspberry Pi is a trademark of the Raspberry Pi Foundation