Low res stream during scanning for instant high res captures
This commit is contained in:
parent
a9fdd0ea3e
commit
17f3bbe646
3 changed files with 39 additions and 9 deletions
|
|
@ -79,6 +79,16 @@ class CameraProtocol(Protocol):
|
||||||
"""Acquire one image from the preview stream and return its size"""
|
"""Acquire one image from the preview stream and return its size"""
|
||||||
...
|
...
|
||||||
|
|
||||||
|
def start_highres_streaming(self) -> None:
|
||||||
|
"""Start (or stop and restart) the camera in a configuration for low
|
||||||
|
res streaming and instant high res captures"""
|
||||||
|
...
|
||||||
|
|
||||||
|
def start_streaming(self) -> None:
|
||||||
|
"""Start (or stop and restart) the camera in the default streaming
|
||||||
|
configuration which balances stream and capture quality"""
|
||||||
|
...
|
||||||
|
|
||||||
class BaseCamera(Thing):
|
class BaseCamera(Thing):
|
||||||
"""A Thing representing a camera
|
"""A Thing representing a camera
|
||||||
|
|
||||||
|
|
@ -182,6 +192,17 @@ class CameraStub(BaseCamera):
|
||||||
"""Acquire one image from the camera and return as a JPEG blob"""
|
"""Acquire one image from the camera and return as a JPEG blob"""
|
||||||
raise NotImplementedError("Cameras must not inherit from CameraStub")
|
raise NotImplementedError("Cameras must not inherit from CameraStub")
|
||||||
|
|
||||||
|
@thing_action
|
||||||
|
def start_highres_streaming(self):
|
||||||
|
"""Start (or stop and restart) the camera in a configuration for low
|
||||||
|
res streaming and instant high res captures"""
|
||||||
|
raise NotImplementedError("Cameras must not inherit from CameraStub")
|
||||||
|
|
||||||
|
@thing_action
|
||||||
|
def start_streaming(self) -> None:
|
||||||
|
"""Start (or stop and restart) the camera in the default streaming
|
||||||
|
configuration which balances stream and capture quality"""
|
||||||
|
raise NotImplementedError("Cameras must not inherit from CameraStub")
|
||||||
|
|
||||||
CameraDependency = direct_thing_client_dependency(CameraStub, "/camera/")
|
CameraDependency = direct_thing_client_dependency(CameraStub, "/camera/")
|
||||||
RawCameraDependency = raw_thing_dependency(CameraProtocol)
|
RawCameraDependency = raw_thing_dependency(CameraProtocol)
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,14 @@ class CaptureThing(Thing):
|
||||||
logger.warning(e)
|
logger.warning(e)
|
||||||
raise CaptureError("An error occurred while capturing after 5 attempts")
|
raise CaptureError("An error occurred while capturing after 5 attempts")
|
||||||
|
|
||||||
|
@thing_action
|
||||||
|
def stop_streaming(self, cam: CamDep):
|
||||||
|
cam.stop_streaming()
|
||||||
|
|
||||||
|
@thing_action
|
||||||
|
def restart_stream(self, cam:CamDep):
|
||||||
|
cam.restart_stream()
|
||||||
|
|
||||||
@thing_action
|
@thing_action
|
||||||
def _capture_array(self, cam: CamDep, metadata_getter: GetThingStates, logger: InvocationLogger, stream: str = 'main'):
|
def _capture_array(self, cam: CamDep, metadata_getter: GetThingStates, logger: InvocationLogger, stream: str = 'main'):
|
||||||
"""Capture an image in memory and return it with metadata
|
"""Capture an image in memory and return it with metadata
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,8 @@ class SmartScanThing(Thing):
|
||||||
self._scan_images_taken = 0
|
self._scan_images_taken = 0
|
||||||
self._stitch_resize = 1
|
self._stitch_resize = 1
|
||||||
|
|
||||||
|
self._cam.start_highres_streaming()
|
||||||
|
|
||||||
# Don't set self._scan_data dictionary. This is done at the start of _run_scan
|
# Don't set self._scan_data dictionary. This is done at the start of _run_scan
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -202,6 +204,7 @@ class SmartScanThing(Thing):
|
||||||
# Error must be raised so UI gives correct output
|
# Error must be raised so UI gives correct output
|
||||||
raise e
|
raise e
|
||||||
finally:
|
finally:
|
||||||
|
self._cam.start_streaming()
|
||||||
# However the scan finishes, unset all variables and release lock
|
# However the scan finishes, unset all variables and release lock
|
||||||
self._cancel = None
|
self._cancel = None
|
||||||
self._scan_logger = None
|
self._scan_logger = None
|
||||||
|
|
@ -404,19 +407,17 @@ class SmartScanThing(Thing):
|
||||||
test_jpg = self._cam.grab_jpeg()
|
test_jpg = self._cam.grab_jpeg()
|
||||||
test_image = np.array(Image.open(test_jpg.open()))
|
test_image = np.array(Image.open(test_jpg.open()))
|
||||||
|
|
||||||
test_image_res = list(test_image.shape[:2])
|
test_image_res = list(test_image.shape)
|
||||||
csm_image_res = [int(i) for i in self._csm.image_resolution]
|
csm_image_res = [int(i) for i in self._csm.image_resolution]
|
||||||
|
|
||||||
if test_image_res != csm_image_res:
|
|
||||||
raise RuntimeError(
|
# If current stream width is different to csm calibration width,
|
||||||
"Cannot start scan as it is set up to capture with a resolution that "
|
# perform the conversion here
|
||||||
"has not been mapped.\n"
|
res_ratio = csm_image_res[0] / test_image_res[0]
|
||||||
f"Scan resolution: {test_image_res}\n"
|
|
||||||
f"camera-stage-mapping resolution {csm_image_res}."
|
|
||||||
)
|
|
||||||
|
|
||||||
# get displacement matrix. note it is for (y, x) not (x, y) coordinates
|
# get displacement matrix. note it is for (y, x) not (x, y) coordinates
|
||||||
csm_disp_matrix = self._csm.image_to_stage_displacement_matrix
|
csm_disp_matrix = np.array(self._csm.image_to_stage_displacement_matrix)
|
||||||
|
csm_disp_matrix *= res_ratio
|
||||||
|
|
||||||
# Calculate displacements in image coordinates
|
# Calculate displacements in image coordinates
|
||||||
dx_img = test_image.shape[1] * (1 - overlap)
|
dx_img = test_image.shape[1] * (1 - overlap)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue