translate.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import numbers
  2. import khandy
  3. import numpy as np
  4. def translate_image(image, x_shift, y_shift, border_value=0):
  5. """Translate an image.
  6. Args:
  7. image (ndarray): Image to be translated with format (h, w) or (h, w, c).
  8. x_shift (int): The offset used for translate in horizontal
  9. direction. right is the positive direction.
  10. y_shift (int): The offset used for translate in vertical
  11. direction. down is the positive direction.
  12. border_value (int | tuple[int]): Value used in case of a
  13. constant border.
  14. Returns:
  15. ndarray: The translated image.
  16. See Also:
  17. crop_or_pad
  18. """
  19. assert khandy.is_numpy_image(image)
  20. assert isinstance(x_shift, numbers.Integral)
  21. assert isinstance(y_shift, numbers.Integral)
  22. image_height, image_width = image.shape[:2]
  23. channels = 1 if image.ndim == 2 else image.shape[2]
  24. if isinstance(border_value, numbers.Real):
  25. dst_image = np.full_like(image, border_value)
  26. elif isinstance(border_value, tuple):
  27. assert len(border_value) == channels, \
  28. 'Expected the num of elements in tuple equals the channels' \
  29. 'of input image. Found {} vs {}'.format(
  30. len(border_value), channels)
  31. if channels == 1:
  32. dst_image = np.full_like(image, border_value[0])
  33. else:
  34. border_value = np.asarray(border_value, dtype=image.dtype)
  35. dst_image = np.empty_like(image)
  36. dst_image[:] = border_value
  37. else:
  38. raise ValueError(
  39. 'Invalid type {} for `border_value`.'.format(type(border_value)))
  40. if (abs(x_shift) >= image_width) or (abs(y_shift) >= image_height):
  41. return dst_image
  42. src_x_begin = max(-x_shift, 0)
  43. src_x_end = min(image_width - x_shift, image_width)
  44. dst_x_begin = max(x_shift, 0)
  45. dst_x_end = min(image_width + x_shift, image_width)
  46. src_y_begin = max(-y_shift, 0)
  47. src_y_end = min(image_height - y_shift, image_height)
  48. dst_y_begin = max(y_shift, 0)
  49. dst_y_end = min(image_height + y_shift, image_height)
  50. dst_image[dst_y_begin:dst_y_end, dst_x_begin:dst_x_end] = \
  51. image[src_y_begin:src_y_end, src_x_begin:src_x_end]
  52. return dst_image