3

I'd like to capture an image at a specified shutter speed and ISO, and write it to disk. I thought that'd be pretty straightforward but... apparently not? In searching, I found people complaining of the same thing 2 years ago but no answers... I guess I'm hoping something has changed.

import picamera
import time
from fractions import Fraction

start = time.time()
print "Initializing...",
camera = picamera.PiCamera()
camera.resolution = (2592,1944)
camera.awb_mode = 'sunlight'
camera.framerate = Fraction(1,15)
camera.exposure_mode = 'off'
camera.iso = 800
camera.shutter_speed = 6000000
print "Done! ",
stop = time.time()
print (stop-start), "seconds"

for i in range(0,10):
    start = time.time()
    print "capturing...",
    camera.capture('image.jpg', format='jpeg', quality=100)
    print "done  ",
    stop = time.time()
    print (stop-start), "seconds"

Initialization takes 0.59 seconds, fine no problem
First image takes 37.44 seconds
The rest take 24.9 seconds each

I'm fine with a bit of overhead, but the overhead is 3 times as long as the actual exposure! Any way around this? Or even an explanation of what's happening for the half-minute it's not taking the picture?

MattieShoes
  • 31
  • 1
  • 2
  • Try decreasing resolution, that might be the problem, and if that's not the problem also try changing other parameters for testing – Tolga Varol Aug 23 '15 at 12:03
  • Changing resolution doesn't fix it. Changing exposure time will reduce the time it takes, but that defeats the purpose of taking a long exposure. – MattieShoes Aug 24 '15 at 01:52
  • This is down to the way still port captures work: if I recall correctly, still port captures typically require three frame's worth of time due to the mode switching that goes on under the covers in the firmware (and because after a mode switch one frame is corrupt and needs to be thrown away). You can try capturing from the video port (use_video_port=True) which should bring things down to a single frame's worth of time (plus I/O) but the results will be much more "grainy". – Dave Jones Aug 24 '15 at 11:53
  • Did you ever find a solution? – hanno May 06 '16 at 20:16

1 Answers1

1

First up, you should profile your code, probably using cProfile:

https://docs.python.org/2/library/profile.html

Optimization without knowing where the time is spent is often pointless.

If the problem is mainly time to write to disk, you might try capturing to a stream/buffer, and then writing the buffer to disk with a side-process, perhaps using threading or an entire separate process which you pass the data to. This article describes how to capture to a stream:

http://picamera.readthedocs.org/en/latest/recipes1.html

This article describes how to use threading easily with the 'threading' library:

http://pymotw.com/2/threading/

Should be pretty easy, since you basically just want to fire off a thread to write data to a specified file each time the image capture is done...

sdenton4
  • 371
  • 2
  • 4
  • It's not the code -- the time spent is in camera.capture. Here's a command line version of the same thing, with the same results
        `$ time raspistill -t 1 -n -ss 6000000 -ISO 800 -awb "sun" -o test.jpg`
    
        `real    0m43.366s`
    
    

    I hadn't considered disk write being the culprit, but it turns out it's not -- I get the same results piping the output directly to /dev/null.

    – MattieShoes Aug 24 '15 at 01:44