imager: add support for white balance
This commit is contained in:
parent
bd3ee26080
commit
05dc317095
|
@ -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}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue