test.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import numpy as np
  2. import sys
  3. import time
  4. from shapely.geometry import Polygon
  5. import paddle
  6. import unittest
  7. try:
  8. from rbox_iou_ops import rbox_iou
  9. except Exception as e:
  10. print('import rbox_iou_ops error', e)
  11. sys.exit(-1)
  12. def rbox2poly_single(rrect, get_best_begin_point=False):
  13. """
  14. rrect:[x_ctr,y_ctr,w,h,angle]
  15. to
  16. poly:[x0,y0,x1,y1,x2,y2,x3,y3]
  17. """
  18. x_ctr, y_ctr, width, height, angle = rrect[:5]
  19. tl_x, tl_y, br_x, br_y = -width / 2, -height / 2, width / 2, height / 2
  20. # rect 2x4
  21. rect = np.array([[tl_x, br_x, br_x, tl_x], [tl_y, tl_y, br_y, br_y]])
  22. R = np.array([[np.cos(angle), -np.sin(angle)],
  23. [np.sin(angle), np.cos(angle)]])
  24. # poly
  25. poly = R.dot(rect)
  26. x0, x1, x2, x3 = poly[0, :4] + x_ctr
  27. y0, y1, y2, y3 = poly[1, :4] + y_ctr
  28. poly = np.array([x0, y0, x1, y1, x2, y2, x3, y3], dtype=np.float64)
  29. return poly
  30. def intersection(g, p):
  31. """
  32. Intersection.
  33. """
  34. g = g[:8].reshape((4, 2))
  35. p = p[:8].reshape((4, 2))
  36. a = g
  37. b = p
  38. use_filter = True
  39. if use_filter:
  40. # step1:
  41. inter_x1 = np.maximum(np.min(a[:, 0]), np.min(b[:, 0]))
  42. inter_x2 = np.minimum(np.max(a[:, 0]), np.max(b[:, 0]))
  43. inter_y1 = np.maximum(np.min(a[:, 1]), np.min(b[:, 1]))
  44. inter_y2 = np.minimum(np.max(a[:, 1]), np.max(b[:, 1]))
  45. if inter_x1 >= inter_x2 or inter_y1 >= inter_y2:
  46. return 0.
  47. x1 = np.minimum(np.min(a[:, 0]), np.min(b[:, 0]))
  48. x2 = np.maximum(np.max(a[:, 0]), np.max(b[:, 0]))
  49. y1 = np.minimum(np.min(a[:, 1]), np.min(b[:, 1]))
  50. y2 = np.maximum(np.max(a[:, 1]), np.max(b[:, 1]))
  51. if x1 >= x2 or y1 >= y2 or (x2 - x1) < 2 or (y2 - y1) < 2:
  52. return 0.
  53. g = Polygon(g)
  54. p = Polygon(p)
  55. if not g.is_valid or not p.is_valid:
  56. return 0
  57. inter = Polygon(g).intersection(Polygon(p)).area
  58. union = g.area + p.area - inter
  59. if union == 0:
  60. return 0
  61. else:
  62. return inter / union
  63. def rbox_overlaps(anchors, gt_bboxes, use_cv2=False):
  64. """
  65. Args:
  66. anchors: [NA, 5] x1,y1,x2,y2,angle
  67. gt_bboxes: [M, 5] x1,y1,x2,y2,angle
  68. Returns:
  69. """
  70. assert anchors.shape[1] == 5
  71. assert gt_bboxes.shape[1] == 5
  72. gt_bboxes_ploy = [rbox2poly_single(e) for e in gt_bboxes]
  73. anchors_ploy = [rbox2poly_single(e) for e in anchors]
  74. num_gt, num_anchors = len(gt_bboxes_ploy), len(anchors_ploy)
  75. iou = np.zeros((num_gt, num_anchors), dtype=np.float64)
  76. start_time = time.time()
  77. for i in range(num_gt):
  78. for j in range(num_anchors):
  79. try:
  80. iou[i, j] = intersection(gt_bboxes_ploy[i], anchors_ploy[j])
  81. except Exception as e:
  82. print('cur gt_bboxes_ploy[i]', gt_bboxes_ploy[i],
  83. 'anchors_ploy[j]', anchors_ploy[j], e)
  84. iou = iou.T
  85. return iou
  86. def gen_sample(n):
  87. rbox = np.random.rand(n, 5)
  88. rbox[:, 0:4] = rbox[:, 0:4] * 0.45 + 0.001
  89. rbox[:, 4] = rbox[:, 4] - 0.5
  90. return rbox
  91. class RBoxIoUTest(unittest.TestCase):
  92. def setUp(self):
  93. self.initTestCase()
  94. self.rbox1 = gen_sample(self.n)
  95. self.rbox2 = gen_sample(self.m)
  96. def initTestCase(self):
  97. self.n = 13000
  98. self.m = 7
  99. def assertAllClose(self, x, y, msg, atol=5e-1, rtol=1e-2):
  100. self.assertTrue(np.allclose(x, y, atol=atol, rtol=rtol), msg=msg)
  101. def get_places(self):
  102. places = [paddle.CPUPlace()]
  103. if paddle.device.is_compiled_with_cuda():
  104. places.append(paddle.CUDAPlace(0))
  105. return places
  106. def check_output(self, place):
  107. paddle.disable_static()
  108. pd_rbox1 = paddle.to_tensor(self.rbox1, place=place)
  109. pd_rbox2 = paddle.to_tensor(self.rbox2, place=place)
  110. actual_t = rbox_iou(pd_rbox1, pd_rbox2).numpy()
  111. poly_rbox1 = self.rbox1
  112. poly_rbox2 = self.rbox2
  113. poly_rbox1[:, 0:4] = self.rbox1[:, 0:4] * 1024
  114. poly_rbox2[:, 0:4] = self.rbox2[:, 0:4] * 1024
  115. expect_t = rbox_overlaps(poly_rbox1, poly_rbox2, use_cv2=False)
  116. self.assertAllClose(
  117. actual_t,
  118. expect_t,
  119. msg="rbox_iou has diff at {} \nExpect {}\nBut got {}".format(
  120. str(place), str(expect_t), str(actual_t)))
  121. def test_output(self):
  122. places = self.get_places()
  123. for place in places:
  124. self.check_output(place)
  125. if __name__ == "__main__":
  126. unittest.main()