You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

bb_generator.py 4.5KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. from typing import List, Optional, Tuple
  2. import numpy as np
  3. import torch
  4. import torch.nn.functional as F
  5. def _generate_receptive_area(size: np.ndarray,
  6. start_ratio: np.ndarray,
  7. end_ratio: np.ndarray,
  8. receptive_radius: Optional[int] = 0) -> torch.Tensor:
  9. """
  10. Generate the map of bounding box's receptive area
  11. Args:
  12. size (np.ndarray): The size of the map
  13. start_ratio (np.ndarray): ratio of the start point
  14. end_ratio (np.ndarray): ratio of the end point
  15. receptive_radius (Optional[int]): radius of the receptive field. Default is 0.
  16. Returns:
  17. torch.Tensor: map of the receptive area
  18. """
  19. x_s, y_s = np.floor(size * start_ratio).astype(int)
  20. x_e, y_e = np.floor(size * end_ratio).astype(int)
  21. point = torch.FloatTensor([[[
  22. [0, 0, 0],
  23. [0, 1, 0],
  24. [0, 0, 0],
  25. ]]])
  26. point = F.interpolate(point, receptive_radius * 2, mode='bilinear', align_corners=True).squeeze()
  27. map = torch.zeros(*size)
  28. map[max(x_s-receptive_radius, 0):x_s, max(y_s-receptive_radius, 0):y_s] = point[max(receptive_radius-x_s, 0):receptive_radius, max(receptive_radius-y_s, 0):receptive_radius]
  29. map[x_e:min(x_e+receptive_radius, size[0]), max(y_s-receptive_radius, 0):y_s] = point[receptive_radius:min(receptive_radius+size[0]-x_e, 2*receptive_radius), max(receptive_radius-y_s, 0):receptive_radius]
  30. map[max(x_s-receptive_radius, 0):x_s, y_e:min(y_e+receptive_radius, size[1])] = point[max(receptive_radius-x_s, 0):receptive_radius, receptive_radius:min(receptive_radius+size[1]-y_e, 2*receptive_radius)]
  31. map[x_e:min(x_e+receptive_radius, size[0]), y_e:min(y_e+receptive_radius, size[1])] = point[receptive_radius:min(receptive_radius+size[0]-x_e, 2*receptive_radius), receptive_radius:min(receptive_radius+size[1]-y_e, 2*receptive_radius)]
  32. horizontal = torch.FloatTensor([[[[0, 1, 0]]]])
  33. horizontal = F.interpolate(horizontal, (x_e - x_s, receptive_radius * 2), mode='bilinear', align_corners=True).squeeze()
  34. map[x_s:x_e, max(y_s-receptive_radius, 0):y_s] = horizontal[:, max(receptive_radius-y_s, 0):receptive_radius]
  35. map[x_s:x_e, y_e:min(y_e+receptive_radius, size[1])] = horizontal[:, receptive_radius:min(receptive_radius+size[1]-y_e, 2*receptive_radius)]
  36. vertical = torch.FloatTensor([[[
  37. [0],
  38. [1],
  39. [0],
  40. ]]])
  41. vertical = F.interpolate(vertical, (receptive_radius * 2, y_e - y_s), mode='bilinear', align_corners=True).squeeze()
  42. map[max(x_s-receptive_radius, 0):x_s, y_s:y_e] = vertical[max(receptive_radius-x_s, 0):receptive_radius, :]
  43. map[x_e:min(x_e+receptive_radius, size[0]), y_s:y_e] = vertical[receptive_radius:min(receptive_radius+size[0]-x_e, 2*receptive_radius), :]
  44. return map
  45. def _generate_bb(size: np.ndarray,
  46. start_ratio: np.ndarray,
  47. end_ratio: np.ndarray) -> torch.Tensor:
  48. """
  49. Generate the map of the bounding box
  50. Args:
  51. size (np.ndarray): The size of the map
  52. start_ratio (np.ndarray): ratio of the start point
  53. end_ratio (np.ndarray): ratio of the end point
  54. Returns:
  55. torch.Tensor: map of the bounding box
  56. """
  57. x_s, y_s = np.floor(size * start_ratio).astype(int)
  58. x_e, y_e = np.floor(size * end_ratio).astype(int)
  59. map = torch.zeros(*size)
  60. map[x_s:x_e, y_s:y_e] = 1
  61. return map
  62. def generate_bb_map(start_ratios: List[Tuple[float, float]],
  63. end_ratios: List[Tuple[float, float]],
  64. size: Tuple[int, int],
  65. receptive_radius: Optional[int] = 0) -> np.ndarray:
  66. """
  67. Generate map of the given bounding box
  68. Args:
  69. start_ratios (List[Tuple[float, float]]): list of ratios of each bounding box's start point
  70. end_ratios (List[Tuple[float, float]]): list of ratios of each bounding box's end point
  71. size (Tuple[int, int]): Size of the map
  72. receptive_radius (Optional[int]): radius of the receptive field. Default is 0.
  73. Returns:
  74. np.ndarray: map of the bounding box
  75. """
  76. map = torch.zeros(size)
  77. size = np.array(size)
  78. for start_ratio, end_ratio in zip(start_ratios, end_ratios):
  79. start_ratio = np.array(start_ratio)
  80. end_ratio = np.array(end_ratio)
  81. map += _generate_bb(size, start_ratio, end_ratio)
  82. if receptive_radius > 0:
  83. map += _generate_receptive_area(size, start_ratio, end_ratio, receptive_radius)
  84. return map.clamp(0, 1).numpy()