All things Raspberry Pi and Time Lapse

Posts tagged ‘scripts’

ImageMagick scripts

I found this post here about a guy who took all of his shots from a year and compiled them into a single image. This sounded like a cool idea, but I could never find the code for how this was accomplished. But I figured that it shouldn’t be too hard so I set about doing it for myself. I have 21 images so far and I compiled them into these two images. One from right to left. And the other from bottom to top.

Once I have more images it should look better as each section will be considerably smaller. I achieved these results using a command line program called ImageMagick on Linux. It was a very simple install ‘yum install ImageMagick’ (notice the capital letters) since I am using Fedora and that was all. Debian based distros may be something like ‘sudo apt-get install ImageMagick’ but I have not tried it. The weird thing though was that I was actually using the command line tool ‘convert’ from the command line instead of ‘ImageMagick’. Great documentation available at their site about the usage here. And documentation specifically about the cropping here. The command line usage looks like this:

convert input_file XxY+X+Y output_file

The program uses the X and Y axis for where to crop. The top left corner of the image is 0x0. The +X+Y is offset from that initial 0x0. Check out the scripts below for actual usage in the script. I did the math before I ran the script and that is where the 92 and 73 come from. I took the dimension of the image and divided by the number of images that I had. So the first image is 2048 wide and I had 21 images. Then I rounded that number down to get the 92 that was used in the script.

This first script is for the top image cutting columns of the image.

#!/bin/bash
# jamesmiller
# get list of files in current directory
files=`ls | grep “^rasplapse*”`
# set the initial crop point
x_factor=0
# for each file in the current directory
for x in $files
do
# ImageMagick convert program to crop the image
convert $x -crop 92×0+$x_factor+0 column_$x
# add to the initial crop point so the next image
# is not the same strip as the previous image
x_factor=$((x_factor + 92))
# add a border of white
#convert column_$x -border 1x column_$x
done
# get the list of newly created images
column_files=`ls | grep “^column*”`
# add all of the strips of images into one image
convert $column_files +append column_file.jpg

This script is for the bottom image cutting rows of the image.

#!/bin/bash
# jamesmiller
# get list of files in current directory
files=`ls -r | grep “^rasplapse*”`
# set the initial crop point
x_factor=0
# for each file in the current directory
for x in $files
do
# ImageMagick convert program to crop the image
convert $x -crop 0x73+0+$x_factor row_$x
# add to the initial crop point so the next image
# is not the same strip as the previous image
x_factor=$((x_factor + 73))
done
# get the list of newly created images
row_files=`ls -r | grep “^row*”`
# add all of the strips of images into one image
convert $row_files -append row_file.jpg

The very last line of each script is what compiles all of the strips of images into one image. NOTE: these scripts are meant to be executed in the folder containing the images. And they may need to be modified to suit other uses depending on the file naming structure and so forth.

I also tried these scripts using the pictures that were taken every 2 minutes. But even separating them out into three different pictures it didn’t turn out that neat. There was very little change across the picture because not that much moved in a single day.

Looking forward to using this technique on more pictures like the pictures shown above once I have more images!

Advertisements

Updated scripts

I made some pretty major changes to the scripts after I figured out the problem with the camera card filling up. The changes were partly because of this, and partly to consolidate code to make it easier to make a minor change. The changes are as follows.

This is the main script to take a picture with gphoto2. Instead of having a separate script for each time the camera takes a picture I added the ability to add arguments to the script. This is represented by the $1 and $2 and so forth. When executing the script it now looks like this on the command line:

/path/to/script argument1 argument2

And as you might assume “argument1” gets assigned to $1 and “argument2 gets assigned to $2. This makes it possible to increase the flexibility of a script and reduce the number of scripts needed to the project to work. It also adds the ability to make a small change to the script and affect everything. Like for example if I want to change the aperture I only have to make one change instead of changing it in every script. The updated script is shown below.

