crop_or_pad.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import cv2
  2. import numpy as np
  3. def crop_or_pad(image, crop_size, crop_center=None, pad_val=None):
  4. """
  5. References:
  6. tf.image.resize_image_with_crop_or_pad
  7. """
  8. assert image.ndim in [2, 3]
  9. src_height, src_width = image.shape[:2]
  10. channels = 1 if image.ndim == 2 else image.shape[2]
  11. dst_height, dst_width = crop_size[1], crop_size[0]
  12. if crop_center is None:
  13. crop_center = [src_width // 2, src_height // 2]
  14. if pad_val is not None:
  15. if isinstance(pad_val, (int, float)):
  16. pad_val = [pad_val for _ in range(channels)]
  17. assert len(pad_val) == channels
  18. crop_begin_x = int(round(crop_center[0] - dst_width / 2.0))
  19. crop_begin_y = int(round(crop_center[1] - dst_height / 2.0))
  20. src_begin_x = max(0, crop_begin_x)
  21. src_begin_y = max(0, crop_begin_y)
  22. src_end_x = min(src_width, crop_begin_x + dst_width)
  23. src_end_y = min(src_height, crop_begin_y + dst_height)
  24. dst_begin_x = max(0, -crop_begin_x)
  25. dst_begin_y = max(0, -crop_begin_y)
  26. dst_end_x = dst_begin_x + src_end_x - src_begin_x
  27. dst_end_y = dst_begin_y + src_end_y - src_begin_y
  28. if image.ndim == 2:
  29. cropped_image_shape = (dst_height, dst_width)
  30. else:
  31. cropped_image_shape = (dst_height, dst_width, channels)
  32. if pad_val is None:
  33. cropped = np.zeros(cropped_image_shape, image.dtype)
  34. else:
  35. cropped = np.full(cropped_image_shape, pad_val, dtype=image.dtype)
  36. if (src_end_x - src_begin_x <= 0) or (src_end_y - src_begin_y <= 0):
  37. return cropped
  38. else:
  39. cropped[dst_begin_y: dst_end_y, dst_begin_x: dst_end_x, ...] = \
  40. image[src_begin_y: src_end_y, src_begin_x: src_end_x, ...]
  41. return cropped
  42. def crop_or_pad_coords(boxes, image_width, image_height):
  43. """
  44. References:
  45. `mmcv.impad`
  46. `pad` in https://github.com/kpzhang93/MTCNN_face_detection_alignment
  47. `MtcnnDetector.pad` in https://github.com/AITTSMD/MTCNN-Tensorflow
  48. """
  49. x_mins = boxes[:, 0]
  50. y_mins = boxes[:, 1]
  51. x_maxs = boxes[:, 2]
  52. y_maxs = boxes[:, 3]
  53. src_x_begin = np.maximum(x_mins, 0)
  54. src_y_begin = np.maximum(y_mins, 0)
  55. src_x_end = np.minimum(x_maxs + 1, image_width)
  56. src_y_end = np.minimum(y_maxs + 1, image_height)
  57. dst_x_begin = src_x_begin - x_mins
  58. dst_y_begin = src_y_begin - y_mins
  59. dst_x_end = src_x_end - x_mins
  60. dst_y_end = src_y_end - y_mins
  61. coords = np.stack([src_x_begin, src_y_begin, src_x_end, src_y_end,
  62. dst_x_begin, dst_y_begin, dst_x_end, dst_y_end], axis=1)
  63. return coords