Fixed description and linted
This commit is contained in:
parent
5527c4eb7b
commit
4c27d88b37
2 changed files with 30 additions and 27 deletions
|
|
@ -2,8 +2,6 @@ import logging
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
import labthings.fields as fields
|
import labthings.fields as fields
|
||||||
import numpy as np
|
|
||||||
import picamerax
|
|
||||||
from flask import abort
|
from flask import abort
|
||||||
from labthings import find_component
|
from labthings import find_component
|
||||||
from labthings.extensions import BaseExtension
|
from labthings.extensions import BaseExtension
|
||||||
|
|
@ -13,12 +11,10 @@ from openflexure_microscope.camera.base import BaseCamera
|
||||||
from openflexure_microscope.microscope import Microscope
|
from openflexure_microscope.microscope import Microscope
|
||||||
|
|
||||||
from .recalibrate_utils import (
|
from .recalibrate_utils import (
|
||||||
auto_expose_and_freeze_settings,
|
|
||||||
flat_lens_shading_table,
|
|
||||||
get_channel_percentiles,
|
|
||||||
recalibrate_camera,
|
|
||||||
adjust_shutter_and_gain_from_raw,
|
adjust_shutter_and_gain_from_raw,
|
||||||
adjust_white_balance_from_raw,
|
adjust_white_balance_from_raw,
|
||||||
|
flat_lens_shading_table,
|
||||||
|
get_channel_percentiles,
|
||||||
lst_from_camera,
|
lst_from_camera,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -82,11 +78,9 @@ class LSTExtension(BaseExtension):
|
||||||
"/auto_white_balance_from_raw",
|
"/auto_white_balance_from_raw",
|
||||||
endpoint="auto_white_balance_from_raw",
|
endpoint="auto_white_balance_from_raw",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def find_microscope():
|
def find_microscope() -> Microscope:
|
||||||
"""Locate the microscope and raise a sensible error if it's missing."""
|
"""Locate the microscope and raise a sensible error if it's missing."""
|
||||||
microscope = find_component("org.openflexure.microscope")
|
microscope = find_component("org.openflexure.microscope")
|
||||||
|
|
||||||
|
|
@ -96,9 +90,7 @@ def find_microscope():
|
||||||
)
|
)
|
||||||
|
|
||||||
if not hasattr(microscope.camera, "picamera"):
|
if not hasattr(microscope.camera, "picamera"):
|
||||||
abort(
|
abort(503, "The PiCamera calibration plugin requires a Raspberry Pi camera.")
|
||||||
503, "The PiCamera calibration plugin requires a Raspberry Pi camera."
|
|
||||||
)
|
|
||||||
|
|
||||||
return microscope
|
return microscope
|
||||||
|
|
||||||
|
|
@ -106,10 +98,15 @@ def find_microscope():
|
||||||
class RecalibrateView(ActionView):
|
class RecalibrateView(ActionView):
|
||||||
args = {
|
args = {
|
||||||
"skip_auto_exposure": fields.Bool(
|
"skip_auto_exposure": fields.Bool(
|
||||||
missing=False,
|
missing=False,
|
||||||
description="Whether to "
|
description=(
|
||||||
|
"By default we perform an auto-exposure and AWB "
|
||||||
|
"step before updating the lens shading table. Set "
|
||||||
|
"this argument to True to disable those steps."
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def post(self, args):
|
def post(self, args):
|
||||||
"""Reset the camera's settings.
|
"""Reset the camera's settings.
|
||||||
|
|
||||||
|
|
@ -184,8 +181,7 @@ class AutoExposureFromRawView(ActionView):
|
||||||
def post(self, args):
|
def post(self, args):
|
||||||
camera = find_component("org.openflexure.microscope").camera.picamera
|
camera = find_component("org.openflexure.microscope").camera.picamera
|
||||||
adjust_shutter_and_gain_from_raw(
|
adjust_shutter_and_gain_from_raw(
|
||||||
camera,
|
camera, **args # I'm relying on the schema to fill in missing values
|
||||||
**args # I'm relying on the schema to fill in missing values
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -206,8 +202,7 @@ class AutoWhiteBalanceFromRawView(ActionView):
|
||||||
def post(self, args):
|
def post(self, args):
|
||||||
camera = find_component("org.openflexure.microscope").camera.picamera
|
camera = find_component("org.openflexure.microscope").camera.picamera
|
||||||
adjust_white_balance_from_raw(
|
adjust_white_balance_from_raw(
|
||||||
camera,
|
camera, **args # I'm relying on the schema to fill in missing values
|
||||||
**args # I'm relying on the schema to fill in missing values
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,12 @@ import numpy as np
|
||||||
from picamerax import PiCamera
|
from picamerax import PiCamera
|
||||||
from picamerax.array import PiBayerArray, PiRGBArray
|
from picamerax.array import PiBayerArray, PiRGBArray
|
||||||
|
|
||||||
|
# I have used f strings throughout, for readability.
|
||||||
|
# The performance implication of using them in logging statements
|
||||||
|
# really doesn't matter here - also, loglevel is usually set to
|
||||||
|
# INFO to report progress via the LabThings action API
|
||||||
|
# pylint: disable=logging-fstring-interpolation
|
||||||
|
|
||||||
|
|
||||||
def rgb_image(
|
def rgb_image(
|
||||||
camera: PiCamera, resize: Optional[Tuple[int, int]] = None, **kwargs
|
camera: PiCamera, resize: Optional[Tuple[int, int]] = None, **kwargs
|
||||||
|
|
@ -66,6 +72,12 @@ def adjust_exposure_and_gain(
|
||||||
iterations = 0
|
iterations = 0
|
||||||
while True:
|
while True:
|
||||||
iterations += 1
|
iterations += 1
|
||||||
|
if iterations > max_iterations:
|
||||||
|
logging.warning(
|
||||||
|
f"Auto exposure is stopping after {max_iterations} "
|
||||||
|
"but it has not converged."
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
||||||
with PiBayerArray(camera) as a:
|
with PiBayerArray(camera) as a:
|
||||||
camera.capture(a, format="jpeg", bayer=True)
|
camera.capture(a, format="jpeg", bayer=True)
|
||||||
|
|
@ -86,7 +98,7 @@ def adjust_exposure_and_gain(
|
||||||
f"{previous_shutter_speed} to {current_shutter_speed}"
|
f"{previous_shutter_speed} to {current_shutter_speed}"
|
||||||
)
|
)
|
||||||
if current_shutter_speed == previous_shutter_speed:
|
if current_shutter_speed == previous_shutter_speed:
|
||||||
logging.info(f"Shutter speed has saturated, stopping.")
|
logging.info("Shutter speed has saturated, stopping.")
|
||||||
break
|
break
|
||||||
|
|
||||||
if max_brightness > target_white_level:
|
if max_brightness > target_white_level:
|
||||||
|
|
@ -153,7 +165,6 @@ def adjust_shutter_and_gain_from_raw(
|
||||||
# until either the brightness is high enough, or we can't increase the
|
# until either the brightness is high enough, or we can't increase the
|
||||||
# shutter speed any more.
|
# shutter speed any more.
|
||||||
iterations = 0
|
iterations = 0
|
||||||
shutter_speed_maximised = False
|
|
||||||
shutter_speed_increments = [10, 2, None]
|
shutter_speed_increments = [10, 2, None]
|
||||||
shutter_speed_increment = shutter_speed_increments.pop(0)
|
shutter_speed_increment = shutter_speed_increments.pop(0)
|
||||||
while iterations < max_iterations:
|
while iterations < max_iterations:
|
||||||
|
|
@ -202,14 +213,9 @@ def adjust_shutter_and_gain_from_raw(
|
||||||
if current_shutter_speed == tested_shutter_speed:
|
if current_shutter_speed == tested_shutter_speed:
|
||||||
camera.analog_gain *= 2
|
camera.analog_gain *= 2
|
||||||
if camera.analog_gain == tested_analog_gain:
|
if camera.analog_gain == tested_analog_gain:
|
||||||
logging.info(f"Shutter speed and gain are both maxed out. Giving up!")
|
logging.info("Shutter speed and gain are both maxed out. Giving up!")
|
||||||
break
|
break
|
||||||
logging.info(
|
logging.info("Shutter speed has maxed out, doubled gain to compensate.")
|
||||||
f"Shutter speed has maxed out at {current_shutter_speed}, doubled gain."
|
|
||||||
)
|
|
||||||
|
|
||||||
max_brightness = np.max(get_channel_percentiles(camera, percentile))
|
|
||||||
logging.info(f"Brightness {max_brightness} after {iterations} tries.")
|
|
||||||
return max_brightness
|
return max_brightness
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -330,6 +336,7 @@ def lst_from_channels(channels: np.ndarray) -> np.ndarray:
|
||||||
lens_shading_table: np.ndarray = gains.astype(np.uint8)
|
lens_shading_table: np.ndarray = gains.astype(np.uint8)
|
||||||
return lens_shading_table[::-1, :, :].copy()
|
return lens_shading_table[::-1, :, :].copy()
|
||||||
|
|
||||||
|
|
||||||
def lst_from_camera(camera: PiCamera) -> np.ndarray:
|
def lst_from_camera(camera: PiCamera) -> np.ndarray:
|
||||||
"""Acquire a raw image and use it to calculate a lens shading table."""
|
"""Acquire a raw image and use it to calculate a lens shading table."""
|
||||||
with PiBayerArray(camera) as a:
|
with PiBayerArray(camera) as a:
|
||||||
|
|
@ -343,6 +350,7 @@ def lst_from_camera(camera: PiCamera) -> np.ndarray:
|
||||||
channels = channels_from_bayer_array(raw_image)
|
channels = channels_from_bayer_array(raw_image)
|
||||||
return lst_from_channels(channels)
|
return lst_from_channels(channels)
|
||||||
|
|
||||||
|
|
||||||
def recalibrate_camera(camera: PiCamera):
|
def recalibrate_camera(camera: PiCamera):
|
||||||
"""Reset the lens shading table and exposure settings.
|
"""Reset the lens shading table and exposure settings.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue