areas.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. from scipy.io.idl import readsav
  2. from .io import read_tif_2Dor3D
  3. from scipy.ndimage.morphology import binary_erosion
  4. import numpy as np
  5. def get_area(flags):
  6. """
  7. Get the area mask for the flags given
  8. Raises
  9. :param flags: FlagsManager object
  10. :return:
  11. """
  12. mask_path = flags.get_existing_area_filepath()
  13. if mask_path is None:
  14. raise FileNotFoundError("Could not find area file")
  15. frame_mask = read_area_file(str(mask_path))
  16. return frame_mask
  17. def frame_mask2perim(frame_mask):
  18. eroded_mask = binary_erosion(frame_mask)
  19. return frame_mask & (~eroded_mask)
  20. def read_area_file(fle):
  21. if fle.endswith(".Area"):
  22. return AreaMaskIO.read_mask_from_file(fle)
  23. elif fle.endswith(".area.tif"):
  24. return TIFMaskIO.read_mask_from_file(fle)
  25. else:
  26. raise NotImplementedError
  27. class BaseMaskIO(object):
  28. def __init__(self):
  29. super().__init__()
  30. @classmethod
  31. def read_mask_from_file(cls, file):
  32. pass
  33. @classmethod
  34. def write_mask_to_file(cls, frame_data, file):
  35. pass
  36. class AreaMaskIO(BaseMaskIO):
  37. def __init__(self):
  38. super().__init__()
  39. @classmethod
  40. def read_mask_from_file(cls, file):
  41. """
  42. Read and returns a boolean mask for VIEW from `file`
  43. :param str file: path to an AREA file
  44. :return: boolean 2D mask
  45. :rtype: numpy.ndarray
  46. """
  47. mask_uint8_XY_y_flipped = cls.read_footprint(file)
  48. mask_XY_y_flipped = mask_uint8_XY_y_flipped > 0
  49. return mask_XY_y_flipped
  50. @classmethod
  51. def read_footprint(cls, file):
  52. """
  53. Reads the AREA file in `file` and returns a 2D ndarray of type uint8
  54. :param str file: path to an AREA file
  55. :return: uint8 2D array
  56. :rtype: numpy.ndarray
  57. """
  58. mask_uint8_YX = readsav(file).maskframe
  59. mask_uint8_XY = mask_uint8_YX.swapaxes(0, 1)
  60. mask_uint8_XY_y_flipped = np.flip(mask_uint8_XY, axis=1)
  61. return mask_uint8_XY_y_flipped
  62. @classmethod
  63. def write_mask_to_file(cls, frame_data, file):
  64. raise NotImplementedError
  65. class TIFMaskIO(BaseMaskIO):
  66. def __init__(self):
  67. super().__init__()
  68. @classmethod
  69. def read_mask_from_file(cls, file):
  70. frame_mask_float, _ = read_tif_2Dor3D(file)
  71. frame_mask = (frame_mask_float > 0).any(axis=2)
  72. return frame_mask
  73. @classmethod
  74. def write_mask_to_file(cls, frame_data, file):
  75. raise NotImplementedError
  76. def get_area_for_p1(frame_size, flags):
  77. try:
  78. area = get_area(flags)
  79. except FileNotFoundError as fnfe:
  80. area = np.ones(frame_size, dtype=bool)
  81. return area
  82. def get_area_for_bleach_correction(area_mask, LE_BleachCutBorder, LE_BleachExcludeArea):
  83. if LE_BleachExcludeArea:
  84. mask_frame = area_mask
  85. else:
  86. frame_size = area_mask.shape
  87. mask_frame = np.zeros(frame_size, dtype=bool)
  88. x_to_cut = round(frame_size[0] * LE_BleachCutBorder / 100)
  89. y_to_cut = round(frame_size[1] * LE_BleachCutBorder / 100)
  90. mask_frame[x_to_cut: frame_size[0] - x_to_cut, y_to_cut: frame_size[1] - y_to_cut] = True
  91. return mask_frame