imager: add support for white balance

This commit is contained in:
Romain Bazile 2020-11-24 17:25:57 +01:00
parent bd3ee26080
commit 05dc317095
5 changed files with 70 additions and 11 deletions

View file

@ -126,7 +126,7 @@ class ImagerProcess(multiprocessing.Process):
"""This class contains the main definitions for the imager of the PlanktoScope""" """This class contains the main definitions for the imager of the PlanktoScope"""
@logger.catch @logger.catch
def __init__(self, stop_event, iso=100, shutter_speed=500): def __init__(self, stop_event, iso=200, shutter_speed=20):
"""Initialize the Imager class """Initialize the Imager class
Args: Args:
@ -188,6 +188,12 @@ class ImagerProcess(multiprocessing.Process):
self.__iso = iso self.__iso = iso
self.__shutter_speed = shutter_speed self.__shutter_speed = shutter_speed
self.__exposure_mode = "fixedfps" self.__exposure_mode = "fixedfps"
self.__white_balance = "off"
self.__white_balance_gain = (
200,
140,
) # Those values were tested on a HQ camera to give a whitish background
self.__base_path = "/home/pi/data/img" self.__base_path = "/home/pi/data/img"
# Let's make sure the base path exists # Let's make sure the base path exists
if not os.path.exists(self.__base_path): if not os.path.exists(self.__base_path):
@ -231,6 +237,24 @@ class ImagerProcess(multiprocessing.Process):
"A timeout has occured when setting the exposure mode, trying again" "A timeout has occured when setting the exposure mode, trying again"
) )
self.__camera.exposure_mode = self.__exposure_mode self.__camera.exposure_mode = self.__exposure_mode
time.sleep(0.1)
try:
self.__camera.white_balance = self.__white_balance
except TimeoutError as e:
logger.error(
"A timeout has occured when setting the white balance mode, trying again"
)
self.__camera.white_balance = self.__white_balance
time.sleep(0.1)
try:
self.__camera.white_balance_gain = self.__white_balance_gain
except TimeoutError as e:
logger.error(
"A timeout has occured when setting the white balance gain, trying again"
)
self.__camera.white_balance_gain = self.__white_balance_gain
logger.success("planktoscope.imager is initialised and ready to go!") logger.success("planktoscope.imager is initialised and ready to go!")
@ -324,6 +348,9 @@ class ImagerProcess(multiprocessing.Process):
"acq_camera_iso": self.__iso, "acq_camera_iso": self.__iso,
"acq_camera_shutter_speed": self.__shutter_speed, "acq_camera_shutter_speed": self.__shutter_speed,
} }
# TODO add here the field size metadata
# For cam HQ 4,15mm x 3,14mm, résolution 1µm/px
# For cam 2.1 2.31mm x 1,74mm, résolution 0.7µm/px
# Concat the local metadata and the metadata from Node-RED # Concat the local metadata and the metadata from Node-RED
self.__global_metadata = {**local_metadata, **nodered_metadata} self.__global_metadata = {**local_metadata, **nodered_metadata}

View file

