Set channel minima and error if any LUV channels have std==0
This commit is contained in:
parent
38b8c5baa5
commit
79c94c96ed
2 changed files with 28 additions and 3 deletions
|
|
@ -18,6 +18,14 @@ class MissingBackgroundDataError(RuntimeError):
|
||||||
"""An error raised if checking for sample without background data set."""
|
"""An error raised if checking for sample without background data set."""
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelBlankError(RuntimeError):
|
||||||
|
"""An error raised if a channel has no measured standard deviation.
|
||||||
|
|
||||||
|
This is not physical and usually means the camera has not yet booted or changed
|
||||||
|
mode fully.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class BackgroundDetectorStatus(BaseModel):
|
class BackgroundDetectorStatus(BaseModel):
|
||||||
"""The status information about a background detector instance needed for the GUI.
|
"""The status information about a background detector instance needed for the GUI.
|
||||||
|
|
||||||
|
|
@ -277,6 +285,12 @@ class ChannelDeviationLUV(BackgroundDetectAlgorithm):
|
||||||
background_data_model: BaseModel = ChannelDistributions
|
background_data_model: BaseModel = ChannelDistributions
|
||||||
settings_data_model: BaseModel = ColourChannelDetectSettings
|
settings_data_model: BaseModel = ColourChannelDetectSettings
|
||||||
|
|
||||||
|
# Empirically, 0.5 seems to be approximate the standard deviation for a good image
|
||||||
|
# in L and V. U appears to be about 60% of this value. U is about 65% of V when
|
||||||
|
# converting white-noise in RGB into LUV (note that we are using cv2's internal
|
||||||
|
# LUV colour space not converting to the CIELUV numbers)
|
||||||
|
min_stds = [0.5, 0.3, 0.5]
|
||||||
|
|
||||||
def get_sample_coverage(self, image: np.ndarray) -> float:
|
def get_sample_coverage(self, image: np.ndarray) -> float:
|
||||||
"""Return the percentage of the input image that is background.
|
"""Return the percentage of the input image that is background.
|
||||||
|
|
||||||
|
|
@ -323,6 +337,9 @@ class ChannelDeviationLUV(BackgroundDetectAlgorithm):
|
||||||
|
|
||||||
mu = np.zeros(3)
|
mu = np.zeros(3)
|
||||||
std = np.median(_chunked_stds(image_luv, 8, 8), axis=(0, 1))
|
std = np.median(_chunked_stds(image_luv, 8, 8), axis=(0, 1))
|
||||||
|
if np.any(std == 0):
|
||||||
|
raise ChannelBlankError("Some LUV channels have no standard devaition.")
|
||||||
|
std = np.maximum(std, self.min_stds)
|
||||||
|
|
||||||
self.background_data = ChannelDistributions(
|
self.background_data = ChannelDistributions(
|
||||||
means=mu.tolist(), standard_deviations=std.tolist()
|
means=mu.tolist(), standard_deviations=std.tolist()
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ from openflexure_microscope_server.ui import (
|
||||||
action_button_for,
|
action_button_for,
|
||||||
property_control_for,
|
property_control_for,
|
||||||
)
|
)
|
||||||
|
from openflexure_microscope_server.background_detect import ChannelBlankError
|
||||||
from . import picamera_recalibrate_utils as recalibrate_utils
|
from . import picamera_recalibrate_utils as recalibrate_utils
|
||||||
from . import picamera_tuning_file_utils as tf_utils
|
from . import picamera_tuning_file_utils as tf_utils
|
||||||
|
|
||||||
|
|
@ -767,7 +768,6 @@ class StreamingPiCamera2(BaseCamera):
|
||||||
* ``auto_expose_from_minimum``
|
* ``auto_expose_from_minimum``
|
||||||
* ``set_static_green_equalisation`` to set geq offset to max
|
* ``set_static_green_equalisation`` to set geq offset to max
|
||||||
* ``calibrate_lens_shading`` (also sets colour gains for white balance)
|
* ``calibrate_lens_shading`` (also sets colour gains for white balance)
|
||||||
|
|
||||||
* ``set_background``
|
* ``set_background``
|
||||||
"""
|
"""
|
||||||
self.flat_lens_shading()
|
self.flat_lens_shading()
|
||||||
|
|
@ -775,8 +775,16 @@ class StreamingPiCamera2(BaseCamera):
|
||||||
self.set_static_green_equalisation()
|
self.set_static_green_equalisation()
|
||||||
self.set_ce_enable_to_off()
|
self.set_ce_enable_to_off()
|
||||||
self.calibrate_lens_shading()
|
self.calibrate_lens_shading()
|
||||||
time.sleep(0.5)
|
for _i in range(3):
|
||||||
self.set_background(portal)
|
try:
|
||||||
|
time.sleep(1)
|
||||||
|
self.set_background(portal)
|
||||||
|
# Return if background is set
|
||||||
|
return
|
||||||
|
except ChannelBlankError:
|
||||||
|
# If channel is blank, sleep a second and try again.
|
||||||
|
pass
|
||||||
|
raise RuntimeError("Couldn't set background")
|
||||||
|
|
||||||
@lt.thing_property
|
@lt.thing_property
|
||||||
def primary_calibration_actions(self) -> list[ActionButton]:
|
def primary_calibration_actions(self) -> list[ActionButton]:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue