resize.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import cv2
  2. import numpy as np
  3. interp_codes = {
  4. 'nearest': cv2.INTER_NEAREST,
  5. 'bilinear': cv2.INTER_LINEAR,
  6. 'bicubic': cv2.INTER_CUBIC,
  7. 'area': cv2.INTER_AREA,
  8. 'lanczos': cv2.INTER_LANCZOS4
  9. }
  10. def scale_image(image, x_scale, y_scale, interpolation='bilinear'):
  11. """Scale image.
  12. Reference:
  13. mmcv.imrescale
  14. """
  15. ori_height, ori_width = image.shape[:2]
  16. new_width = int(round(x_scale * ori_width))
  17. new_height = int(round(y_scale * ori_height))
  18. resized_image = cv2.resize(image, (new_width, new_height),
  19. interpolation=interp_codes[interpolation])
  20. return resized_image
  21. def resize_image(image, width, height, return_scale=False, interpolation='bilinear'):
  22. """Resize image to a given size.
  23. Args:
  24. img (ndarray): The input image.
  25. width (int): Target width.
  26. height (int): Target height.
  27. return_scale (bool): Whether to return `x_scale` and `y_scale`.
  28. interpolation (str): Interpolation method, accepted values are
  29. "nearest", "bilinear", "bicubic", "area", "lanczos".
  30. Returns:
  31. tuple or ndarray: (`resized_image`, `x_scale`, `y_scale`) or `resized_image`.
  32. Reference:
  33. mmcv.imresize
  34. """
  35. ori_height, ori_width = image.shape[:2]
  36. resized_image = cv2.resize(image, (width, height),
  37. interpolation=interp_codes[interpolation])
  38. if not return_scale:
  39. return resized_image
  40. else:
  41. x_scale = width / ori_width
  42. y_scale = height / ori_height
  43. return resized_image, x_scale, y_scale
  44. def resize_image_short(image, size, return_scale=False, interpolation='bilinear'):
  45. """Resize an image so that the length of shorter side is size while
  46. preserving the original aspect ratio.
  47. References:
  48. `resize_min` in `https://github.com/pjreddie/darknet/blob/master/src/image.c`
  49. """
  50. ori_height, ori_width = image.shape[:2]
  51. new_height, new_width = size, size
  52. if ori_height > ori_width:
  53. new_height = int(round(size * ori_height / ori_width))
  54. else:
  55. new_width = int(round(size * ori_width / ori_height))
  56. resized_image = cv2.resize(image, (new_width, new_height),
  57. interpolation=interp_codes[interpolation])
  58. if not return_scale:
  59. return resized_image
  60. else:
  61. scale = new_width / ori_width
  62. return resized_image, scale
  63. def resize_image_long(image, size, return_scale=False, interpolation='bilinear'):
  64. """Resize an image so that the length of longer side is size while
  65. preserving the original aspect ratio.
  66. References:
  67. `resize_max` in `https://github.com/pjreddie/darknet/blob/master/src/image.c`
  68. """
  69. ori_height, ori_width = image.shape[:2]
  70. new_height, new_width = size, size
  71. if ori_height < ori_width:
  72. new_height = int(round(size * ori_height / ori_width))
  73. else:
  74. new_width = int(round(size * ori_width / ori_height))
  75. resized_image = cv2.resize(image, (new_width, new_height),
  76. interpolation=interp_codes[interpolation])
  77. if not return_scale:
  78. return resized_image
  79. else:
  80. scale = new_width / ori_width
  81. return resized_image, scale
  82. def letterbox_resize_image(image, new_width, new_height, pad_val=0,
  83. return_scale=False, interpolation='bilinear'):
  84. """Resize an image preserving the original aspect ratio using padding.
  85. References:
  86. `letterbox_image` in `https://github.com/pjreddie/darknet/blob/master/src/image.c`
  87. """
  88. ori_height, ori_width = image.shape[:2]
  89. scale = min(new_width / ori_width, new_height / ori_height)
  90. resize_w = int(round(scale * ori_width))
  91. resize_h = int(round(scale * ori_height))
  92. resized_image = cv2.resize(image, (resize_w, resize_h),
  93. interpolation=interp_codes[interpolation])
  94. padded_shape = list(resized_image.shape)
  95. padded_shape[0] = new_height
  96. padded_shape[1] = new_width
  97. padded_image = np.full(padded_shape, pad_val, image.dtype)
  98. dw = int(round((new_width - resize_w) / 2.0))
  99. dh = int(round((new_height - resize_h) / 2.0))
  100. padded_image[dh: resize_h + dh, dw: resize_w + dw, ...] = resized_image
  101. if not return_scale:
  102. return padded_image
  103. else:
  104. return padded_image, scale, dw, dh
  105. def resize_image_to_range(image, min_length, max_length, return_scale=False, interpolation='bilinear'):
  106. """Resizes an image so its dimensions are within the provided value.
  107. Rescale the shortest side of the image up to `min_length` pixels
  108. while keeping the largest side below `max_length` pixels without
  109. changing the aspect ratio. Often used in object detection (e.g. RCNN and SSH.)
  110. The output size can be described by two cases:
  111. 1. If the image can be rescaled so its shortest side is equal to the
  112. `min_length` without the other side exceeding `max_length`, then do so.
  113. 2. Otherwise, resize so the longest side is equal to `max_length`.
  114. Returns:
  115. resized_image: resized image (with bilinear interpolation) so that
  116. min(new_height, new_width) == min_length or
  117. max(new_height, new_width) == max_length.
  118. References:
  119. `resize_to_range` in `models-master/research/object_detection/core/preprocessor.py`
  120. `prep_im_for_blob` in `py-faster-rcnn-master/lib/utils/blob.py`
  121. mmcv.imrescale
  122. """
  123. assert min_length < max_length
  124. ori_height, ori_width = image.shape[:2]
  125. min_side_length = np.minimum(ori_width, ori_height)
  126. max_side_length = np.maximum(ori_width, ori_height)
  127. scale = min_length / min_side_length
  128. if round(scale * max_side_length) > max_length:
  129. scale = max_length / max_side_length
  130. new_width = int(round(scale * ori_width))
  131. new_height = int(round(scale * ori_height))
  132. resized_image = cv2.resize(image, (new_width, new_height),
  133. interpolation=interp_codes[interpolation])
  134. if not return_scale:
  135. return resized_image
  136. else:
  137. return resized_image, scale