#!/bin/bash
# jamesmiller
# 6-22-2012
#
# change directories to the correct folder to save the image
cd /root/$1
# check how many images are in the folder
before=`ls -l | wc -l`
# take the picture using gphoto2
gphoto2 –set-config shootingmode=3 –set-config aperture=9 –set-config shutterspeed=37 –set-config focusingpoint=0 –set-config imagequality=2 –capture-image-and-download –filename “%Y%m%d%H%M%S_$2.jpg”
# wait for 30 seconds to give the camera time to take the
# picture and save it.
sleep 30
# then check how many images are in the folder
after=`ls -l | wc -l`
# compare the before and after image count. If it is the same
# number then we assume that the image did not get downloaded
# and stayed in the folder on the camera card.
if [ $before == $after ]
then
# execute the download script to download that picture
/root/download_pics $2
fi

And the script that gets executed if the number of pictures stays the same is shown below. It is not commented at all, so I will update that when I have some time.

#!/bin/bash
# jamesmiller
cd /root
# use a here doc to list all directories in the main
# DCIM directory on the camera
dir=$(gphoto2 –shell << EOF |
cd store_00010001/DCIM/
ls
exit
EOF
grep CANON)
# for every directory in DCIM do these actions
for x in $dir
do
# except for this directory so that the card ALWAYS has
# one picture on it so it doesnt stop taking pictures
if [[ $x == 157* ]]
then
continue
else
# Use another here doc to list the files in each directory
img=$(gphoto2 –shell << EOF |
cd store_00010001/DCIM/$x
ls
exit
EOF
grep IMG)
# change directories to the camera card and the correct folder
gphoto2 –shell << EOF
cd store_00010001/DCIM/$x
# download the image to the main folder (/root) of the raspberrypi
get $img
# delete the image from the camera sd card
delete $img
cd ..
# remove the directory
rmdir $x
exit
EOF
# get the time stamp information from the image that was downloaded
tstamp=`stat $img | grep Modify | cut -d ” ” -f2,3 | cut -d “.” -f1 | tr ‘ ‘ ‘_’`
# rename the image that was labeled like IMG_1398 to a filename with the
# timestamp inforamation
mv $img $tstamp$1
# move that image to another folder to keep /root clean
mv $tstamp$1 canon_pics
fi
done

The general idea of the script is that it uses a Here document to accomplish its goals. It changes directories to the camera card, then gets the folders listed there. Then for each folder it downloads the images to the Raspberry Pi, deletes the images from the camera, and then deletes the folder. After that it renames the images (which needs some work) and saves them in a separate folder.

The crontab changed as well because of the changes to the main script.

@reboot /root/set_camera_time
@reboot /root/focuslock
1 12 * * * /root/camera pics_1day 1day
31 7 * * * /root/camera pics_7am 7am
31 15 * * * /root/camera pics_3pm 3pm
*/2 5-20 * * 3 /root/camera pics_2min 2min

This shows how the one main script is being used to take four different sets of images. And it labels them correctly and saves them in the correct folder so they do not get mixed with another time.

These scripts work using Arch Linux and a canon PowerShot A510. It should work with other setups, but I have not tested it with anything else.
I downloaded all of the pictures so far and it is looking amazing. It is possible to see the plants grow daily. The one issue I am having is with flicker. This is caused by a sunny day, then a cloudy day, then a sunny day. The camera is set to manual because on the auto feature it can change drastically between two sunny days, and cause more drastic changes than dealing with the problems of the manual settings. I am looking into the GBS (Granite Bay Software) plugin for After Effects which smooths the exposure across multiple images. From the initial test it looks like it did a very good job, but before I buy it I am looking to see about any other options (if there is any) and how they compare.

More about those images soon!

Back up and running

It is all setup again – as of Saturday – and should be taking pictures. Here is a shot of what it looks like now. All of the tomato plants have been removed and the new ones will be planted soon.

