openflexure-microscope-server/openflexure_microscope/api/v2/views/camera.py

51 lines
1.9 KiB
Python

import datetime
import logging
from io import BytesIO
import numpy as np
from flask import send_file
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": {"image/jpeg": {}},
"description": "Lens-shading table in RGB format",
}
}
def get(self):
"""
Get the lens shading table as an image.
"""
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:
# Get the LST Numpy array from the camera's memoryview
lst = np.asarray(microscope.camera.camera.lens_shading_table)
# Create array of R next to G1
top = np.concatenate(lst[:2], axis=1)
# Create array of G2 next to B
bottom = np.concatenate(lst[2:], axis=1)
# Create combined array of 2x2 grid of greyscale images
all_channels = np.concatenate((top, bottom), axis=0)
# Create a PNG
img_bytes: BytesIO = BytesIO()
Image.fromarray(np.uint8(all_channels), "L").save(img_bytes, "PNG")
img_bytes.seek(0)
# Return the image
fname: str = f"lst-{datetime.date.today().isoformat()}.png"
return send_file(img_bytes, as_attachment=True, attachment_filename=fname)