Source code for displayarray.effects.crop

"""Crop any n-dimensional array."""

import numpy as np
from ..input import mouse_loop


[docs]class Crop(object): """A callback class that will return the input array cropped to the output size. N-dimensional.""" def __init__(self, output_size=(64, 64, 3), center=None): """ Create the cropping callback class. :param output_size: Specified the size the input should be cropped to. Can be redefined later. :param center: Specifies the center on the input array to take the crop out of. """ self._output_size = None self._center = np.asarray([o // 2 for o in output_size]) self.odd_center = None self.mouse_control = None self.input_size = None self.center = center self.output_size = output_size @property def output_size(self): """Get the output size.""" return self._output_size @output_size.setter def output_size(self, set): """Set the output size.""" self._output_size = set if self._output_size is not None: self._output_size = np.asarray(set) @property def center(self): """Get the center.""" return self._center @center.setter def center(self, set): """Set the center. Guarded so that colors need not be set.""" if set is not None: for x in range(len(set)): self._center[x] = set[x] def __call__(self, arr): """Crop the input array to the specified output size. output is centered on self.center point on input.""" self.input_size = arr.shape if self.center is None: self.center = [int(arr.shape[x]) // 2 for x in range(arr.ndim)] self.odd_out = np.array( [self.output_size[x] % 2 for x in range(len(self.output_size))] ) self.odd_center = np.array( [self.center[x] % 2 for x in range(len(self.center))] ) center = self.center.copy() # stop opencv from thread breaking us top_left_get = [ min(max(0, center[x] - self.output_size[x] // 2), arr.shape[x] - 1) for x in range(arr.ndim) ] bottom_right_get = [ min( max(0, center[x] + self.output_size[x] // 2 + self.odd_out[x]), arr.shape[x], ) for x in range(arr.ndim) ] top_left_put = [ min( max( 0, -(bottom_right_get[x] - center[x] - self.output_size[x] // 2) + self.odd_out[x], ), self.output_size[x], ) for x in range(arr.ndim) ] bottom_right_put = [ min( max(0, top_left_put[x] + (bottom_right_get[x] - top_left_get[x])), self.output_size[x], ) for x in range(arr.ndim) ] get_slices = [slice(x1, x2) for x1, x2 in zip(top_left_get, bottom_right_get)] get_slices = tuple(get_slices) put_slices = [slice(x1, x2) for x1, x2 in zip(top_left_put, bottom_right_put)] put_slices = tuple(put_slices) out_array = np.zeros(self.output_size) out_array[put_slices] = arr[get_slices] return out_array.astype(arr.dtype)
[docs] def enable_mouse_control(self): """Move the mouse to move where the crop is from on the original image.""" @mouse_loop def m_loop(me): if self.center is None: self.center = [0, 0, 1] self.center[:] = [ int(me.y / self.output_size[0] * self.input_size[0]), int(me.x / self.output_size[1] * self.input_size[1]), 1, ] self.mouse_control = m_loop return self