Update tests for new camera streaming modes
This commit is contained in:
parent
aff860a086
commit
7dd715da88
8 changed files with 27 additions and 35 deletions
|
|
@ -107,9 +107,9 @@ def mock_picam_thing(mocker):
|
|||
},
|
||||
)
|
||||
|
||||
from openflexure_microscope_server.things.camera.picamera import StreamingPiCamera2
|
||||
from openflexure_microscope_server.things.camera.picamera import PiCameraV2
|
||||
|
||||
return create_thing_without_server(StreamingPiCamera2)
|
||||
return create_thing_without_server(PiCameraV2)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from contextlib import contextmanager
|
|||
from typing import Optional
|
||||
|
||||
from openflexure_microscope_server.things.background_detect import ChannelDeviationLUV
|
||||
from openflexure_microscope_server.things.camera.picamera import StreamingPiCamera2
|
||||
from openflexure_microscope_server.things.camera.picamera import PiCameraV2
|
||||
|
||||
from ...shared_utils.lt_test_utils import LabThingsTestEnv
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ def camera_test_env(settings_folder: Optional[str] = None):
|
|||
temporary directory will be used as the settings folder.
|
||||
"""
|
||||
thing_conf = {
|
||||
"camera": StreamingPiCamera2,
|
||||
"camera": PiCameraV2,
|
||||
"bg_channel_deviations_luv": ChannelDeviationLUV,
|
||||
}
|
||||
app_config = {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from .cam_test_utils import camera_test_env
|
|||
|
||||
@pytest.fixture
|
||||
def picamera_test_env() -> lt.ThingClient:
|
||||
"""Initialise a test environment with only a StreamingPiCamera2 Thing."""
|
||||
"""Initialise a test environment with only a PiCameraV2 Thing."""
|
||||
with camera_test_env() as env:
|
||||
yield env
|
||||
|
||||
|
|
|
|||
|
|
@ -93,13 +93,13 @@ def test_exposure_time_on_start_and_stop_stream():
|
|||
print(f"Starting simulation scan {i}")
|
||||
# This will need updating if we start supporting other Picamera models
|
||||
# It is currently used here to mimic the behaviour in in scanning.
|
||||
client.start_streaming(main_resolution=(3280, 2464))
|
||||
client.change_streaming_mode(mode="full_resolution")
|
||||
time.sleep(0.5)
|
||||
for _j in range(5):
|
||||
client.capture_to_memory(buffer_max=1)
|
||||
# Reset to main resolution
|
||||
time.sleep(0.5)
|
||||
client.start_streaming()
|
||||
client.change_streaming_mode(mode="default")
|
||||
# Check after all of this the exposure time is the same.
|
||||
assert client.exposure_time == set_time
|
||||
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ from .cam_test_utils import camera_test_client
|
|||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
|
||||
def test_sensor_mode():
|
||||
def test_streaming_mode():
|
||||
"""Test capturing raw arrays in two different sensor modes."""
|
||||
with camera_test_client() as client:
|
||||
for size in [(3280, 2464), (1640, 1232)]:
|
||||
client.sensor_mode = {"output_size": size, "bit_depth": 10}
|
||||
arr = np.array(client.capture_array(stream_name="raw"))
|
||||
for mode, res in ["default", (820, 616)], ["full_resolution", (3280, 2464)]:
|
||||
client.change_streaming_mode(mode=mode)
|
||||
arr = np.array(client.capture_array(stream_name="main"))
|
||||
# Check that the array dimensions match the requested image size.
|
||||
# Note: Numpy array shape is (y,x), but the sensor is set with (x,y)
|
||||
# hence the need to compare index 0 with index 1.
|
||||
assert arr.shape[0] == size[1]
|
||||
assert arr.shape[0] == res[1]
|
||||
|
|
@ -6,7 +6,6 @@ on camera functionality using the simulation camera are in "test_camera".
|
|||
|
||||
from labthings_fastapi.testing import create_thing_without_server
|
||||
|
||||
from openflexure_microscope_server.things.camera import BaseCamera
|
||||
from openflexure_microscope_server.things.camera.opencv import OpenCVCamera
|
||||
from openflexure_microscope_server.things.camera.simulation import SimulatedCamera
|
||||
|
||||
|
|
@ -57,11 +56,9 @@ def test_thing_description_equivalence(mock_picam_thing):
|
|||
camera child classes. Any addition of actions must be accompanied by an update
|
||||
to this test, prompting discussion of whether the action belongs in the subclass
|
||||
or the base camera class.
|
||||
"""
|
||||
base_td = create_thing_without_server(BaseCamera).thing_description()
|
||||
base_actions = set(base_td.actions.keys())
|
||||
base_props = set(base_td.properties.keys())
|
||||
|
||||
The base camera class is not instantiated as it is an Abstract Base Class
|
||||
"""
|
||||
sim_camera = create_thing_without_server(SimulatedCamera)
|
||||
sim_description = _get_clean_camera_description(sim_camera)
|
||||
opencv_camera = create_thing_without_server(OpenCVCamera)
|
||||
|
|
@ -82,8 +79,8 @@ def test_thing_description_equivalence(mock_picam_thing):
|
|||
|
||||
# Camera actions and properties should generally be equivalent except for exposed
|
||||
# manual settings and calibration actions.
|
||||
assert opencv_actions == sim_actions == base_actions
|
||||
assert opencv_props == sim_props == base_props
|
||||
assert opencv_actions == sim_actions
|
||||
assert opencv_props == sim_props
|
||||
|
||||
# For now PiCamera has a number of extra actions and properties. These should be
|
||||
# reduced over time by creating a way to use the functionality in a way as clearly
|
||||
|
|
@ -92,7 +89,6 @@ def test_thing_description_equivalence(mock_picam_thing):
|
|||
picamera_extra_actions = {
|
||||
"set_static_green_equalisation",
|
||||
"set_ce_enable_to_off",
|
||||
"stop_streaming",
|
||||
"reset_ccm",
|
||||
}
|
||||
picamera_extra_props = {
|
||||
|
|
@ -103,15 +99,12 @@ def test_thing_description_equivalence(mock_picam_thing):
|
|||
"sensor_resolution",
|
||||
"capture_metadata",
|
||||
"camera_configuration",
|
||||
"stream_resolution",
|
||||
"tuning",
|
||||
"sensor_modes",
|
||||
"sensor_mode",
|
||||
}
|
||||
# Note these are only the action not exposed as calibration actions.
|
||||
for action in picamera_extra_actions:
|
||||
assert action in picamera_actions
|
||||
for props in picamera_extra_props:
|
||||
assert props in picamera_props
|
||||
assert picamera_actions - base_actions == picamera_extra_actions
|
||||
assert picamera_props - base_props == picamera_extra_props
|
||||
assert picamera_actions - sim_actions == picamera_extra_actions
|
||||
assert picamera_props - sim_props == picamera_extra_props
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import labthings_fastapi as lt
|
|||
from labthings_fastapi.testing import create_thing_without_server
|
||||
|
||||
from openflexure_microscope_server.things.background_detect import ChannelDeviationLUV
|
||||
from openflexure_microscope_server.things.camera import BaseCamera
|
||||
from openflexure_microscope_server.things.camera import (
|
||||
picamera_tuning_file_utils as tf_utils,
|
||||
)
|
||||
|
|
@ -32,8 +31,8 @@ def temp_jpeg(tmp_path: Path) -> Path:
|
|||
|
||||
|
||||
def test_add_metadata_to_capture(temp_jpeg):
|
||||
"""Use a BaseCamera to add metadata to a tmp capture and test fields."""
|
||||
base_cam = create_thing_without_server(BaseCamera)
|
||||
"""Use a SimulatedCamerato add metadata to a tmp capture and test fields."""
|
||||
cam = create_thing_without_server(SimulatedCamera)
|
||||
metadata = {
|
||||
"Dummy1": 1,
|
||||
"Dummy2": "two",
|
||||
|
|
@ -48,7 +47,7 @@ def test_add_metadata_to_capture(temp_jpeg):
|
|||
"things_states": metadata,
|
||||
}
|
||||
|
||||
base_cam._add_metadata_to_capture(str(temp_jpeg), capture_metadata)
|
||||
cam._add_metadata_to_capture(str(temp_jpeg), capture_metadata)
|
||||
|
||||
# Reload EXIF
|
||||
exif_dict = piexif.load(str(temp_jpeg))
|
||||
|
|
@ -177,7 +176,7 @@ def test_picamera_metadata_written_to_exif(mock_picam_thing, temp_jpeg, mocker):
|
|||
exif_dict = piexif.load(str(temp_jpeg))
|
||||
user_comment = json.loads(exif_dict["Exif"][piexif.ExifIFD.UserComment].decode())
|
||||
|
||||
assert user_comment["camera"] == "StreamingPiCamera2"
|
||||
assert user_comment["camera"] == "PiCameraV2"
|
||||
assert user_comment["camera_board"] == "imx219"
|
||||
# gamma_correction keys are cast to strings
|
||||
assert user_comment["tuning"] == {
|
||||
|
|
|
|||
|
|
@ -492,7 +492,7 @@ def check_run_scan(scan_thing, caplog, expected_exception=None):
|
|||
|
||||
final_scan_data = scan_thing._ongoing_scan.save_scan_data.call_args[0][0]
|
||||
calls = {
|
||||
"cam_start_streaming_calls": scan_thing._cam.start_streaming.call_count,
|
||||
"cam_change_streaming_mode_calls": scan_thing._cam.change_streaming_mode.call_count,
|
||||
"main_scan_loop_calls": scan_thing._main_scan_loop.call_count,
|
||||
"return_to_start_calls": scan_thing._return_to_starting_position.call_count,
|
||||
"perform_final_stitch_calls": scan_thing._perform_final_stitch.call_count,
|
||||
|
|
@ -509,7 +509,7 @@ def test_run_scan(scan_thing_mocked_for_run_scan, caplog):
|
|||
assert len(logs) == 0
|
||||
|
||||
expected_calls_numbers = {
|
||||
"cam_start_streaming_calls": 2,
|
||||
"cam_change_streaming_mode_calls": 2,
|
||||
"main_scan_loop_calls": 1,
|
||||
"return_to_start_calls": 1,
|
||||
"perform_final_stitch_calls": 1,
|
||||
|
|
@ -534,7 +534,7 @@ def test_run_scan_err_in_main_loop(scan_thing_mocked_for_run_scan, caplog, mocke
|
|||
# Main loop not run, nor are return to start, final stitch, or purging of empty
|
||||
# scans. Save scan data is still called twice
|
||||
expected_calls_numbers = {
|
||||
"cam_start_streaming_calls": 2,
|
||||
"cam_change_streaming_mode_calls": 2,
|
||||
"main_scan_loop_calls": 1,
|
||||
"return_to_start_calls": 0,
|
||||
"perform_final_stitch_calls": 0,
|
||||
|
|
@ -559,7 +559,7 @@ def test_run_scan_cancelled(scan_thing_mocked_for_run_scan, caplog, mocker):
|
|||
# Main loop not run, nor are return to start, final stitch, or purging of empty
|
||||
# scans. Save scan data is still called twice
|
||||
expected_calls_numbers = {
|
||||
"cam_start_streaming_calls": 2,
|
||||
"cam_change_streaming_mode_calls": 2,
|
||||
"main_scan_loop_calls": 1,
|
||||
"return_to_start_calls": 1,
|
||||
"perform_final_stitch_calls": 1,
|
||||
|
|
@ -584,7 +584,7 @@ def test_run_scan_fill_disk(scan_thing_mocked_for_run_scan, caplog, mocker):
|
|||
# Main loop not run, nor are return to start, final stitch, or purging of empty
|
||||
# scans. Save scan data is still called twice
|
||||
expected_calls_numbers = {
|
||||
"cam_start_streaming_calls": 2,
|
||||
"cam_change_streaming_mode_calls": 2,
|
||||
"main_scan_loop_calls": 1,
|
||||
"return_to_start_calls": 0,
|
||||
"perform_final_stitch_calls": 0,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue