While chatting with a friend today about my new Venus Flytrap plant they asked to see it catch a fly .. well that’s kind hard to capture as it’s a lot of chance (unless you shove a fly into one of the traps). So I got to thinking, I can use my Raspberry Pi and the RaspiCam to take time lapse photos using raspistill then stitch them all together into a video.
Read on to find out how I made this happen …
There are lots of resources out there for using raspistill to take images and use the built in time lapse options (Here’s a decent one), in the simplest form this is all you need
This will capture one image every 1000ms (1sec) over a period of 5000ms (5 seconds), the %04d is replaced with a 4 digit number that starts at 0001 and increments with each new image.
raspistill -o timelapse%04d.jpg -t 5000 -tl 1000
There is one issue with this, if you run it twice in the same directory your images will be overwritten.
While that works fine, I just couldn’t leave it there. I like to wrap simple one line scripts with 100’s more lines to keep it company. So I knocked up this script
Running the script with no options outputs the help page for you, here it is
You need to provide at least 3 command line variables for this script.
ARG1 = Subject – The subject of the time lapse (no spaces allowed), ie: flytrap
ARG2 = Runtime – In seconds, how long to capture for? ie: 100 (seconds)
ARG3 = Captime – In seconds (or parts of) when to capture, ie: 0.2 (200ms)
Optional, if not specified Full Landscape will be used
ARG4 = CapSize – Size of the image you want to capture, pick from these
1 – Full – Landscape (2592 H x 1944 W)
2 – Full – Portrait (1944 H x 2592 W)
3 – Large – Landscape (1600 H x 1200 W)
4 – Large – Portrait (1200 H x 1600 W)
5 – Medium – Landscape (1024 H x 768 W)
6 – Medium – Portrait (768 H x 1024 W)
7 – Small – Landscape (800 H x 600 W)
8 – Small – Portrait (600 H x 800 W)
If you want to only capture 1 image use 1 and 1 for ARG 2 and 3, ie:
./picam-timelapse.sh mysubject 1 1
The only requirement is that you provide 3 options, the 4th option is entirely optional and controls the image size.
Lets have a look under the bonnet:
There shouldn’t be much that you need to edit to make this work right out of the box, the only line that really should change is
# Set this to the root path of where you will store images, a new folder $SUBJECT will be created here
# ie: /media/bigUSBhdd/timelapse/
This is the base directory of where you want stuff to go, under $CAPATH the script will create a directory that matches $SUBJECT (cmdline $1), so if you name the subject as MyStreet or FlyTrap then your photos will be stored in $CAPPATH/MyStreet/ or $CAPPATH/FlyTrap, simple enough isn’t it?
The thing you might want to tweak are the default camera options, my defaults are:
# Add / Remove any options you want here, however don’t add -h or -v to sizes, thats done later in the script,
# the output and capture timings will also be added later (-o, -t and -tl)
CAMOPS=" -sh 100 -awb auto -ex auto -q 100 -vf "
As the note says, don’t specify the output file or image resolution here, this will be done later. You can read up on the options I’ve picked by going to the man page or head over to the RaspiCam page.
If you dig into the script you’ll see where I set the image resolution and there is an approximate image size (on disk) at that size, the image size is used to give you an indication of how many images you’ll end up with during your run and an approximate space those images will require.
This is the output from an actual time lapse run I currently have going on while I type this up…
rmckenzi@pi1 ~ $ timelapse.sh flytrap 72000 10 5
Setting image size…
Working dir: /export/storage2/rmckenzi/timelapse/
RUNTIME: 72000 (seconds)
CRUNTIME: 72000000 (ms)
CAPTIME: 10 (seconds)
CCAPTIME: 10000 (ms)
Image size: -h 1024 -w 768
Number of photos to be: 7200
Estimate disk space of capture run: 4078 meg
So here I’m capturing using the “medium landscape” sized images, every 10 seconds for 72,000 seconds (20 hours). I should get 7200 images using just over 4GB of disk.
The image resolution is handled (currently) in the function setsize a snippit of that area:
IMAGESIZE=" -h 2592 -w 1944 "
IMAGESIZE=" -h 1944 -w 2592 "
IMAGESIZE=" -h 1600 -w 1200 "
IMAGESIZE=" -h 1200 -w 1600 "
IMAGESIZE=" -h 1024 -w 768 "
The contents of ISPACE is just an approx. value in KB of how big the images are, these were taken from my camera shooting the same scene in the same light at different resolutions, the amount of light (ie: day or night) will change the image size, night (all black) images are smaller. I want to redo this section and use an array of some sort for the resolutions, but currently I’m just storing the –h and –w values then shove those into the command line for raspistill later on.
My ToDo list for the script:
– Add options to allow custom image resolution from the command line
– Tweak status output text
– Add options to allow times to be specified in other formats such as 1d (86400 seconds), 1h (3600 seconds), 8h (28800 seconds), etc.
– Find a way to protect existing images from getting overwritten, most likely adding a date code or something to image names or just move the $SUBJECT to a new name (and again have to protect that directory as well)
Any other suggestions?
I may also add options to turn the images into a movie, however doing this on the RPi itself could be very time consuming, I plan to use another server to do this work for me.
If you try the script out I’d like to hear how you get on with it, I’d also like to hear how you change it to make it better for you!
I’m releasing this script to the wild for anyone to use as they see fit, I only ask that you please give credit to me for the work I’ve put into the script.