functions.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. # Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import cv2
  15. import numpy as np
  16. import shapely.ops
  17. from shapely.geometry import Polygon, MultiPolygon, GeometryCollection
  18. import copy
  19. def normalize(im, mean, std, min_value=[0, 0, 0], max_value=[255, 255, 255]):
  20. # Rescaling (min-max normalization)
  21. range_value = np.asarray(
  22. [1. / (max_value[i] - min_value[i]) for i in range(len(max_value))],
  23. dtype=np.float32)
  24. im = (im - np.asarray(min_value, dtype=np.float32)) * range_value
  25. # Standardization (Z-score Normalization)
  26. im -= mean
  27. im /= std
  28. return im
  29. def permute(im, to_bgr=False):
  30. im = np.swapaxes(im, 1, 2)
  31. im = np.swapaxes(im, 1, 0)
  32. if to_bgr:
  33. im = im[[2, 1, 0], :, :]
  34. return im
  35. def center_crop(im, crop_size=224):
  36. height, width = im.shape[:2]
  37. w_start = (width - crop_size) // 2
  38. h_start = (height - crop_size) // 2
  39. w_end = w_start + crop_size
  40. h_end = h_start + crop_size
  41. im = im[h_start:h_end, w_start:w_end, ...]
  42. return im
  43. def horizontal_flip(im):
  44. im = im[:, ::-1, ...]
  45. return im
  46. def vertical_flip(im):
  47. im = im[::-1, :, ...]
  48. return im
  49. def rgb2bgr(im):
  50. return im[:, :, ::-1]
  51. def is_poly(poly):
  52. assert isinstance(poly, (list, dict)), \
  53. "Invalid poly type: {}".format(type(poly))
  54. return isinstance(poly, list)
  55. def horizontal_flip_poly(poly, width):
  56. flipped_poly = np.array(poly)
  57. flipped_poly[0::2] = width - np.array(poly[0::2])
  58. return flipped_poly.tolist()
  59. def horizontal_flip_rle(rle, height, width):
  60. import pycocotools.mask as mask_util
  61. if 'counts' in rle and type(rle['counts']) == list:
  62. rle = mask_util.frPyObjects(rle, height, width)
  63. mask = mask_util.decode(rle)
  64. mask = mask[:, ::-1]
  65. rle = mask_util.encode(np.array(mask, order='F', dtype=np.uint8))
  66. return rle
  67. def vertical_flip_poly(poly, height):
  68. flipped_poly = np.array(poly)
  69. flipped_poly[1::2] = height - np.array(poly[1::2])
  70. return flipped_poly.tolist()
  71. def vertical_flip_rle(rle, height, width):
  72. import pycocotools.mask as mask_util
  73. if 'counts' in rle and type(rle['counts']) == list:
  74. rle = mask_util.frPyObjects(rle, height, width)
  75. mask = mask_util.decode(rle)
  76. mask = mask[::-1, :]
  77. rle = mask_util.encode(np.array(mask, order='F', dtype=np.uint8))
  78. return rle
  79. def crop_poly(segm, crop):
  80. xmin, ymin, xmax, ymax = crop
  81. crop_coord = [xmin, ymin, xmin, ymax, xmax, ymax, xmax, ymin]
  82. crop_p = np.array(crop_coord).reshape(4, 2)
  83. crop_p = Polygon(crop_p)
  84. crop_segm = list()
  85. for poly in segm:
  86. poly = np.array(poly).reshape(len(poly) // 2, 2)
  87. polygon = Polygon(poly)
  88. if not polygon.is_valid:
  89. exterior = polygon.exterior
  90. multi_lines = exterior.intersection(exterior)
  91. polygons = shapely.ops.polygonize(multi_lines)
  92. polygon = MultiPolygon(polygons)
  93. multi_polygon = list()
  94. if isinstance(polygon, MultiPolygon):
  95. multi_polygon = copy.deepcopy(polygon)
  96. else:
  97. multi_polygon.append(copy.deepcopy(polygon))
  98. for per_polygon in multi_polygon:
  99. inter = per_polygon.intersection(crop_p)
  100. if not inter:
  101. continue
  102. if isinstance(inter, (MultiPolygon, GeometryCollection)):
  103. for part in inter:
  104. if not isinstance(part, Polygon):
  105. continue
  106. part = np.squeeze(
  107. np.array(part.exterior.coords[:-1]).reshape(1, -1))
  108. part[0::2] -= xmin
  109. part[1::2] -= ymin
  110. crop_segm.append(part.tolist())
  111. elif isinstance(inter, Polygon):
  112. crop_poly = np.squeeze(
  113. np.array(inter.exterior.coords[:-1]).reshape(1, -1))
  114. crop_poly[0::2] -= xmin
  115. crop_poly[1::2] -= ymin
  116. crop_segm.append(crop_poly.tolist())
  117. else:
  118. continue
  119. return crop_segm
  120. def crop_rle(rle, crop, height, width):
  121. import pycocotools.mask as mask_util
  122. if 'counts' in rle and type(rle['counts']) == list:
  123. rle = mask_util.frPyObjects(rle, height, width)
  124. mask = mask_util.decode(rle)
  125. mask = mask[crop[1]:crop[3], crop[0]:crop[2]]
  126. rle = mask_util.encode(np.array(mask, order='F', dtype=np.uint8))
  127. return rle
  128. def expand_poly(poly, x, y):
  129. expanded_poly = np.array(poly)
  130. expanded_poly[0::2] += x
  131. expanded_poly[1::2] += y
  132. return expanded_poly.tolist()
  133. def expand_rle(rle, x, y, height, width, h, w):
  134. import pycocotools.mask as mask_util
  135. if 'counts' in rle and type(rle['counts']) == list:
  136. rle = mask_util.frPyObjects(rle, height, width)
  137. mask = mask_util.decode(rle)
  138. expanded_mask = np.full((h, w), 0).astype(mask.dtype)
  139. expanded_mask[y:y + height, x:x + width] = mask
  140. rle = mask_util.encode(np.array(expanded_mask, order='F', dtype=np.uint8))
  141. return rle
  142. def resize_poly(poly, im_scale_x, im_scale_y):
  143. resized_poly = np.array(poly, dtype=np.float32)
  144. resized_poly[0::2] *= im_scale_x
  145. resized_poly[1::2] *= im_scale_y
  146. return resized_poly.tolist()
  147. def resize_rle(rle, im_h, im_w, im_scale_x, im_scale_y, interp):
  148. import pycocotools.mask as mask_util
  149. if 'counts' in rle and type(rle['counts']) == list:
  150. rle = mask_util.frPyObjects(rle, im_h, im_w)
  151. mask = mask_util.decode(rle)
  152. mask = cv2.resize(
  153. mask, None, None, fx=im_scale_x, fy=im_scale_y, interpolation=interp)
  154. rle = mask_util.encode(np.array(mask, order='F', dtype=np.uint8))
  155. return rle