resize.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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. src_height, src_width = image.shape[:2]
  16. dst_width = int(round(x_scale * src_width))
  17. dst_height = int(round(y_scale * src_height))
  18. resized_image = cv2.resize(image, (dst_width, dst_height),
  19. interpolation=interp_codes[interpolation])
  20. return resized_image
  21. def resize_image(image, dst_width, dst_height, return_scale=False, interpolation='bilinear'):
  22. """Resize image to a given size.
  23. Args:
  24. image (ndarray): The input image.
  25. dst_width (int): Target width.
  26. dst_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. src_height, src_width = image.shape[:2]
  36. resized_image = cv2.resize(image, (dst_width, dst_height),
  37. interpolation=interp_codes[interpolation])
  38. if not return_scale:
  39. return resized_image
  40. else:
  41. x_scale = dst_width / src_width
  42. y_scale = dst_height / src_height
  43. return resized_image, x_scale, y_scale
  44. def resize_image_short(image, dst_size, return_scale=False, interpolation='bilinear'):
  45. """Resize an image so that the length of shorter side is dst_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. src_height, src_width = image.shape[:2]
  51. scale = max(dst_size / src_width, dst_size / src_height)
  52. dst_width = int(round(scale * src_width))
  53. dst_height = int(round(scale * src_height))
  54. resized_image = cv2.resize(image, (dst_width, dst_height),
  55. interpolation=interp_codes[interpolation])
  56. if not return_scale:
  57. return resized_image
  58. else:
  59. return resized_image, scale
  60. def resize_image_long(image, dst_size, return_scale=False, interpolation='bilinear'):
  61. """Resize an image so that the length of longer side is dst_size while
  62. preserving the original aspect ratio.
  63. References:
  64. `resize_max` in `https://github.com/pjreddie/darknet/blob/master/src/image.c`
  65. """
  66. src_height, src_width = image.shape[:2]
  67. scale = min(dst_size / src_width, dst_size / src_height)
  68. dst_width = int(round(scale * src_width))
  69. dst_height = int(round(scale * src_height))
  70. resized_image = cv2.resize(image, (dst_width, dst_height),
  71. interpolation=interp_codes[interpolation])
  72. if not return_scale:
  73. return resized_image
  74. else:
  75. return resized_image, scale
  76. def letterbox_resize_image(image, dst_width, dst_height, pad_val=0,
  77. return_scale=False, interpolation='bilinear'):
  78. """Resize an image preserving the original aspect ratio using padding.
  79. References:
  80. `letterbox_image` in `https://github.com/pjreddie/darknet/blob/master/src/image.c`
  81. """
  82. src_height, src_width = image.shape[:2]
  83. scale = min(dst_width / src_width, dst_height / src_height)
  84. resize_w = int(round(scale * src_width))
  85. resize_h = int(round(scale * src_height))
  86. resized_image = cv2.resize(image, (resize_w, resize_h),
  87. interpolation=interp_codes[interpolation])
  88. padded_shape = list(resized_image.shape)
  89. padded_shape[0] = dst_height
  90. padded_shape[1] = dst_width
  91. padded_image = np.full(padded_shape, pad_val, image.dtype)
  92. dw = (dst_width - resize_w) // 2
  93. dh = (dst_height - resize_h) // 2
  94. padded_image[dh: resize_h + dh, dw: resize_w + dw, ...] = resized_image
  95. if not return_scale:
  96. return padded_image
  97. else:
  98. return padded_image, scale, dw, dh
  99. def resize_image_to_range(image, min_length, max_length, return_scale=False, interpolation='bilinear'):
  100. """Resizes an image so its dimensions are within the provided value.
  101. Rescale the shortest side of the image up to `min_length` pixels
  102. while keeping the largest side below `max_length` pixels without
  103. changing the aspect ratio. Often used in object detection (e.g. RCNN and SSH.)
  104. The output size can be described by two cases:
  105. 1. If the image can be rescaled so its shortest side is equal to the
  106. `min_length` without the other side exceeding `max_length`, then do so.
  107. 2. Otherwise, resize so the longest side is equal to `max_length`.
  108. Returns:
  109. resized_image: resized image (with bilinear interpolation) so that
  110. min(new_height, new_width) == min_length or
  111. max(new_height, new_width) == max_length.
  112. References:
  113. `resize_to_range` in `models-master/research/object_detection/core/preprocessor.py`
  114. `prep_im_for_blob` in `py-faster-rcnn-master/lib/utils/blob.py`
  115. mmcv.imrescale
  116. """
  117. assert min_length < max_length
  118. ori_height, ori_width = image.shape[:2]
  119. min_side_length = np.minimum(ori_width, ori_height)
  120. max_side_length = np.maximum(ori_width, ori_height)
  121. scale = min_length / min_side_length
  122. if round(scale * max_side_length) > max_length:
  123. scale = max_length / max_side_length
  124. new_width = int(round(scale * ori_width))
  125. new_height = int(round(scale * ori_height))
  126. resized_image = cv2.resize(image, (new_width, new_height),
  127. interpolation=interp_codes[interpolation])
  128. if not return_scale:
  129. return resized_image
  130. else:
  131. return resized_image, scale