db_resize_for_test.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import math
  2. import sys
  3. import cv2
  4. import numpy as np
  5. class DetResizeForTest(object):
  6. def __init__(self, **kwargs):
  7. super(DetResizeForTest, self).__init__()
  8. self.resize_type = 0
  9. self.keep_ratio = False
  10. if 'image_shape' in kwargs:
  11. self.image_shape = kwargs['image_shape']
  12. self.resize_type = 1
  13. if 'keep_ratio' in kwargs:
  14. self.keep_ratio = kwargs['keep_ratio']
  15. elif 'limit_side_len' in kwargs:
  16. self.limit_side_len = kwargs['limit_side_len']
  17. self.limit_type = kwargs.get('limit_type', 'min')
  18. elif 'resize_long' in kwargs:
  19. self.resize_type = 2
  20. self.resize_long = kwargs.get('resize_long', 960)
  21. else:
  22. self.limit_side_len = 736
  23. self.limit_type = 'min'
  24. def __call__(self, data):
  25. img = data['image']
  26. if 'max_sile_len' in data:
  27. self.limit_side_len = data['max_sile_len']
  28. src_h, src_w, _ = img.shape
  29. if sum([src_h, src_w]) < 64:
  30. img = self.image_padding(img)
  31. if self.resize_type == 0:
  32. # img, shape = self.resize_image_type0(img)
  33. img, [ratio_h, ratio_w] = self.resize_image_type0(img)
  34. elif self.resize_type == 2:
  35. img, [ratio_h, ratio_w] = self.resize_image_type2(img)
  36. else:
  37. # img, shape = self.resize_image_type1(img)
  38. img, [ratio_h, ratio_w] = self.resize_image_type1(img)
  39. data['image'] = img
  40. data['shape'] = np.array([src_h, src_w, ratio_h, ratio_w])
  41. return data
  42. def image_padding(self, im, value=0):
  43. h, w, c = im.shape
  44. im_pad = np.zeros((max(32, h), max(32, w), c), np.uint8) + value
  45. im_pad[:h, :w, :] = im
  46. return im_pad
  47. def resize_image_type1(self, img):
  48. resize_h, resize_w = self.image_shape
  49. ori_h, ori_w = img.shape[:2] # (h, w, c)
  50. if self.keep_ratio is True:
  51. resize_w = ori_w * resize_h / ori_h
  52. N = math.ceil(resize_w / 32)
  53. resize_w = N * 32
  54. ratio_h = float(resize_h) / ori_h
  55. ratio_w = float(resize_w) / ori_w
  56. img = cv2.resize(img, (int(resize_w), int(resize_h)))
  57. # return img, np.array([ori_h, ori_w])
  58. return img, [ratio_h, ratio_w]
  59. def resize_image_type0(self, img):
  60. """
  61. resize image to a size multiple of 32 which is required by the network
  62. args:
  63. img(array): array with shape [h, w, c]
  64. return(tuple):
  65. img, (ratio_h, ratio_w)
  66. """
  67. limit_side_len = self.limit_side_len
  68. h, w, c = img.shape
  69. # limit the max side
  70. if self.limit_type == 'max':
  71. if max(h, w) > limit_side_len:
  72. if h > w:
  73. ratio = float(limit_side_len) / h
  74. else:
  75. ratio = float(limit_side_len) / w
  76. else:
  77. ratio = 1.0
  78. elif self.limit_type == 'min':
  79. if min(h, w) < limit_side_len:
  80. if h < w:
  81. ratio = float(limit_side_len) / h
  82. else:
  83. ratio = float(limit_side_len) / w
  84. else:
  85. ratio = 1.0
  86. elif self.limit_type == 'resize_long':
  87. ratio = float(limit_side_len) / max(h, w)
  88. else:
  89. raise Exception('not support limit type, image ')
  90. resize_h = int(h * ratio)
  91. resize_w = int(w * ratio)
  92. resize_h = max(int(round(resize_h / 32) * 32), 32)
  93. resize_w = max(int(round(resize_w / 32) * 32), 32)
  94. try:
  95. if int(resize_w) <= 0 or int(resize_h) <= 0:
  96. return None, (None, None)
  97. img = cv2.resize(img, (int(resize_w), int(resize_h)))
  98. except:
  99. print(img.shape, resize_w, resize_h)
  100. sys.exit(0)
  101. ratio_h = resize_h / float(h)
  102. ratio_w = resize_w / float(w)
  103. return img, [ratio_h, ratio_w]
  104. def resize_image_type2(self, img):
  105. h, w, _ = img.shape
  106. resize_w = w
  107. resize_h = h
  108. if resize_h > resize_w:
  109. ratio = float(self.resize_long) / resize_h
  110. else:
  111. ratio = float(self.resize_long) / resize_w
  112. resize_h = int(resize_h * ratio)
  113. resize_w = int(resize_w * ratio)
  114. max_stride = 128
  115. resize_h = (resize_h + max_stride - 1) // max_stride * max_stride
  116. resize_w = (resize_w + max_stride - 1) // max_stride * max_stride
  117. img = cv2.resize(img, (int(resize_w), int(resize_h)))
  118. ratio_h = resize_h / float(h)
  119. ratio_w = resize_w / float(w)
  120. return img, [ratio_h, ratio_w]