5

I'm using my Raspberry Pi with the RPi camera board to capture a time-lapse video of outdoor scenery using the raspistill command. As I am uploading the photos to a server after I take each photo, I'm not using the in-built time lapse functionality, but instead running a cronjob which runs this script every minute:

filename=$(date +"%d%m%Y_%H%M-%S").jpg
raspistill --width 1280 --height 960 --quality 100 --timeout 500 --encoding jpg -sh 0 -co 0 -br 50 -sa 0 -ev 0 --exposure snow --awb sun --ISO 100 --metering average --nopreview --output $PROJECTDIR/$IMAGEDIR/$filename
# some additional code I use to upload the files.

As I'm running the same code to capture photos throughout the day and into the night, I need the code to chose appropriate shutter speeds that allow the image to be correctly lit.

One possible approach to getting consistent lighting is to fix a shutter speed. However, I found that this approach was not general enough. Setting --ss 1000, or a shutter speed of 1ms, is great for sunny days, but a shutter speed at least four times as long is required for good images on cloudy days (forget about night photography!)

As such, I have to rely on the camera's internal metering. This gives me a degree of flexibility since it modifies the shutter speed according to the total light coming in, giving decent photos both in the day and in the night. However, using the default settings on the camera leads to images which are generally underexposed, whatever the conditions. I've tried playing around with --ev, --brightness and so on, but the results are not consistent.

One approach that I've found to work is by changing the --timeout settings on the camera. In general, the shorter the --timeout chosen, the slower the shutter speed is likely to be (and the brighter the resulting image).

Without setting a fixed value for shutter speed, I've found that the Raspberry Pi chooses a good shutter speed in sunny conditions when --timeout is set at 500. However, on cloudy days and for night-time, the resulting image from --timeout 500 is too dark, and I have to reduce --timeout to 200.

Here is a bit of data on the shutter speeds the camera chooses.

Sunny Days:

  • --timeout 500: exposure 1/1060 s
  • --timeout 200: exposure 1/366 s

If it helps for me to upload the images, please mention in a comment below.

  • Do you get similar results when using other metering modes, e.g. --metering matrix? – maniacyak Dec 16 '13 at 20:32
  • I've tried --spot and --average metering - the documentation isn't clear as to how either works, but I thought --average would be a sensible way to meter for outdoor images. I'm willing to try matrix too once I get my Pi back up running though. – Vincent Tjeng Dec 16 '13 at 20:34
  • If someone could point me to documentation explaining how metering works, I'd be very happy too :) – Vincent Tjeng Dec 16 '13 at 20:34
  • I have no knowledge as to how metering modes are implemented on the RPi camera specifically, but try these links to get a better understanding of how metering and exposure work in general. Average metering is just what it sounds like: adjusting exposure to compensate for the brightest and darkest areas of the frame. – maniacyak Dec 16 '13 at 21:13
  • I originally suggested matrix because it's usually the "smartest" of the available modes on most cameras. Unfortunately however I don't yet have a Pi camera to play with so I don't know how well it works for that. – maniacyak Dec 16 '13 at 21:16
8

I've been working on a bit of Python code to do exactly this. You can find it here: https://github.com/sdenton4/pipic And there's an example timelapse here: http://inventingsituations.net/2014/01/01/pilapse3/

You should note that both shutter speed (SS) and ISO are directly controllable with recent firmware. (Run sudo rpi-update to get the latest firmware and raspistill.) Both of these influence the overall brightness of an image, and to get consistent lighting over a timelapse you'll need to directly control both. Relying on any kind of auto-exposure is bad, because the auto-exposure will make different decisions for SS and ISO from one image to the next, which will result in considerable flicker in your timelapse. And you should disable the automatic white balance, for the same reason. (Also also, I believe that using both --exposure and --ISO conflict; don't use --exposure if you're manually setting ISO and SS.)

I should also note that the sensor tends to lock up if you ask it for shots with a shutter speed of more than 2.5 seconds. (Actually, a little more than 2.5s seems to still be ok, but I've never had trouble with 2.5s shots.) This sometimes causes the sensor to lock up if you're using auto-exposure settings; since switching to setting SS manually with a hard maximum of 2.5s, I haven't had any problems with sensor lockup; this is another good argument for manually setting SS and ISO.

I initially was doing a cron-based image capture, but have switched to running a single Python script, which can remember a collection of SS and ISO values. I then have an @reboot command in cron which starts the timelapse.py script automatically when the Pi powers up. I've also set up my timelapse program to ignore images that are too far from my favorite brightness; this lets me avoid ending up with massive piles of too-dark shots from the middle of the night. (I was keeping the night shots in the linked example, though, to good effect!)

My approach has been to:

  1. Run an initial sequence of 'fast' image captures to find an appropriate initial shutter speed and ISO. This usually takes about eight seconds, for standard room lighting.
  2. Once initial values are known, slow down to taking pictures at the desired intervals. We keep a list of the brightness of the last 10 or so images, and dynamically adjust the SS and ISO to maintain a constant average brightness.
  3. I've also set it up to throw out images that are too far away from the desired brightness; this lets me run the timelapse overnight for months without worrying about running out of disk space. By averaging over ten images, we prevent individual outlier images from having too much effect on our SS and ISO, while also being sensitive to overall change in the image (from, say, the sun setting).

The code I've written is set up to increase SS before increasing ISO, since I'm interested in having less sensor noise, and don't care much about motion blur.

Another way to attack the problem is to do some regression analysis on the camera sensor and essentially write your own metering algorithm. But you'll still only want to use the metering to get an initial value for the SS and ISO, and then either keep them constant or slowly change them over time. I've been playing with this approach, too, and hope to put up a blog post about it in the next couple weeks. It should let me bring down the eight second warm-up time for the timelapse to about 1 second.

Hope that's helpful!

  • Hi Tom, it looks like you've implemented a bunch of things that I'm interested in! There are several questions I have which I would like to address in separate comments. – Vincent Tjeng Jan 11 '14 at 3:37
  • 1. You mention that you attempt to maintain a constant average brightness; does this mean that the algorithm attempts to maintain the same overall brightness during both night and day? This doesn't seem to be the case from the time-lapse that I viewed on your website. Otherwise, how does your algorithm identify when it is appropriate to allow the overall brightness to reduce? – Vincent Tjeng Jan 11 '14 at 3:38
  • 2. I have had a similar problem of the white balance changing, even though I have set --exposure snow --awb sun. Do you have any idea why this happens? My assumption is that only the shutter speed should change in this situation. – Vincent Tjeng Jan 11 '14 at 3:41
  • 3. Does your Python script experience the time 'drift' that I describe here? raspberrypi.stackexchange.com/questions/12249/… I decided to run my timelapse as a cron job as a result, but if Python can give a similar degree of temporal accuracy (capturing images on the minute every minute, I would be very happy to use it). – Vincent Tjeng Jan 11 '14 at 3:44
  • 1
    If you're playing with the script I linked to, there's a command line option for the target brightness (or you can just change the default variable in the script directly). If you would like a brighter image, you can just provide a different value, between 0 and 255 - the default is 100. – sdenton4 Jan 14 '14 at 4:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.