data_limit.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. import numpy as np
  2. from view.python_core.misc import class_mixer
  3. from view.python_core.flags import FlagsManager
  4. class CalculatorDefault(object):
  5. def __init__(self):
  6. super().__init__()
  7. def subsetter(self, data):
  8. return data
  9. def get_min(self, data):
  10. subsetted_data = self.subsetter(data)
  11. return self.min(subsetted_data)
  12. def get_max(self, data):
  13. subsetted_data = self.subsetter(data)
  14. return self.max(subsetted_data)
  15. def min(self, data):
  16. pass
  17. def max(self, data):
  18. pass
  19. def get_data_limit(self, data):
  20. return self.get_min(data), self.get_max(data)
  21. class CalculatorFixedMin(CalculatorDefault):
  22. def __init__(self, SO_MV_scalemin, **kwargs):
  23. super().__init__(**kwargs)
  24. self.SO_MV_scalemin = SO_MV_scalemin
  25. def min(self, data):
  26. return self.SO_MV_scalemin
  27. class CalculatorFixedMax(CalculatorDefault):
  28. def __init__(self, SO_MV_scalemax, **kwargs):
  29. super().__init__(**kwargs)
  30. self.SO_MV_scalemax = SO_MV_scalemax
  31. def max(self, data):
  32. return self.SO_MV_scalemax
  33. class CalculatorNormalMax(CalculatorDefault):
  34. def __init__(self, **kwargs):
  35. super().__init__(**kwargs)
  36. def max(self, data):
  37. return data.max()
  38. class CalculatorNormalMin(CalculatorDefault):
  39. def __init__(self, **kwargs):
  40. super().__init__(**kwargs)
  41. def min(self, data):
  42. return data.min()
  43. class CalculatorPercentileMax(CalculatorDefault):
  44. def __init__(self, percentile_value_from_top, **kwargs):
  45. super().__init__(**kwargs)
  46. self.percentile_value = percentile_value_from_top
  47. def max(self, data):
  48. # method was set to 'nearest' because of numpy bug: https://github.com/numpy/numpy/issues/21524
  49. return np.percentile(data, 100 - self.percentile_value, method='nearest')
  50. class CalculatorPercentileMin(CalculatorDefault):
  51. def __init__(self, percentile_value_from_bottom, **kwargs):
  52. super().__init__(**kwargs)
  53. self.percentile_value = percentile_value_from_bottom
  54. def min(self, data):
  55. # method was set to 'nearest' because of numpy bug: https://github.com/numpy/numpy/issues/21524
  56. return np.percentile(data, self.percentile_value, method='nearest')
  57. class SquareSubsetter2D(CalculatorDefault):
  58. def __init__(self, fractional_margin, **kwargs):
  59. super().__init__(**kwargs)
  60. self.fractional_margin = fractional_margin
  61. def subsetter(self, data):
  62. xborder = int(data.shape[0] * self.fractional_margin)
  63. yborder = int(data.shape[1] * self.fractional_margin)
  64. return data[xborder: data.shape[0] - xborder, yborder: data.shape[1] - yborder]
  65. class SquareSubsetter3D(CalculatorDefault):
  66. def __init__(self, fractional_margin, **kwargs):
  67. super().__init__(**kwargs)
  68. self.fractional_margin = fractional_margin
  69. def subsetter(self, data):
  70. xborder = int(data.shape[0] * self.fractional_margin)
  71. yborder = int(data.shape[1] * self.fractional_margin)
  72. return data[xborder: data.shape[0] - xborder, yborder: data.shape[1] - yborder, :]
  73. class AreaSubsetter2D(CalculatorDefault):
  74. def __init__(self, frame_mask, **kwargs):
  75. super().__init__(**kwargs)
  76. self.frame_mask = frame_mask
  77. def subsetter(self, data):
  78. return np.ma.MaskedArray(data=data, mask=~self.frame_mask)
  79. class AreaSubsetter3D(CalculatorDefault):
  80. def __init__(self, frame_mask, **kwargs):
  81. super().__init__(**kwargs)
  82. self.frame_mask = frame_mask
  83. def subsetter(self, data):
  84. mask_3D = np.stack([self.frame_mask] * data.shape[-1], axis=2)
  85. return np.ma.MaskedArray(data=data, mask=~mask_3D)
  86. def get_data_limit_decider_3D(flags: FlagsManager, frame_mask):
  87. min_max_decider = flags["mv_individualScale"] % 10
  88. if flags["mv_percentileScale"] == 1:
  89. min_class, max_class = CalculatorPercentileMin, CalculatorPercentileMax
  90. min_kwargs, max_kwargs = [{"percentile_value_from_bottom": flags["mv_percentileValue"]},
  91. {"percentile_value_from_top": flags["mv_percentileValue"]}]
  92. else:
  93. min_class, max_class = CalculatorNormalMin, CalculatorNormalMax
  94. min_kwargs, max_kwargs = [{}, {}]
  95. if min_max_decider in [0, 1]:
  96. mixed_class = class_mixer(CalculatorFixedMin, CalculatorFixedMax)
  97. return mixed_class(SO_MV_scalemin=flags["SO_MV_scalemin"], SO_MV_scalemax=flags["SO_MV_scalemax"])
  98. elif min_max_decider == 2:
  99. mixed_class = class_mixer(min_class, max_class)
  100. return mixed_class(**min_kwargs, **max_kwargs)
  101. elif min_max_decider == 3:
  102. mixed_class = class_mixer(SquareSubsetter3D, min_class, max_class)
  103. return mixed_class(fractional_margin=flags["mv_indiScale3factor"], **min_kwargs, **max_kwargs)
  104. elif min_max_decider == 4:
  105. mixed_class = class_mixer(CalculatorFixedMin, max_class)
  106. return mixed_class(SO_MV_scalemin=flags["SO_MV_scalemin"], **max_kwargs)
  107. elif min_max_decider == 5:
  108. mixed_class = class_mixer(AreaSubsetter3D, min_class, max_class)
  109. return mixed_class(frame_mask=frame_mask, **min_kwargs, **max_kwargs)
  110. elif min_max_decider == 6:
  111. mixed_class = class_mixer(AreaSubsetter3D, CalculatorFixedMin, max_class)
  112. return mixed_class(frame_mask=frame_mask, SO_MV_scalemin=flags["SO_MV_scalemin"], **max_kwargs)
  113. else:
  114. raise NotImplementedError
  115. def get_data_limit_decider_2D(flags: FlagsManager, frame_mask):
  116. min_max_decider = flags["SO_individualScale"] % 10
  117. if flags["SO_percentileScale"] == 1:
  118. min_class, max_class = CalculatorPercentileMin, CalculatorPercentileMax
  119. min_kwargs, max_kwargs = [{"percentile_value_from_bottom": flags["SO_percentileValue"]},
  120. {"percentile_value_from_top": flags["SO_percentileValue"]}]
  121. else:
  122. min_class, max_class = CalculatorNormalMin, CalculatorNormalMax
  123. min_kwargs, max_kwargs = [{}, {}]
  124. if min_max_decider in [0, 1]:
  125. mixed_class = class_mixer(CalculatorFixedMin, CalculatorFixedMax)
  126. return mixed_class(SO_MV_scalemin=flags["SO_MV_scalemin"], SO_MV_scalemax=flags["SO_MV_scalemax"])
  127. elif min_max_decider == 2:
  128. mixed_class = class_mixer(min_class, max_class)
  129. return mixed_class(**min_kwargs, **max_kwargs)
  130. elif min_max_decider == 3:
  131. mixed_class = class_mixer(SquareSubsetter2D, min_class, max_class)
  132. return mixed_class(fractional_margin=flags["SO_indiScale3factor"], **min_kwargs, **max_kwargs)
  133. elif min_max_decider == 4:
  134. mixed_class = class_mixer(CalculatorFixedMin, max_class)
  135. return mixed_class(SO_MV_scalemin=flags["SO_MV_scalemin"], **max_kwargs)
  136. elif min_max_decider == 5:
  137. mixed_class = class_mixer(AreaSubsetter2D, min_class, max_class)
  138. return mixed_class(frame_mask=frame_mask, **min_kwargs, **max_kwargs)
  139. elif min_max_decider == 6:
  140. mixed_class = class_mixer(AreaSubsetter2D, CalculatorFixedMin, max_class)
  141. return mixed_class(frame_mask=frame_mask, SO_MV_scalemin=flags["SO_MV_scalemin"], **max_kwargs)
  142. else:
  143. raise NotImplementedError