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 357 forks source link

How know when first frame with new settings has been delivered? #454

Open mklein9 opened 6 years ago

mklein9 commented 6 years ago

Is there a way to know whether a given frame retrieved from the stream is the first one fully captured with a modified set of parameters? Example: I want to adjust shutter speed, so I write the new shutter speed to camera.shutter_speed. I believe that when the stream delivers an image where camera.exposure_speed matches the new shutter speed, that this frame was captured with the new shutter speed and I can process this one.

Is there a general method to use when the event that changes the image is not directly related to the camera, such as changing the scene lighting under control of the application? I can think of two potential ways:

1) Use EXIF tags by writing one with a specific value and waiting until the JPEG image shows it -- but not sure how to do this with the primary image being the Bayer array

2) Use the camera.timestamp property and wait until a frame that is long enough after the event in question

Thank you.

6by9 commented 6 years ago

Exposure time and analogue gain get written to the sensor. Typically rolling shutter sensors will take 2 frames to adopt a new setting - if frame N is being read out, frame N+1 is already being exposed and therefore settings can't be changed, so they get latched at the start of N+2. Flips (but not transpose) also get done on the sensor, therefore the same applies to those.

All other settings should be applied in the ISP and can therefore be applied to frame N+1.

If the sensor is stopped and restarted then it will restart with the latest settings applied. This should be the case when capturing JPEGs as long as you aren't using use_video_port=true (which would disable EXIF anyway).

The camera subsystem can be asked to produce callbacks whenever exposure time, analogue gain, digital gain, or white balance gains. This is what is reported if you add the -set option to raspistill etc. PiCamera also uses this to update properties exposure_speed, analog_gain, digital_gain, and awb_gains (see http://picamera.readthedocs.io/en/latest/api_camera.html for further details)

As to your application changing something external.

1) If capturing JPEGs then it is triggered at the point you call capture(). There should be no need to wait for anything in that case.

2) Yes you can request the current GPU timestamp and compare to incoming frames. I don't quite see what "long enough after the event in question" means. If you've changed lighting then are you wanting to have seen AE adjust to the new settings, or are you only wanting the next frame after the event? Seeing as the frame timestamp is for the frame readout start, you do need to subtract the exposure time from it to get start of exposure if that is what you're meaning.