@ -8,7 +8,7 @@
# Library to send command over I2C for the light module on the fan # Library to send command over I2C for the light module on the fan
import smbus import smbus
import RPi.GPIO import RPi.GPIO
import subprocess import subprocess # nosec
# define the bus used to actuate the light module on the fan # define the bus used to actuate the light module on the fan
bus = smbus.SMBus(1) bus = smbus.SMBus(1)
@ -22,25 +22,26 @@ rgb_off_reg = 0x07
################################################################################ ################################################################################
# LEDs functions # LEDs functions
################################################################################ ################################################################################
def i2c_update():
# Update the I2C Bus in order to really update the LEDs new values
subprocess.Popen("i2cdetect -y 1".split(), stdout=subprocess.PIPE) # nosec
def setRGB(R, G, B): def setRGB(R, G, B):
"""Update all LED at the same time""" """Update all LED at the same time"""
bus.write_byte_data(DEVICE_ADDRESS, 0x00, 0xFF) bus.write_byte_data(DEVICE_ADDRESS, 0x00, 0xFF)
bus.write_byte_data(DEVICE_ADDRESS, 0x01, R & 0xFF) bus.write_byte_data(DEVICE_ADDRESS, 0x01, R & 0xFF)
bus.write_byte_data(DEVICE_ADDRESS, 0x02, G & 0xFF) bus.write_byte_data(DEVICE_ADDRESS, 0x02, G & 0xFF)
bus.write_byte_data(DEVICE_ADDRESS, 0x03, B & 0xFF) bus.write_byte_data(DEVICE_ADDRESS, 0x03, B & 0xFF)
i2c_update()
# Update the I2C Bus in order to really update the LEDs new values
cmd = "i2cdetect -y 1"
subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
def setRGBOff(): def setRGBOff():
"""Turn off the RGB LED""" """Turn off the RGB LED"""
bus.write_byte_data(DEVICE_ADDRESS, 0x07, 0x00) bus.write_byte_data(DEVICE_ADDRESS, 0x07, 0x00)
i2c_update()
# Update the I2C Bus in order to really update the LEDs new values
cmd = "i2cdetect -y 1"
subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
def setRGBEffect(effect): def setRGBEffect(effect):
@ -88,6 +89,10 @@ def light(state):
RPi.GPIO.output(21, RPi.GPIO.LOW) RPi.GPIO.output(21, RPi.GPIO.LOW)
## Wait message: Green
## Actuate message: White
## Pumping message: Blue
# This is called if this script is launched directly # This is called if this script is launched directly
if __name__ == "__main__": if __name__ == "__main__":
# TODO This should be a test suite for this library # TODO This should be a test suite for this library

View file

@ -25,6 +25,7 @@ class raspimjpeg(object):
self.__binary = "/home/pi/PlanktonScope/scripts/raspimjpeg/bin/raspimjpeg" self.__binary = "/home/pi/PlanktonScope/scripts/raspimjpeg/bin/raspimjpeg"
self.__statusfile = "/dev/shm/mjpeg/status_mjpeg.txt" self.__statusfile = "/dev/shm/mjpeg/status_mjpeg.txt"
self.__pipe = "/home/pi/PlanktonScope/scripts/raspimjpeg/FIFO" self.__pipe = "/home/pi/PlanktonScope/scripts/raspimjpeg/FIFO"
self.__sensor_name = ""
# make sure the status file exists and is empty # make sure the status file exists and is empty
if not os.path.exists(self.__statusfile): if not os.path.exists(self.__statusfile):
@ -374,6 +375,32 @@ class raspimjpeg(object):
) )
raise ValueError raise ValueError
@property
def white_balance_gain(self):
return self.__white_balance_gain
@white_balance_gain.setter
def white_balance_gain(self, gain):
"""Change the camera white balance gain
The gain value should be a int between 0 and 300. By default the camera
is set to use 150 both for the red and the blue gain.
Args:
gain (tuple of int): Red gain and blue gain to use
"""
logger.debug(f"Setting the white balance mode to {gain}")
if (0 < gain[0] < 300) and (0 < gain[1] < 300):
self.__white_balance_gain = gain
self.__send_command(
f"ag {self.__white_balance_gain[0]} {self.__white_balance_gain[1]}"
)
else:
logger.error(
f"The camera white balance gain specified ({gain}) is not valid"
)
raise ValueError
@property @property
def image_quality(self): def image_quality(self):
return self.__image_quality return self.__image_quality

Binary file not shown.

View file

@ -89,7 +89,7 @@ MP4Box_cmd (set -e;MP4Box -fps %i -add %s %s > /dev/null 2>&1;rm "%s";) &
# #
image_width 3280 image_width 3280
image_height 2464 image_height 2464
image_quality 25 image_quality 80
#time lapse interval 0.1 sec units #time lapse interval 0.1 sec units
tl_interval 30 tl_interval 30