[BUG] Cannot reset AnalogueGain to automatic after manually setting it
Hi,
I have the following code:
picam2 = Picamera2()
picam2.create_video_configuration(main={"size": (1920, 1080), "format": "YUV420"},
sensor=sensor,
controls={
'FrameRate': 50,
'NoiseReductionMode': 1,
'AeConstraintMode': 2}
)
picam2.configure(self.video_config)
picam2.start()
After this, if I print the analogue gain value periodically I can see them changing when moving my camera (values are printed from a while loop)
AG: 1.1228070259094238
AG: 5.417989253997803
AG: 7.5851850509643555
AG: 7.816793918609619
Then, I manually set the AnalogueGain :
video_config["controls"]["AnalogueGain"] = 2.3
# I am not sure this part is needed
picam2.stop()
picam2.configure(self.video_config)
picam2.start()
So now, no matter if I move my camera or not, the AnalogueGain value remains the same (values are printed from a while loop)
AG: 2.295964241027832
AG: 2.295964241027832
AG: 2.295964241027832
So until now, this is the expected behavior.
But when I want to reset AnalogueGain to be automatic, things do not work as expected:
picam2.set_controls({'ExposureTime': 0, 'AnalogueGain': 0})
After doing that, printing the AnalogueGain value result in a fixed value that doesn't change even when moving my camera.
AG: 1.1228070259094238
AG: 1.1228070259094238
AG: 1.1228070259094238
I ran the following version of your code
import time
from picamera2 import Picamera2
picam2 = Picamera2()
video_config = picam2.create_video_configuration(main={"size": (1920, 1080), "format": "YUV420"},
sensor={'output_size': (2304, 1296)},
controls={
'FrameRate': 50,
'NoiseReductionMode': 1,
'AeConstraintMode': 2}
)
picam2.configure(video_config)
picam2.start()
time.sleep(1.0)
print(picam2.capture_metadata()['AnalogueGain'])
picam2.stop()
video_config["controls"]["AnalogueGain"] = 2.3
picam2.configure(video_config)
picam2.start()
time.sleep(1.0)
print(picam2.capture_metadata()['AnalogueGain'])
picam2.set_controls({'ExposureTime': 0, 'AnalogueGain': 0})
time.sleep(1.0)
print(picam2.capture_metadata()['AnalogueGain'])
and it printed the values
4.031496047973633
2.295964241027832
3.9233715534210205
suggesting that the gain went back to auto correctly.
Can I just check what Picamera2 version you're running? Libcamera changed their AGC/AEC controls API a few weeks back (they added ExposureTimeMode and AnalogueGainMode) which affected how transitions between auto/manual worked, and it took us a few moments to catch up. We should probably just check that's not what's catching you out. Thanks!
Something must be wrong on my side, with your version of the code it works as expected. I'll investigate, sorry for wasting your time.
Edit: I found out how to reproduce the issue, see my comment further down.
Sure, let me know if you can reproduce it again in such a way that I can help!
Actually, I found out how to reproduce the issue !
import time
from picamera2 import Picamera2
picam2 = Picamera2()
video_config = picam2.create_video_configuration(main={"size": (1920, 1080), "format": "YUV420"},
sensor={'output_size': (2304, 1296)},
controls={
'FrameRate': 50,
'NoiseReductionMode': 1,
'AeConstraintMode': 2}
)
picam2.configure(video_config)
picam2.start()
time.sleep(1.0)
print(picam2.capture_metadata()['AnalogueGain'])
picam2.stop()
video_config["controls"]["AnalogueGain"] = 2.3
picam2.configure(video_config)
picam2.start()
time.sleep(1.0)
print(picam2.capture_metadata()['AnalogueGain'])
still_capture_config = picam2.create_still_configuration(raw={})
picam2.set_controls({'ExposureTime': 0, 'AnalogueGain': 0})
r = picam2.switch_mode_and_capture_request(still_capture_config)
r.save("main", "image.jpg")
r.save_dng("raw.dng")
time.sleep(1.0)
print(picam2.capture_metadata()['AnalogueGain'])
So right after saving the image, the analogue gain is reverted back to the manual value it was set to, rather than reverting back to the automatic value
@davidplowman I can't reopen the issue, can you do it ?
Yes, I can understand this. It's a tricky little one, not sure what one can really do.
The problem is that changing the settings takes a few frames, because those changes end up at the back of the request queue. Doing that right before a switch_mode (effectively stopping the camera system immediately for a mode switch) means those changes are never seen, and therefore don't happen.
I'm not sure what we can really do about that. You don't want to apply them, wait for them to happen, and then do the mode switch, as that's not really what you want!
Pragmatically, the best answer might be to put {'ExposureTime': 0, 'AnalogueGain': 0} in as the controls for the create_video_configuration. That way, they should get re-applied immediately when the still capture is done and you return to the video mode. (Though obviously auto mode will resume from the fixed exposure/gain values you have just used.)
Does that explain/help at all?