Fix issues found by linter in PiCamera Code
Issue #423 created based on lens shading TODOs
This commit is contained in:
parent
0e3f4305b5
commit
72faba0272
4 changed files with 26 additions and 29 deletions
|
|
@ -303,7 +303,7 @@ class AutofocusThing(Thing):
|
||||||
|
|
||||||
jpeg_path = os.path.join(stack_dir, f"{capture_count}.jpeg")
|
jpeg_path = os.path.join(stack_dir, f"{capture_count}.jpeg")
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
cam.capture_to_memory(logger=logger, metadata_getter=logger)
|
cam.capture_to_memory(logger=logger, metadata_getter=metadata_getter)
|
||||||
captured_time = time.time()
|
captured_time = time.time()
|
||||||
|
|
||||||
if capture_count + 1 < images_to_capture:
|
if capture_count + 1 < images_to_capture:
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,7 @@ class PicameraControl(PropertyDescriptor):
|
||||||
|
|
||||||
def _getter(self, obj: StreamingPiCamera2):
|
def _getter(self, obj: StreamingPiCamera2):
|
||||||
with obj.picamera() as cam:
|
with obj.picamera() as cam:
|
||||||
ret = cam.capture_metadata()[self.control_name]
|
return cam.capture_metadata()[self.control_name]
|
||||||
return ret
|
|
||||||
|
|
||||||
def _setter(self, obj: StreamingPiCamera2, value: Any):
|
def _setter(self, obj: StreamingPiCamera2, value: Any):
|
||||||
with obj.picamera() as cam:
|
with obj.picamera() as cam:
|
||||||
|
|
@ -171,6 +170,7 @@ class StreamingPiCamera2(BaseCamera):
|
||||||
initial_value=(820, 616),
|
initial_value=(820, 616),
|
||||||
description="Resolution to use for the MJPEG stream",
|
description="Resolution to use for the MJPEG stream",
|
||||||
)
|
)
|
||||||
|
|
||||||
mjpeg_bitrate = PropertyDescriptor(
|
mjpeg_bitrate = PropertyDescriptor(
|
||||||
Optional[int],
|
Optional[int],
|
||||||
initial_value=100000000,
|
initial_value=100000000,
|
||||||
|
|
@ -368,8 +368,6 @@ class StreamingPiCamera2(BaseCamera):
|
||||||
lower may cause dropped frames. Defaults to 6.
|
lower may cause dropped frames. Defaults to 6.
|
||||||
"""
|
"""
|
||||||
with self.picamera() as picam:
|
with self.picamera() as picam:
|
||||||
# TODO: Filip: can we use the lores output to keep preview stream going
|
|
||||||
# while recording? According to picamera2 docs 4.2.1.6 this should work
|
|
||||||
try:
|
try:
|
||||||
if picam.started:
|
if picam.started:
|
||||||
picam.stop()
|
picam.stop()
|
||||||
|
|
|
||||||
|
|
@ -80,16 +80,15 @@ def set_minimum_exposure(camera: Picamera2):
|
||||||
|
|
||||||
We set exposure mode to manual, analog and digital gain
|
We set exposure mode to manual, analog and digital gain
|
||||||
to 1, and shutter speed to the minimum (8us for Pi Camera v2)
|
to 1, and shutter speed to the minimum (8us for Pi Camera v2)
|
||||||
NB ISO is left at auto, because this is needed for the gains
|
|
||||||
|
Note ISO is left at auto, because this is needed for the gains
|
||||||
to be set correctly.
|
to be set correctly.
|
||||||
"""
|
"""
|
||||||
camera.set_controls({"AeEnable": False, "AnalogueGain": 1, "ExposureTime": 1})
|
# Disable Automatic exposure and gain algoritm (AeEnable), and set analogue
|
||||||
# camera.iso = 0 # We must set ISO=0 (auto) or we can't set gain
|
# gain and exposure time.
|
||||||
# camera.analog_gain = 1
|
|
||||||
# camera.digital_gain = 1 (not configurable)
|
|
||||||
# Setting the shutter speed to 1us will result in it being set
|
# Setting the shutter speed to 1us will result in it being set
|
||||||
# to the minimum possible, which is probably 8us for PiCamera v2
|
# to the minimum possible, which is ~8us for PiCamera v2
|
||||||
# camera.shutter_speed = 1
|
camera.set_controls({"AeEnable": False, "AnalogueGain": 1, "ExposureTime": 1})
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -138,8 +137,7 @@ def test_exposure_settings(camera: Picamera2, percentile: float) -> ExposureTest
|
||||||
|
|
||||||
def check_convergence(test: ExposureTest, target: int, tolerance: float):
|
def check_convergence(test: ExposureTest, target: int, tolerance: float):
|
||||||
"""Check whether the brightness is within the specified target range"""
|
"""Check whether the brightness is within the specified target range"""
|
||||||
converged = abs(test.level - target) < target * tolerance
|
return abs(test.level - target) < target * tolerance
|
||||||
return converged
|
|
||||||
|
|
||||||
|
|
||||||
def adjust_shutter_and_gain_from_raw(
|
def adjust_shutter_and_gain_from_raw(
|
||||||
|
|
@ -257,7 +255,6 @@ def adjust_white_balance_from_raw(
|
||||||
camera.configure(config)
|
camera.configure(config)
|
||||||
camera.start()
|
camera.start()
|
||||||
channels = channels_from_bayer_array(camera.capture_array("raw"))
|
channels = channels_from_bayer_array(camera.capture_array("raw"))
|
||||||
# logging.info(f"White balance: channels were retrieved with shape {channels.shape}.")
|
|
||||||
if luminance is not None and Cr is not None and Cb is not None:
|
if luminance is not None and Cr is not None and Cb is not None:
|
||||||
# Reconstruct a low-resolution image from the lens shading tables
|
# Reconstruct a low-resolution image from the lens shading tables
|
||||||
# and use it to normalise the raw image, to compensate for
|
# and use it to normalise the raw image, to compensate for
|
||||||
|
|
@ -328,10 +325,9 @@ def get_16x12_grid(chan: np.ndarray, dx: int, dy: int):
|
||||||
for consistency.
|
for consistency.
|
||||||
"""
|
"""
|
||||||
grid = []
|
grid = []
|
||||||
"""
|
|
||||||
since left and bottom border will not necessarily have rectangles of
|
# since left and bottom border will not necessarily have rectangles of
|
||||||
dimension dx x dy, the 32nd iteration has to be handled separately.
|
# dimension dx x dy, the final iteration has to be handled separately.
|
||||||
"""
|
|
||||||
for i in range(11):
|
for i in range(11):
|
||||||
for j in range(15):
|
for j in range(15):
|
||||||
grid.append(np.mean(chan[dy * i : dy * (1 + i), dx * j : dx * (1 + j)]))
|
grid.append(np.mean(chan[dy * i : dy * (1 + i), dx * j : dx * (1 + j)]))
|
||||||
|
|
@ -339,9 +335,7 @@ def get_16x12_grid(chan: np.ndarray, dx: int, dy: int):
|
||||||
for j in range(15):
|
for j in range(15):
|
||||||
grid.append(np.mean(chan[11 * dy :, dx * j : dx * (1 + j)]))
|
grid.append(np.mean(chan[11 * dy :, dx * j : dx * (1 + j)]))
|
||||||
grid.append(np.mean(chan[11 * dy :, 15 * dx :]))
|
grid.append(np.mean(chan[11 * dy :, 15 * dx :]))
|
||||||
"""
|
# return as np.array, ready for further manipulation
|
||||||
return as np.array, ready for further manipulation
|
|
||||||
"""
|
|
||||||
return np.reshape(np.array(grid), (12, 16))
|
return np.reshape(np.array(grid), (12, 16))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -387,24 +381,27 @@ def lst_from_channels(channels: np.ndarray) -> LensShadingTables:
|
||||||
def lst_from_grids(grids: np.ndarray) -> LensShadingTables:
|
def lst_from_grids(grids: np.ndarray) -> LensShadingTables:
|
||||||
"""Given 4 downsampled grids, generate the luminance and chrominance tables
|
"""Given 4 downsampled grids, generate the luminance and chrominance tables
|
||||||
|
|
||||||
|
The grids are the 4 BAYER channels RGGB
|
||||||
|
|
||||||
The LST format has changed with `picamera2` and now uses a fixed resolution,
|
The LST format has changed with `picamera2` and now uses a fixed resolution,
|
||||||
and is in luminance, Cr, Cb format. This function returns three ndarrays of
|
and is in luminance, Cr, Cb format. This function returns three ndarrays of
|
||||||
luminance, Cr, Cb, each with shape (12, 16).
|
luminance, Cr, Cb, each with shape (12, 16).
|
||||||
|
|
||||||
# TODO: make consistent with
|
|
||||||
https://git.linuxtv.org/libcamera.git/tree/utils/raspberrypi/ctt/ctt_alsc.py
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Calculated red, green, and blue channels from Bayer data
|
||||||
r: np.ndarray = grids[3, ...]
|
r: np.ndarray = grids[3, ...]
|
||||||
g: np.ndarray = np.mean(grids[1:3, ...], axis=0)
|
g: np.ndarray = np.mean(grids[1:3, ...], axis=0)
|
||||||
b: np.ndarray = grids[0, ...]
|
b: np.ndarray = grids[0, ...]
|
||||||
|
|
||||||
# What we actually want to calculate is the gains needed to compensate for the
|
# What we actually want to calculate is the gains needed to compensate for the
|
||||||
# lens shading - that's 1/lens_shading_table_float as we currently have it.
|
# lens shading - that's 1/lens_shading_table_float as we currently have it.
|
||||||
luminance_gains: np.ndarray = np.max(g) / g # Minimum luminance gain is 1
|
|
||||||
|
# Minimum luminance gain is 1
|
||||||
|
luminance_gains: np.ndarray = np.max(g) / g
|
||||||
|
|
||||||
cr_gains: np.ndarray = g / r
|
cr_gains: np.ndarray = g / r
|
||||||
# cr_gains /= cr_gains[5, 7] # Normalise so the central colour doesn't change
|
|
||||||
cb_gains: np.ndarray = g / b
|
cb_gains: np.ndarray = g / b
|
||||||
# cb_gains /= cb_gains[5, 7]
|
|
||||||
return luminance_gains, cr_gains, cb_gains
|
return luminance_gains, cr_gains, cb_gains
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -491,11 +488,12 @@ def _geq_is_static(tuning: dict) -> bool:
|
||||||
return geq["offset"] == 65535
|
return geq["offset"] == 65535
|
||||||
|
|
||||||
|
|
||||||
def index_of_algorithm(algorithms: list[dict], algorithm: str):
|
def index_of_algorithm(algorithms: list[dict], algorithm: str) -> int:
|
||||||
"""Find the index of an algorithm's section in the tuning file"""
|
"""Find the index of an algorithm's section in the tuning file"""
|
||||||
for i, a in enumerate(algorithms):
|
for i, a in enumerate(algorithms):
|
||||||
if algorithm in a:
|
if algorithm in a:
|
||||||
return i
|
return i
|
||||||
|
raise ValueError(f"Algorithm {algorithm} is not available.")
|
||||||
|
|
||||||
|
|
||||||
def copy_alsc_section(from_tuning: dict, to_tuning: dict):
|
def copy_alsc_section(from_tuning: dict, to_tuning: dict):
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ from ..stage import StageProtocol as Stage
|
||||||
# higher related to a faster movement
|
# higher related to a faster movement
|
||||||
RATIO = 0.2
|
RATIO = 0.2
|
||||||
|
|
||||||
|
|
||||||
class SimulatedCamera(BaseCamera):
|
class SimulatedCamera(BaseCamera):
|
||||||
"""A Thing representing an OpenCV camera"""
|
"""A Thing representing an OpenCV camera"""
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue