misc.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import os
  2. import cv2
  3. import khandy
  4. import numpy as np
  5. from PIL import Image
  6. def imread_pil(filename, to_mode='RGB'):
  7. with open(filename, 'rb') as f:
  8. img = Image.open(f)
  9. if to_mode is None:
  10. return img
  11. else:
  12. return img.convert(to_mode)
  13. def imread_cv(filename_or_buffer, flags=-1):
  14. """Improvement on cv2.imread, make it support filename including chinese character.
  15. """
  16. try:
  17. if isinstance(filename_or_buffer, bytes):
  18. return cv2.imdecode(np.frombuffer(filename_or_buffer, dtype=np.uint8), flags)
  19. else:
  20. return cv2.imdecode(np.fromfile(filename_or_buffer, dtype=np.uint8), flags)
  21. except Exception as e:
  22. return None
  23. def imwrite_cv(filename, image):
  24. """Improvement on cv2.imwrite, make it support filename including chinese character.
  25. """
  26. cv2.imencode(os.path.splitext(filename)[-1], image)[1].tofile(filename)
  27. def normalize_image_dtype(image, keep_num_channels=False):
  28. """Normalize image dtype to uint8 (usually for visualization).
  29. Args:
  30. image : ndarray
  31. Input image.
  32. keep_num_channels : bool, optional
  33. If this is set to True, the result is an array which has
  34. the same shape as input image, otherwise the result is
  35. an array whose channels number is 3.
  36. Returns:
  37. out: ndarray
  38. Image whose dtype is np.uint8.
  39. """
  40. assert (image.ndim == 3 and image.shape[-1] in [1, 3]) or (image.ndim == 2)
  41. image = image.astype(np.float32)
  42. image = khandy.minmax_normalize(image, axis=None, copy=False)
  43. image = np.array(image * 255, dtype=np.uint8)
  44. if not keep_num_channels:
  45. if image.ndim == 2:
  46. image = np.expand_dims(image, -1)
  47. if image.shape[-1] == 1:
  48. image = np.tile(image, (1,1,3))
  49. return image
  50. def normalize_image_shape(image, swap_rb=False):
  51. """Normalize image shape to (h, w, 3).
  52. Args:
  53. image : ndarray
  54. Input image.
  55. swap_rb : bool, optional
  56. whether swap red and blue channel or not
  57. Returns:
  58. out: ndarray
  59. Image whose shape is (h, w, 3).
  60. """
  61. if image.ndim == 2:
  62. image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
  63. elif image.ndim == 3:
  64. num_channels = image.shape[-1]
  65. if num_channels == 1:
  66. image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
  67. elif num_channels == 3:
  68. if swap_rb:
  69. image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  70. elif num_channels == 4:
  71. if swap_rb:
  72. image = cv2.cvtColor(image, cv2.COLOR_BGRA2RGB)
  73. else:
  74. image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)
  75. else:
  76. raise ValueError('Unsupported!')
  77. else:
  78. raise ValueError('Unsupported!')
  79. return image
  80. def stack_image_list(image_list, dtype=np.float32):
  81. """Join a sequence of image along a new axis before first axis.
  82. References:
  83. `im_list_to_blob` in `py-faster-rcnn-master/lib/utils/blob.py`
  84. """
  85. assert isinstance(image_list, (tuple, list))
  86. max_dimension = np.array([image.ndim for image in image_list]).max()
  87. assert max_dimension in [2, 3]
  88. max_shape = np.array([image.shape[:2] for image in image_list]).max(axis=0)
  89. num_channels = []
  90. for image in image_list:
  91. if image.ndim == 2:
  92. num_channels.append(1)
  93. else:
  94. num_channels.append(image.shape[-1])
  95. assert len(set(num_channels) - set([1])) in [0, 1]
  96. max_num_channels = np.max(num_channels)
  97. blob = np.empty((len(image_list), max_shape[0], max_shape[1], max_num_channels), dtype=dtype)
  98. for k, image in enumerate(image_list):
  99. blob[k, :image.shape[0], :image.shape[1], :] = np.atleast_3d(image).astype(dtype, copy=False)
  100. if max_dimension == 2:
  101. blob = np.squeeze(blob, axis=-1)
  102. return blob
  103. def is_numpy_image(image):
  104. return isinstance(image, np.ndarray) and image.ndim in {2, 3}
  105. def is_gray_image(image, tol=3):
  106. assert is_numpy_image(image)
  107. if image.ndim == 2:
  108. return True
  109. elif image.ndim == 3:
  110. num_channels = image.shape[-1]
  111. if num_channels == 1:
  112. return True
  113. elif num_channels == 4:
  114. rgb = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)
  115. gray = cv2.cvtColor(rgb, cv2.COLOR_BGR2GRAY)
  116. gray3 = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
  117. mae = np.mean(cv2.absdiff(rgb, gray3))
  118. return mae <= tol
  119. elif num_channels == 3:
  120. gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  121. gray3 = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
  122. mae = np.mean(cv2.absdiff(image, gray3))
  123. return mae <= tol
  124. else:
  125. return False
  126. else:
  127. return False