I was growing some ground cherry plants in pots and it seemed like their growth was exploding so I wanted to make a timelapse video like I had seen on youtube to get a sense of their growth rate.
I decided to make my timelapse using fswebcam to take the frames, imagemagick to add a nice timestamp, and avconv (fork of ffmpeg) to combine them into one video. There are simpler tools to capture the frames with but fswebcam has some very useful options which some people might need depending on their webcam, I’ll get into this later down in the code.
I have used these exact instructions on fresh installations of Ubuntu and Mint Linux on my laptop, and have also used them with my Raspberry Pi and it worked just the same.
If you use an original Raspberry Pi you may need an externally powered USB hub to actually use any decent webcam because it can draw too much power, if you’re using a Raspberry Pi B+ or a Raspberry Pi 2 then you can adjust a config file setting to allow your RPI B+/RPI 2 to allow higher power consumption on USB ports.
I am not an expert on this sort of stuff but you can read more about it here, the website gives instructions for the B+ but they also work for the Raspberry Pi 2.
First we’ll need to install the latest version of fswebcam, avconv, v4l-utils, and imagemagick . I’m doing this on a laptop running Linux Mint 17.1 which is Ubuntu based so if you’re using a different package manager like yum (Fedora) or pacman (Arch Linux) you’ll have to change the installation command accordingly, these packages should be available for most systems. Run these commands in your prefered terminal.
sudo apt-get install fswebcam libav-tools imagemagick v4l-utils
Make sure your webcam is plugged in and run this command so we can see the path to our webcam
ls -ltrh /dev/video*
On my system this outputs the following:
This tells us that our webcam is connected and the system recognizes it, so now we’re going to make a new directory and setup the script we’ll use to take the pictures with our webcam. If you’re using a laptop with a built in webcam it should show 2 webcams, you’ll just have to test both to see which webcam you want to use.
Next we’re going to get the max resolution for our webcam using the following command, since my webcam was on /dev/video0 that’s what I will use
v4l2-ctl --list-formats-ext -d /dev/video0 | grep Size
this commands returns
Size: Discrete 640x360 Size: Discrete 320x240 Size: Discrete 640x480 Size: Discrete 960x720 Size: Discrete 1280x720 Size: Discrete 640x360 Size: Discrete 320x240 Size: Discrete 640x480 Size: Discrete 960x720 Size: Discrete 1280x720
As you can see 1280×720 is the max resolution so that’s what I will use.
Capturing the timelapse frames
Make the directory and then cd into it.
cd ~/ mkdir timelapse cd timelapse/ mkdir frames
Next we’re going to use nano to edit our script file, you can substitute your preferred text editor if you like.
now copy and paste this script into the file (ctrl+shift+v in a terminal)
#!/bin/bash # Timelapse controller for USB webcam DIR=frames #counter for filename n=1 #counter for files saved x=1 #number of screenshots to take num=10000 #interval at which screenshots get taken in seconds interval=5 while [ $x -le $num ]; do filename=$(printf "%05d.jpg" "$n") let n=n+1 #Capture image fswebcam -d /dev/video0 -S 5 -D 1 -r 1280x720 --jpeg 95 --no-banner --save $DIR/$filename #add timestamp with imagemagick convert $DIR/$filename -pointsize 30 -fill white -stroke black -gravity southeast -annotate +4+0 "$(date +"%D %r")" $DIR/$filename x=$(( $x + 1 )) sleep $interval; done;
Next make the script executable with the following command
chmod +X timelapse.sh
You can modify the script based on your needs, most of the things are self explanatory if you read the comments. I had to use the -S and -D switches because my webcam takes a few seconds to turn on and adjust to light levels, -D turns on the webcam and waits a specified number of seconds to ensure the webcam is actually on and -S skips a set number of frames to give my webcam time to adjust to light levels.
You may not need these settings or you may need to adjust them to use a longer delay or to skip more frames, just mess around with it until you find something that works for you.
I used imagemagick to add timestamps because the timestamp in fswebcam has this ugly overlay that you can’t turn off and still keep the timestamp. If you want to adjust your timestamp format check out the man page for date and adjust it in the script to your liking.
Once you’ve changed everything you want to change then you can go ahead and run the script.
If all goes well you should start getting images in the frames folder, let the script run for however long you want your timelapse to be and then continue reading on how to turn the images into a video file.
Creating the video
cd into your frames directory and run the following command
avconv -r 5 -i %05d.jpg -vcodec libx264 -r 30 output.mp4
I’ll try to explain the reason why I have 2 -r switches but I don’t know the terminology 100%, I just tried to explain it in an easy way so please don’t be upset if I’ve worded things wrong.
In this command the -r switch sets fps and is used twice, the first -r switch sets the fps that you actually want your video to display and the second -r switch sets the fps of the video file. If i set the input -r switch to 5 and the output -r switch to 30 then it will duplicate each frame 6 times to give the illusion of 5 fps while letting the video container have 30 fps.
If I were make the first switch higher than the last switch, say 60 for the first and the last switch 30 then avconv would skip every other frame, you will have to play around with skipping frames sometimes to get a timelapse that looks good if you didn’t use a long enough interval. If you don’t want to duplicate or remove any frames you can remove the first -r switch and just set the last switch to what you want it to be.
Let avconv combine all of your frames and then when it’s done you should have a file output.mp4 which will be your timelapse.
Here’s the timelapse I made
I was using a Creative Live! Cam Sync HD 720P webcam which I would probably give a 5/10 quality wise, the video was very obviously just stretched from some lower resolution to 720p, it ran at like 10fps, on a sunny day the image was very washed out white, and in any amount of darkness the video quality is very poor. I didn’t expect much for $20 but I would definitely get something higher quality like a Logitech C920 or a Logitech C310.