Repository navigation
switch_mode_and_capture_request does not restore camera settings afterwords. #1406
|
When I set up a camera configuration in both preview and high resolution modes, start the preview mode, change the exposure time, and then use How can I change this behavior? Here's a minimal example. When I run it, the two print statements show that before and after calling import time
from collections.abc import Buffer
from copy import deepcopy
from io import BufferedIOBase, BytesIO
from threading import Lock
from typing import Any
from picamera2.encoders import MJPEGEncoder, Quality
from picamera2.outputs.fileoutput import FileOutput
from picamera2.picamera2 import Picamera2
class StreamingOutput(BufferedIOBase):
"""Simulated Buffered IO to write the frames to as they are encoded."""
def __init__(self) -> None:
"""Initialize the writer."""
self.frame: bytes | None = None
self.condition = Lock()
def write(self, buf: Buffer) -> int:
"""Write the bytes to the frame.
Arguments:
buf: The buffer to write
Returns:
Number of written bytes
"""
with self.condition:
self.frame = BytesIO(buf).read()
return len(self.frame)
cam_controls: dict[str, Any] = {
"AeEnable": True,
"ExposureValue": 0.0,
"FrameRate": 30.0,
}
picam2 = Picamera2()
output = StreamingOutput()
preview_config = picam2.create_video_configuration(
main={"size": (2028, 1520), "format": "YUV420"},
controls=cam_controls,
)
picam2.configure(preview_config)
picam2.start_recording(
MJPEGEncoder(cam_controls["FrameRate"]),
FileOutput(output),
quality=Quality.VERY_HIGH,
)
time.sleep(1)
###########################################
# Modify exposure time
###########################################
cam_controls.update(
{"ExposureTime": 1_000_000, "FrameDurationLimits": (0, 1_000_000)},
)
preview_controls = deepcopy(cam_controls)
preview_controls.update({"FrameDurationLimits": (0, 1_000_000)})
picam2.set_controls(preview_controls)
time.sleep(2)
###########################################
# Take the photo
###########################################
# Create config for high res photo
capture_config = picam2.create_still_configuration(
raw={"format": "SRGGB12", "size": (4056, 3040)},
display=None,
controls=cam_controls,
)
# Stop the encoder to prevent crashes
# See https://forums.raspberrypi.com/viewtopic.php?t=354226
picam2.stop_encoder()
print(picam2.capture_metadata()["ExposureTime"])
request = picam2.switch_mode_and_capture_request(
capture_config,
)
print(picam2.capture_metadata()["ExposureTime"])
picam2.start_encoder(MJPEGEncoder(), FileOutput(output))
# Release the request
request.release() |
Replies: 1 comment 5 replies
|
Hi, thanks for sending the test case. I think the main cause of this may be that you've included the The other slight catch is that So here's what I would do:
Here's a further simplified version of what you had: Note that I've put wide frame duration limits on all the modes, so they'll never truncate you back to 30fps or anything. But outside of the preview config, I've set 30fps before starting the camera, so any recording (if I hadn't removed it!) would be at 30fps. Do be aware, however, that at the end of this script, you're still running at exposure time = 1 second, i.e. 1fps. Hope that helps! |
Hi, thanks for sending the test case. I think the main cause of this may be that you've included the
cam_controlswith your preview configuration. This means that, whenever yourpreview_configgets applied (either when you start the camera, or after the mode switch), it reapplies those controls. This includes the framerate of 30, which truncates that 1 second exposure time right back to approximately 33ms.The other slight catch is that
create_video_configurationwill, unless you say otherwise, also give you 30fps by default.So here's what I would do:
No need to set those
cam_controlswith either the preview or capture config. They're all defaults anyway. If you want to set controls be…