waveform80 / picamera

A pure Python interface to the Raspberry Pi camera module
https://picamera.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
1.57k stars 355 forks source link

Some actions requiere very long time #180

Closed snoygues closed 9 years ago

snoygues commented 10 years ago

I sue last picamera 1.8 on raspberry with last 09/09/2014 firmware from Adafruit (use of Pitft screen). Some actions requiere very long time as :

whereas some others are quite short :

Is it normal ? is there a solution to reduce delay ?

snoygues commented 10 years ago

I did additional test with two official last Rpi firmware :

I run following python code : import picamera import time import numpy as np from fractions import Fraction

t0 = time.time() Camera = picamera.PiCamera() print("Camera = picamera.PiCamera() : ", "%0.3f" % (time.time()-t0))

t0 = time.time() Camera.resolution = (256, 192) print("Camera.resolution = (256, 192) : ", "%0.3f" % (time.time()-t0))

t0 = time.time() Camera.framerate = 1 print("Camera.framerate = 1 : ", "%0.3f" % (time.time()-t0))

t0 = time.time() Camera.ISO = 100 print("Camera.ISO = 100 : ", "%0.3f" % (time.time()-t0))

t0 = time.time() stream = open('image.data', 'w+b') print("stream = open('image.data', 'w+b') : ", "%0.3f" % (time.time()-t0))

t0 = time.time() Camera.capture(stream, 'yuv') print("Camera.capture(stream, 'yuv') : ", "%0.3f" % (time.time()-t0))

t0 = time.time() stream.seek(0) print("stream.seek(0) : ", "%0.3f" % (time.time()-t0))

t0 = time.time() Y = np.fromfile(stream, dtype=np.uint8, count=256_192).reshape((192, 256)) print("Y = np.fromfile(stream, dtype=np.uint8, count=256_192)... : ", "%0.3f" % (time.time()-t0))

Results are :

Camera = picamera.PiCamera() : 0.546 Camera.resolution = (256, 192) : 0.337 Camera.framerate = 1 : 0.342 Camera.ISO = 100 : 0.001 stream = open('image.data', 'w+b') : 0.003 Camera.capture(stream, 'yuv') : 2.717 stream.seek(0) : 0.002 Y = np.fromfile(stream, dtype=np.uint8, count=256*192)... : 0.002

Camera = picamera.PiCamera() : 1.217 Camera.resolution = (256, 192) : 1.090 Camera.framerate = 1 : 1.023 Camera.ISO = 100 : 0.001 stream = open('image.data', 'w+b') : 0.001 Camera.capture(stream, 'yuv') : 4.351 stream.seek(0) : 0.000 Y = np.fromfile(stream, dtype=np.uint8, count=256*192)... : 0.001

Some operations are now very long (x3) are take more than 1s.

waveform80 commented 10 years ago

Unfortunately you are correct that later firmwares take far longer to initialise than earlier ones; sometime around when stereoscopic support got added to the firmware (for the compute module), I noticed runtimes on the picamera test suite jumped from about an hour and a half to over four hours! I figured out it was down to the initialisation time increasing substantially but there's very little I can do about that.

This is also the reason resolution and framerate changes take longer as both these require reinitializing the camera.

I could add constructor arguments to allow users to specify the initial resolution and framerate (which would save people having to reconfigure then after init in the case that people wanted a relatively fast init). I'll make that an enhancement for 1.9

waveform80 commented 10 years ago

I'm afraid as far as fixing the initialisation time is concerned, that's something you'll need to report upstream (the raspberrypi/userland project is the usual place for such things). It may be that the longer time is necessary to support stereoscopic capability, but I can't say for certain. If you do decide to report it upstream, it would probably be extremely useful to track down exactly which release resulted in the slower init time (somewhere just before 709 by the looks of it)

snoygues commented 9 years ago

Actually, long time for "resolution or "frame_rate" function are not a problem for my projet as I do not have to change them so often. On the opposite, "Capture" process time is very important for my project as I use this function each time I request a picture. But maybe there is another way/solution. Here is my need :

I currently used a timer and the "Capture" fonction. Is there a more effiicent way to do that ?

snoygues commented 9 years ago

It seems that using "Rapid capture and streaming" as describe in your online help (chapter 5.4) could be a solution for me. I'm a bit afraid with ausing "server" & "client", as I'm not use to, but first tests shows that it's should be ok. I just have one problem right now: it works as lons as I use "camera.capture_continuous(stream, 'jpeg', use_video_port=True): but, if I replace "jpeg" by "yuv", that does not work anymore. Solution is problably quite simple, but I have no idea. Could you help me?

waveform80 commented 9 years ago

How does it fail when you change 'jpeg' to 'yuv'? You will need to change the server end to deal with the fact that the format's changed (as yuv is unencoded things like PIL won't automatically be able to interpret the data any more; you'll need to tell them exactly what size/format the image data is in).