Something that started to concern me was Daylight Savings time. This would be a problem if the camera changed time and then the power went out. The raspberry pi would pull the new time and it would be an hour off of what it was before. I contacted Canon about this potential issue. And they tried to sell me one of their newer cameras that has this feature. But they said that the Canon Powershot A510 does not have this feature. I could not find this option on the SX100 either. However this is a good thing as it means I am safe from having to worry about that. It will definitely be something to think about in the future however.

I changed the way the scripts were written and so I will post them and the updated crontab hopefully sometime early next week.

gphoto2 camera scripts

I could not wait for my Raspberry Pi to arrive so I went ahead and wrote the scripts using gphoto to take pictures. These were written on a Fedora desktop, but since it is using standard Linux commands it should work from any distribution.

A very good tutorial on cron and at are availble here at IBM.

This first one is pretty standard. It will take a picture at noon once a day… The actual scheduling of the script will take place using the cron daemon.

#!/bin/bash
# jamesmiller
# 6-22-2012
#
# change directories to the correct folder to save the image
cd /home/jamesmiller/gphoto/1day
# actually take the picture using gphoto2
gphoto2 –capture-image-and-download –filename “%Y%m%d%H%M%S_1day.jpg”

Note the last line is supposed to be all on one line. The crontab entry for this first script will look like this… The twelve in the second position means to take the picture at 12:00 (noon) every day of the month, every month, every day of the week. Note that the time in cron uses a 24 hour clock.

0 12 * * * /home/jamesmiller/gphoto/1day

And the second one is very similar to the first. Except it will take a picture once every 5 minutes for an entire day on the first and fifth days of the month. In the final I will only use one of the days a month, but by shooting two days that gives me an error margin (if the power goes out that day) or some other unforeseen accident occurs.

#!/bin/bash
# jamesmiller
# 6-22-2012
#
# change directories to the correct folder to save the image
cd /home/jamesmiller/gphoto/5min
# actually take the picture using gphoto2
gphoto2 –capture-image-and-download –filename “%Y%m%d%H%M%S_5min.jpg”

Note the last line is supposed to be all on one line. This script is very similar to the last script except for the file location where it will store the images. This will keep the different scripts separate. However the crontab entry for this script is very different! The first (*/5) means to take a picture every 5 minutes, the second piece (4-20) means to only take the picture if the time is between 4am and 8pm, and the (1,5) means on the first and fifth of the month to execute. the last two stars mean every month, every day of the week. This script will provide a time-lapse that looks like 12 days – one for each month of the year.

*/5 4-20 1,5 * * /home/jamesmiller/gphoto/5min

The last script is more complicated. It uses cron and it also uses a different scheduling daemon called at.

#!/bin/bash
# jamesmiller
# 6-22-2012
#
# change directories to the correct folder to save the image
cd /home/jamesmiller/gphoto/1443min
# schedule the next runtime of this script
at -f ../camera_1443min now + 1443min
# store the date and time in a file to be read as the time
# when the picture was taken.
echo `date +%Y%m%d%H%M%S` >> ../1443_time
# actually take the picture using gphoto2
gphoto2 –capture-image-and-download –filename “%Y%m%d%H%M%S_1443min.jpg”

Note the last line is supposed to be all on one line. The purpose of this script is to take a picture at like 4:00am the first day, then the next day at 4:03, and the next day at 4:06 and so on. This last script will provide a very interesting time lapse as it will take one year and compress it into time lapse that looks like a day. It will start in the morning and end at night, but all 4 seasons will have passed. I am not totally sure at what time I want this to start, because there is no reason to take pictures in the dark. The cron details I have not finished working on yet, but I will add them here when I finish it.

cron details to follow

Those are my ideas for a year-long time lapse. This will give me three different looks into the scene over the course of a year. If anyone has other/more ideas for when the camera should take a picture do not hesitate to comment below!

Tag Cloud