Tidy post refactor of cameras
This commit is contained in:
parent
4368dc3d90
commit
0e3f4305b5
7 changed files with 22 additions and 46 deletions
|
|
@ -83,8 +83,8 @@ addopts = [
|
||||||
]
|
]
|
||||||
|
|
||||||
norecursedirs = [".git", "build", "node_modules"]
|
norecursedirs = [".git", "build", "node_modules"]
|
||||||
|
|
||||||
pythonpath = ["."]
|
pythonpath = ["."]
|
||||||
|
testpaths = ["tests"]
|
||||||
|
|
||||||
[tool.ruff.format]
|
[tool.ruff.format]
|
||||||
# Use native line endings for all files
|
# Use native line endings for all files
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ from labthings_fastapi.dependencies.blocking_portal import BlockingPortal
|
||||||
from labthings_fastapi.decorators import thing_action, thing_property
|
from labthings_fastapi.decorators import thing_action, thing_property
|
||||||
from labthings_fastapi.dependencies.metadata import GetThingStates
|
from labthings_fastapi.dependencies.metadata import GetThingStates
|
||||||
from labthings_fastapi.types.numpy import NDArray
|
from labthings_fastapi.types.numpy import NDArray
|
||||||
from labthings_fastapi.dependencies.thing import direct_thing_client_dependency
|
|
||||||
from labthings_fastapi.dependencies.invocation import InvocationLogger
|
from labthings_fastapi.dependencies.invocation import InvocationLogger
|
||||||
|
|
||||||
from .camera import RawCameraDependency as Camera
|
from .camera import RawCameraDependency as Camera
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,12 @@ See repository root for licensing information.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import logging
|
|
||||||
from typing import Literal, Optional, Tuple
|
from typing import Literal, Optional, Tuple
|
||||||
|
import json
|
||||||
|
|
||||||
from pydantic import RootModel
|
from pydantic import RootModel
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
import piexif
|
||||||
|
|
||||||
from labthings_fastapi.thing import Thing
|
from labthings_fastapi.thing import Thing
|
||||||
from labthings_fastapi.decorators import thing_action, thing_property
|
from labthings_fastapi.decorators import thing_action, thing_property
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ import piexif
|
||||||
from labthings_fastapi.utilities import get_blocking_portal
|
from labthings_fastapi.utilities import get_blocking_portal
|
||||||
from labthings_fastapi.decorators import thing_action, thing_property
|
from labthings_fastapi.decorators import thing_action, thing_property
|
||||||
from labthings_fastapi.dependencies.metadata import GetThingStates
|
from labthings_fastapi.dependencies.metadata import GetThingStates
|
||||||
from labthings_fastapi.outputs.mjpeg_stream import MJPEGStreamDescriptor
|
|
||||||
from labthings_fastapi.types.numpy import NDArray
|
from labthings_fastapi.types.numpy import NDArray
|
||||||
|
|
||||||
from . import BaseCamera, JPEGBlob
|
from . import BaseCamera, JPEGBlob
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from dataclasses import dataclass
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import io
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
@ -12,19 +10,14 @@ from tempfile import TemporaryDirectory
|
||||||
from pydantic import BaseModel, BeforeValidator
|
from pydantic import BaseModel, BeforeValidator
|
||||||
|
|
||||||
from labthings_fastapi.descriptors.property import PropertyDescriptor
|
from labthings_fastapi.descriptors.property import PropertyDescriptor
|
||||||
from labthings_fastapi.thing import Thing
|
|
||||||
from labthings_fastapi.decorators import thing_action, thing_property
|
from labthings_fastapi.decorators import thing_action, thing_property
|
||||||
from labthings_fastapi.outputs.mjpeg_stream import MJPEGStream
|
from labthings_fastapi.outputs.mjpeg_stream import MJPEGStream
|
||||||
from labthings_fastapi.utilities import get_blocking_portal
|
from labthings_fastapi.utilities import get_blocking_portal
|
||||||
from labthings_fastapi.types.numpy import NDArray
|
|
||||||
from labthings_fastapi.dependencies.metadata import GetThingStates
|
from labthings_fastapi.dependencies.metadata import GetThingStates
|
||||||
from labthings_fastapi.dependencies.blocking_portal import BlockingPortal
|
from labthings_fastapi.dependencies.blocking_portal import BlockingPortal
|
||||||
from typing import Annotated, Any, Iterator, Literal, Mapping, Optional, Self
|
from typing import Annotated, Any, Iterator, Literal, Mapping, Optional
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
import piexif
|
import piexif
|
||||||
from scipy.ndimage import zoom
|
|
||||||
from scipy.interpolate import interp1d
|
|
||||||
from PIL import Image
|
|
||||||
from threading import RLock
|
from threading import RLock
|
||||||
import picamera2
|
import picamera2
|
||||||
from picamera2 import Picamera2
|
from picamera2 import Picamera2
|
||||||
|
|
@ -33,7 +26,7 @@ from picamera2.outputs import Output
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from . import picamera_recalibrate_utils as recalibrate_utils
|
from . import picamera_recalibrate_utils as recalibrate_utils
|
||||||
|
|
||||||
from . import BaseCamera, JPEGBlob, PNGBlob, ArrayModel
|
from . import BaseCamera, JPEGBlob, ArrayModel
|
||||||
|
|
||||||
|
|
||||||
class PicameraControl(PropertyDescriptor):
|
class PicameraControl(PropertyDescriptor):
|
||||||
|
|
@ -636,7 +629,9 @@ class StreamingPiCamera2(BaseCamera):
|
||||||
the processed images. It should not affect raw images.
|
the processed images. It should not affect raw images.
|
||||||
"""
|
"""
|
||||||
with self.picamera(pause_stream=True) as cam:
|
with self.picamera(pause_stream=True) as cam:
|
||||||
L, Cr, Cb = recalibrate_utils.lst_from_camera(cam)
|
# Suppress lint warning that L, Cr, and Cb are not lowercase, as this is the
|
||||||
|
# Standard format for these mathematical vars.
|
||||||
|
L, Cr, Cb = recalibrate_utils.lst_from_camera(cam) # noqa: N806
|
||||||
recalibrate_utils.set_static_lst(self.tuning, L, Cr, Cb)
|
recalibrate_utils.set_static_lst(self.tuning, L, Cr, Cb)
|
||||||
self.initialise_picamera()
|
self.initialise_picamera()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,11 @@ picamera.lens_shading_table = lst
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Disable N806 & 803, which checks that all variables and args are lowercase.
|
||||||
|
# This is due to the number of matrix calculations and colour channel
|
||||||
|
# calculations that are clearer using the standard R, G, B, or L, Cr, Cb terms.
|
||||||
|
# ruff: noqa: N806 N803
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import gc
|
import gc
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -43,6 +48,9 @@ from picamera2 import Picamera2
|
||||||
import picamera2
|
import picamera2
|
||||||
|
|
||||||
|
|
||||||
|
LensShadingTables = tuple[np.ndarray, np.ndarray, np.ndarray]
|
||||||
|
|
||||||
|
|
||||||
def load_default_tuning(cam: Picamera2) -> dict:
|
def load_default_tuning(cam: Picamera2) -> dict:
|
||||||
"""Load the default tuning file for the camera
|
"""Load the default tuning file for the camera
|
||||||
|
|
||||||
|
|
@ -58,12 +66,13 @@ def load_default_tuning(cam: Picamera2) -> dict:
|
||||||
try:
|
try:
|
||||||
return cam.load_tuning_file(fname)
|
return cam.load_tuning_file(fname)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
dir = "/usr/share/libcamera/ipa/raspberrypi" # from picamera2 v0.3.9
|
tuning_dir = "/usr/share/libcamera/ipa/raspberrypi"
|
||||||
# The directory above has been removed from the search path, which I
|
# from picamera2 v0.3.9
|
||||||
|
# The directory above has been removed from the search path seems
|
||||||
# find odd - as that's where the files currently are on a default
|
# find odd - as that's where the files currently are on a default
|
||||||
# Raspbian image. This may need updating if the files have moved
|
# Raspbian image. This may need updating if the files have moved
|
||||||
# in future updates to the system libcamera package
|
# in future updates to the system libcamera package
|
||||||
return cam.load_tuning_file(fname, dir=dir)
|
return cam.load_tuning_file(fname, dir=tuning_dir)
|
||||||
|
|
||||||
|
|
||||||
def set_minimum_exposure(camera: Picamera2):
|
def set_minimum_exposure(camera: Picamera2):
|
||||||
|
|
@ -312,9 +321,6 @@ def channels_from_bayer_array(bayer_array: np.ndarray) -> np.ndarray:
|
||||||
return channels
|
return channels
|
||||||
|
|
||||||
|
|
||||||
LensShadingTables = tuple[np.ndarray, np.ndarray, np.ndarray]
|
|
||||||
|
|
||||||
|
|
||||||
def get_16x12_grid(chan: np.ndarray, dx: int, dy: int):
|
def get_16x12_grid(chan: np.ndarray, dx: int, dy: int):
|
||||||
"""Compresses channel down to a 16x12 grid - from libcamera
|
"""Compresses channel down to a 16x12 grid - from libcamera
|
||||||
|
|
||||||
|
|
@ -527,8 +533,8 @@ def raw_channels_from_camera(camera: Picamera2) -> LensShadingTables:
|
||||||
# raw_image is a 3D array, with full resolution and 3 colour channels. No
|
# raw_image is a 3D array, with full resolution and 3 colour channels. No
|
||||||
# de-mosaicing has been done, so 2/3 of the values are zero (3/4 for R and B
|
# de-mosaicing has been done, so 2/3 of the values are zero (3/4 for R and B
|
||||||
# channels, 1/2 for green because there's twice as many green pixels).
|
# channels, 1/2 for green because there's twice as many green pixels).
|
||||||
format = camera.camera_configuration()["raw"]["format"]
|
raw_format = camera.camera_configuration()["raw"]["format"]
|
||||||
print(f"Acquired a raw image in format {format}")
|
print(f"Acquired a raw image in format {raw_format}")
|
||||||
return channels_from_bayer_array(raw_image)
|
return channels_from_bayer_array(raw_image)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -540,24 +546,3 @@ def recreate_camera_manager():
|
||||||
del Picamera2._cm
|
del Picamera2._cm
|
||||||
gc.collect()
|
gc.collect()
|
||||||
Picamera2._cm = picamera2.picamera2.CameraManager()
|
Picamera2._cm = picamera2.picamera2.CameraManager()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
"""This block is untested but has been updated."""
|
|
||||||
with Picamera2() as cam:
|
|
||||||
tuning = load_default_tuning(cam)
|
|
||||||
f = np.ones((12, 16))
|
|
||||||
set_static_lst(tuning, f, f, f)
|
|
||||||
set_static_geq(tuning)
|
|
||||||
with Picamera2(tuning=tuning) as cam:
|
|
||||||
cam.start_preview()
|
|
||||||
time.sleep(3)
|
|
||||||
logging.info("Recalibrating...")
|
|
||||||
adjust_shutter_and_gain_from_raw(cam)
|
|
||||||
adjust_white_balance_from_raw(cam)
|
|
||||||
lst = lst_from_camera(cam)
|
|
||||||
set_static_lst(tuning, *lst)
|
|
||||||
logging.info("Done.")
|
|
||||||
with Picamera2(tuning=tuning) as cam:
|
|
||||||
cam.start_preview()
|
|
||||||
time.sleep(2)
|
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,7 @@ from scipy.ndimage import gaussian_filter
|
||||||
from labthings_fastapi.utilities import get_blocking_portal
|
from labthings_fastapi.utilities import get_blocking_portal
|
||||||
from labthings_fastapi.decorators import thing_action, thing_property
|
from labthings_fastapi.decorators import thing_action, thing_property
|
||||||
from labthings_fastapi.dependencies.metadata import GetThingStates
|
from labthings_fastapi.dependencies.metadata import GetThingStates
|
||||||
from labthings_fastapi.types.numpy import NDArray
|
|
||||||
from labthings_fastapi.server import ThingServer
|
from labthings_fastapi.server import ThingServer
|
||||||
from pydantic import RootModel
|
|
||||||
|
|
||||||
from . import BaseCamera, JPEGBlob, ArrayModel
|
from . import BaseCamera, JPEGBlob, ArrayModel
|
||||||
from ..stage import StageProtocol as Stage
|
from ..stage import StageProtocol as Stage
|
||||||
|
|
@ -33,7 +31,6 @@ 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