Coverage for /opt/conda/envs/apienv/lib/python3.10/site-packages/daiquiri/core/hardware/abstract/camera.py: 69%
39 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-14 02:13 +0000
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-14 02:13 +0000
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3from marshmallow import fields
4import numpy as np
5import cv2
7from PIL import Image
9from daiquiri.core.hardware.abstract import HardwareObject
10from daiquiri.core.schema.hardware import HardwareSchema
12import logging
14logger = logging.getLogger(__name__)
16CameraStatuses = ["READY", "ACQUIRING", "UNKNOWN", "ERROR"]
19class CameraPropertiesSchema(HardwareSchema):
20 state = fields.Str()
21 exposure = fields.Float()
22 gain = fields.Float()
23 mode = fields.Str(metadata={"readOnly": True})
24 live = fields.Bool()
25 width = fields.Int(metadata={"readOnly": True})
26 height = fields.Int(metadata={"readOnly": True})
29class CameraCallablesSchema(HardwareSchema):
30 save = fields.Str()
33class Camera(HardwareObject):
34 _type = "camera"
35 _state_ok = [CameraStatuses[0], CameraStatuses[1]]
37 _properties = CameraPropertiesSchema()
38 _callables = CameraCallablesSchema()
40 def frame(self):
41 """Return a frame from the camera"""
42 return np.array([])
44 def _call_save(self, path, type="PNG"):
45 """Return a frame from the camera to disk"""
46 frame = self.frame()
47 if frame is None:
48 raise RuntimeError("Could not get frame from camera")
50 # Possible the frame will not be uint8, convert it
51 if frame.dtype != np.uint8:
52 # opencv does not support uint32?
53 # https://github.com/MouseLand/cellpose/issues/937
54 if frame.dtype == np.uint32:
55 frame = frame.astype(np.float32)
56 frame = cv2.normalize(frame, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
57 frame = frame.astype(np.uint8)
59 im = Image.fromarray(frame)
60 if im.mode != "RGB":
61 im = im.convert("RGB")
63 im.save(path, type, quality=100)