boxes_transform_scale.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import numpy as np
  2. from .boxes_utils import assert_and_normalize_shape
  3. def scale_boxes(boxes, x_scale=1, y_scale=1, x_center=0, y_center=0, copy=True):
  4. """Scale boxes coordinates in x and y dimensions.
  5. Args:
  6. boxes: (N, 4+K)
  7. x_scale: array-like whose shape is (), (1,), (N,), (1, 1) or (N, 1)
  8. scale factor in x dimension
  9. y_scale: array-like whose shape is (), (1,), (N,), (1, 1) or (N, 1)
  10. scale factor in y dimension
  11. x_center: array-like whose shape is (), (1,), (N,), (1, 1) or (N, 1)
  12. y_center: array-like whose shape is (), (1,), (N,), (1, 1) or (N, 1)
  13. References:
  14. `core.box_list_ops.scale` in TensorFlow object detection API
  15. `utils.box_list_ops.scale` in TensorFlow object detection API
  16. `datasets.pipelines.Resize._resize_bboxes` in mmdetection
  17. `core.anchor.guided_anchor_target.calc_region` in mmdetection where comments may be misleading!
  18. `layers.mask_ops.scale_boxes` in detectron2
  19. `mmcv.bbox_scaling`
  20. """
  21. boxes = np.array(boxes, dtype=np.float32, copy=copy)
  22. x_scale = np.asarray(x_scale, np.float32)
  23. y_scale = np.asarray(y_scale, np.float32)
  24. x_scale = assert_and_normalize_shape(x_scale, boxes.shape[0])
  25. y_scale = assert_and_normalize_shape(y_scale, boxes.shape[0])
  26. x_center = np.asarray(x_center, np.float32)
  27. y_center = np.asarray(y_center, np.float32)
  28. x_center = assert_and_normalize_shape(x_center, boxes.shape[0])
  29. y_center = assert_and_normalize_shape(y_center, boxes.shape[0])
  30. x_shift = 1 - x_scale
  31. y_shift = 1 - y_scale
  32. x_shift *= x_center
  33. y_shift *= y_center
  34. boxes[:, 0] *= x_scale
  35. boxes[:, 1] *= y_scale
  36. boxes[:, 2] *= x_scale
  37. boxes[:, 3] *= y_scale
  38. boxes[:, 0] += x_shift
  39. boxes[:, 1] += y_shift
  40. boxes[:, 2] += x_shift
  41. boxes[:, 3] += y_shift
  42. return boxes
  43. def scale_boxes_wrt_centers(boxes, x_scale=1, y_scale=1, copy=True):
  44. """
  45. Args:
  46. boxes: (N, 4+K)
  47. x_scale: array-like whose shape is (), (1,), (N,), (1, 1) or (N, 1)
  48. scale factor in x dimension
  49. y_scale: array-like whose shape is (), (1,), (N,), (1, 1) or (N, 1)
  50. scale factor in y dimension
  51. References:
  52. `core.anchor.guided_anchor_target.calc_region` in mmdetection where comments may be misleading!
  53. `layers.mask_ops.scale_boxes` in detectron2
  54. `mmcv.bbox_scaling`
  55. """
  56. boxes = np.array(boxes, dtype=np.float32, copy=copy)
  57. x_scale = np.asarray(x_scale, np.float32)
  58. y_scale = np.asarray(y_scale, np.float32)
  59. x_scale = assert_and_normalize_shape(x_scale, boxes.shape[0])
  60. y_scale = assert_and_normalize_shape(y_scale, boxes.shape[0])
  61. x_factor = (x_scale - 1) * 0.5
  62. y_factor = (y_scale - 1) * 0.5
  63. x_deltas = boxes[:, 2] - boxes[:, 0]
  64. y_deltas = boxes[:, 3] - boxes[:, 1]
  65. x_deltas *= x_factor
  66. y_deltas *= y_factor
  67. boxes[:, 0] -= x_deltas
  68. boxes[:, 1] -= y_deltas
  69. boxes[:, 2] += x_deltas
  70. boxes[:, 3] += y_deltas
  71. return boxes