From 4d40e81f0e72db30ec54d7c6dc0004f80f7fb313 Mon Sep 17 00:00:00 2001 From: Joel Collins Date: Wed, 18 Nov 2020 14:23:12 +0000 Subject: [PATCH] Added API route to convert LST to PNG --- openflexure_microscope/api/app.py | 5 +- .../api/v2/views/__init__.py | 1 + openflexure_microscope/api/v2/views/camera.py | 47 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 openflexure_microscope/api/v2/views/camera.py diff --git a/openflexure_microscope/api/app.py b/openflexure_microscope/api/app.py index 4c8b0ef0..0c85c99f 100644 --- a/openflexure_microscope/api/app.py +++ b/openflexure_microscope/api/app.py @@ -29,10 +29,10 @@ from labthings import create_app from labthings.extensions import find_extensions from labthings.views import View -from openflexure_microscope.microscope import Microscope from openflexure_microscope.api.utilities import init_default_extensions, list_routes from openflexure_microscope.api.v2 import views from openflexure_microscope.json import JSONEncoder +from openflexure_microscope.microscope import Microscope from openflexure_microscope.paths import ( OPENFLEXURE_EXTENSIONS_PATH, OPENFLEXURE_VAR_PATH, @@ -135,6 +135,9 @@ labthing.add_root_link(views.ConfigurationProperty, "instrumentConfiguration") # Attach stage resources labthing.add_view(views.StageTypeProperty, "/instrument/stage/type") +# Attach camera resources +labthing.add_view(views.LSTImageProperty, "/instrument/camera/lst") + # Attach streams resources labthing.add_view(views.MjpegStream, "/streams/mjpeg") labthing.add_view(views.SnapshotStream, "/streams/snapshot") diff --git a/openflexure_microscope/api/v2/views/__init__.py b/openflexure_microscope/api/v2/views/__init__.py index 796a3f09..5771e204 100644 --- a/openflexure_microscope/api/v2/views/__init__.py +++ b/openflexure_microscope/api/v2/views/__init__.py @@ -1,4 +1,5 @@ from .actions import enabled_root_actions +from .camera import * from .captures import * from .instrument import * from .stage import * diff --git a/openflexure_microscope/api/v2/views/camera.py b/openflexure_microscope/api/v2/views/camera.py new file mode 100644 index 00000000..f72f2930 --- /dev/null +++ b/openflexure_microscope/api/v2/views/camera.py @@ -0,0 +1,47 @@ +import logging +from io import BytesIO + +import numpy as np +from flask import Response +from labthings import find_component +from labthings.views import PropertyView +from PIL import Image + + +class LSTImageProperty(PropertyView): + """Gets the lens-shading table as an image""" + + responses = { + 200: { + "content_type": "image/png", + "description": "Lens-shading table in RGB format", + } + } + + def get(self): + """ + Get the stage geometry. + """ + microscope = find_component("org.openflexure.microscope") + + # Return intentionally empty response if no LST is available + if microscope.get_configuration()["camera"]["type"] != "PiCameraStreamer": + logging.warning("Requested an LST from a non-PiCameraStreamer camera") + return ("", 204) + # Return intentionally empty response if we have a valid PiCamera but no LST + elif getattr(microscope.camera.camera, "lens_shading_table") is None: + logging.warning("PiCamera.lens_shading_table returned as None") + return ("", 204) + else: + lst = np.asarray(microscope.camera.camera.lens_shading_table) + # R next to G1 + top = np.concatenate(lst[:2], axis=1) + # G2 next to B + bottom = np.concatenate(lst[2:], axis=1) + # Combined into a 2x2 grid of greyscale images + all_channels = np.concatenate((top, bottom), axis=0) + # Create a PNG + img_bytes = BytesIO() + Image.fromarray(np.uint8(all_channels), "L").save(img_bytes, "PNG") + # Return the image + return Response(img_bytes.getvalue(), mimetype="image/png")