translate.py 2.2 KB

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