Source code for crappy.blocks.gpucorrel

# coding: utf-8

from time import time
import numpy as np
from typing import Callable

from ..tool import GPUCorrel as GPUCorrel_tool
from .camera import Camera


[docs]class GPUCorrel(Camera): """This block uses the :ref:`GPU Correl` class. See the documentation of :ref:`GPU Correl` to have more information about the arguments specific to this class. It will try to identify the deformation parameters for each fields. If you use custom fields, you can use ``labels=(...)`` to name the data sent through the link. If no labels are specified, custom fields will be named by their position. The reference image is only taken once, when the :meth:`start` method is called (after dropping the first image). """ def __init__(self, camera: str, fields: list, save_folder: str = None, verbose: bool = False, labels: list = None, fps_label: str = False, img_name: str = "{self.loops:06d}_{t-self.t0:.6f}", ext: str = 'tiff', save_period: int = 1, save_backend: str = None, transform: Callable = None, input_label: str = None, config: bool = True, cam_kwargs: dict = None, discard_lim: int = 3, discard_ref: int = 5, imgref=None, **kwargs) -> None: self.ready = False cam_kw = {} self.fields = fields # Kwargs to be given to the camera BLOCK # ie save_folder, config, etc... but NOT the labels cam_kw['save_folder'] = save_folder cam_kw['verbose'] = verbose cam_kw['fps_label'] = fps_label cam_kw['img_name'] = img_name cam_kw['ext'] = ext cam_kw['save_period'] = save_period cam_kw['save_backend'] = save_backend cam_kw['transform'] = transform cam_kw['input_label'] = input_label cam_kw['config'] = config self.verbose = cam_kw['verbose'] # Also, we keep the verbose flag if cam_kwargs is not None: cam_kw.update(cam_kwargs) Camera.__init__(self, camera, **cam_kw) # A function to apply to the image self.transform = cam_kw.get("transform") self.discard_lim = discard_lim self.discard_ref = discard_ref # If the residual of the image exceeds <discard_lim> times the # average of the residual of the last <discard_ref> images, # do not send the result (requires res=True) # Creating the tuple of labels (to name the outputs) self.labels = ('t(s)',) for i in range(len(self.fields)): # If explicitly named with labels=(...) if labels is not None: self.labels += (labels[i],) # Else if we got a default field as a string, # use this string (ex: fields=('x', 'y', 'r', 'exx', 'eyy')) elif isinstance(fields[i], str): self.labels += (fields[i],) # Custom field and no label given: name it by its position... else: self.labels += (str(i),) # Handle res parameters: if true, also return the residual self.res = kwargs.get("res", True) if self.res: self.labels += ("res",) self.imgref = imgref self.gpu_correl_kwargs = kwargs self.gpu_correl_kwargs['fields'] = self.fields
[docs] def prepare(self, *_, **__) -> None: Camera.prepare(self, send_img=False) t, img = self.camera.read_image() if self.transform is not None: img = self.transform(img) self.correl = GPUCorrel_tool(img.shape, **self.gpu_correl_kwargs) self.loops = 0 self.nloops = 50 self.res_hist = [np.inf] if self.imgref is not None: if self.transform is not None: self.correl.set_orig(self.transform(self.imgref.astype(np.float32))) else: self.correl.set_orig(self.imgref.astype(np.float32)) self.correl.prepare()
[docs] def begin(self) -> None: self.last_t = time() - 1 if self.imgref is not None: return t, img = self.camera.read_image() if self.transform is not None: self.correl.set_orig(self.transform(img).astype(np.float32)) else: self.correl.set_orig(img.astype(np.float32)) self.correl.prepare() if self.save_folder: self.save(img, self.save_folder + "img_ref_%.6f.tiff" % (t - self.t0))
def loop(self) -> None: if self.verbose and self.loops % self.nloops == 0: t = time() print("[Correl block] processed", self.nloops / (t - self.last_t), "ips") self.last_t = t t, img = self.get_img() out = [t - self.t0] + self.correl.get_disp(img.astype(np.float32)).tolist() if self.res: out += [self.correl.get_res()] if self.discard_lim: self.res_hist = self.res_hist + [out[-1]] self.res_hist = self.res_hist[-self.discard_ref - 1:] if self.res_hist[-1] > \ self.discard_lim * np.average(self.res_hist[:-1]): print("[Correl block] Residual too high, not sending values") return self.send(out)
[docs] def finish(self) -> None: self.correl.clean() Camera.finish(self)