openflexure-microscope-server/openflexure_microscope/camera/set_picamera_gain.py
2020-11-30 13:36:45 +00:00

73 lines
2.5 KiB
Python

from __future__ import print_function
import logging
import time
from typing import Union
import picamerax
from picamerax import exc, mmal
from picamerax.mmalobj import to_rational
MMAL_PARAMETER_ANALOG_GAIN: int = mmal.MMAL_PARAMETER_GROUP_CAMERA + 0x59
MMAL_PARAMETER_DIGITAL_GAIN: int = mmal.MMAL_PARAMETER_GROUP_CAMERA + 0x5A
def set_gain(camera: picamerax.PiCamera, gain: int, value: Union[int, float]):
"""Set the analog gain of a PiCamera.
camera: the picamerax.PiCamera() instance you are configuring
gain: either MMAL_PARAMETER_ANALOG_GAIN or MMAL_PARAMETER_DIGITAL_GAIN
value: a numeric value that can be converted to a rational number.
"""
if gain not in [MMAL_PARAMETER_ANALOG_GAIN, MMAL_PARAMETER_DIGITAL_GAIN]:
raise ValueError("The gain parameter was not valid")
ret = mmal.mmal_port_parameter_set_rational(
camera._camera.control._port, gain, to_rational(value) # pylint: disable=W0212
)
if ret == 4:
raise exc.PiCameraMMALError(
ret,
"Are you running the latest version of the userland libraries? Gain setting was introduced in late 2017.",
)
elif ret != 0:
raise exc.PiCameraMMALError(ret)
def set_analog_gain(camera: picamerax.PiCamera, value: Union[int, float]):
"""Set the gain of a PiCamera object to a given value."""
set_gain(camera, MMAL_PARAMETER_ANALOG_GAIN, value)
def set_digital_gain(camera: picamerax.PiCamera, value: Union[int, float]):
"""Set the digital gain of a PiCamera object to a given value."""
set_gain(camera, MMAL_PARAMETER_DIGITAL_GAIN, value)
if __name__ == "__main__":
with picamerax.PiCamera() as cam:
cam.start_preview(fullscreen=False, window=(0, 50, 640, 480))
time.sleep(2)
# fix the auto white balance gains at their current values
g = cam.awb_gains
cam.awb_mode = "off"
cam.awb_gains = g
# fix the shutter speed
cam.shutter_speed = cam.exposure_speed
logging.info("Current a/d gains: %s, %s", cam.analog_gain, cam.digital_gain)
logging.info("Attempting to set analogue gain to 1")
set_analog_gain(cam, 1)
logging.info("Attempting to set digital gain to 1")
set_digital_gain(cam, 1)
try:
while True:
logging.info(
"Current a/d gains: %s, %s", cam.analog_gain, cam.digital_gain
)
time.sleep(1)
except KeyboardInterrupt:
logging.info("Stopping...")