MediaFile.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. from os import path, getcwd
  2. from typing import Optional, List, Union
  3. from pycs.database.File import File
  4. from pycs.database.Result import Result
  5. from pycs.frontend.notifications.NotificationList import NotificationList
  6. from pycs.interfaces.MediaBoundingBox import MediaBoundingBox
  7. from pycs.interfaces.MediaImageLabel import MediaImageLabel
  8. from pycs.interfaces.MediaLabel import MediaLabel
  9. class MediaFile:
  10. """
  11. contains various attributes of a saved media file
  12. """
  13. def __init__(self, file: File, notifications: NotificationList):
  14. self.__file = file
  15. self.__notifications = notifications
  16. self.type = file.type
  17. self.size = file.size
  18. self.frames = file.frames
  19. self.fps = file.fps
  20. if path.isabs(file.path):
  21. self.path = file.path
  22. else:
  23. self.path = path.join(getcwd(), file.path)
  24. def set_collection(self, reference: Optional[str]):
  25. """
  26. set this file's collection
  27. :param reference: use None to remove this file's collection
  28. """
  29. self.__file.set_collection_by_reference(reference)
  30. self.__notifications.add(self.__notifications.notifications.edit_file, self.__file)
  31. def set_image_label(self, label: Union[int, MediaLabel], frame: int = None):
  32. """
  33. create a labeled-image result
  34. :param label: label identifier
  35. :param frame: frame index (only set for videos)
  36. """
  37. if label is not None and isinstance(label, MediaLabel):
  38. label = label.identifier
  39. if frame is not None:
  40. data = {'frame': frame}
  41. else:
  42. data = None
  43. created = self.__file.create_result('pipeline', 'labeled-image', label, data)
  44. self.__notifications.add(self.__notifications.notifications.create_result, created)
  45. def add_bounding_box(self, x: float, y: float, w: float, h: float,
  46. label: Union[int, MediaLabel] = None, frame: int = None):
  47. """
  48. create a bounding-box result
  49. :param x: relative x coordinate [0, 1]
  50. :param y: relative y coordinate [0, 1]
  51. :param w: relative width [0, 1]
  52. :param h: relative height [0, 1]
  53. :param label: label
  54. :param frame: frame index (only set for videos)
  55. """
  56. result = {
  57. 'x': x,
  58. 'y': y,
  59. 'w': w,
  60. 'h': h
  61. }
  62. if frame is not None:
  63. result['frame'] = frame
  64. if label is not None and isinstance(label, MediaLabel):
  65. label = label.identifier
  66. created = self.__file.create_result('pipeline', 'bounding-box', label, result)
  67. self.__notifications.add(self.__notifications.notifications.create_result, created)
  68. def remove_predictions(self):
  69. """
  70. remove and return all predictions added from pipelines
  71. """
  72. removed = self.__file.remove_results(origin='pipeline')
  73. for result in removed:
  74. self.__notifications.add(self.__notifications.notifications.remove_result, result)
  75. def __get_results(self, origin: str) -> List[Union[MediaImageLabel, MediaBoundingBox]]:
  76. def map_r(result: Result) -> Union[MediaImageLabel, MediaBoundingBox]:
  77. if result.type == 'labeled-image':
  78. return MediaImageLabel(result)
  79. return MediaBoundingBox(result)
  80. return list(map(map_r,
  81. filter(lambda r: r.origin == origin,
  82. self.__file.results())))
  83. def results(self) -> List[Union[MediaImageLabel, MediaBoundingBox]]:
  84. """
  85. receive results added by users
  86. :return: list of results
  87. """
  88. return self.__get_results('user')
  89. def predictions(self) -> List[Union[MediaImageLabel, MediaBoundingBox]]:
  90. """
  91. receive results added by pipelines
  92. :return: list of predictions
  93. """
  94. return self.__get_results('pipeline')
  95. def serialize(self) -> dict:
  96. """
  97. serialize all object properties to a dict
  98. :return: dict
  99. """
  100. return {
  101. 'type': self.type,
  102. 'size': self.size,
  103. 'frames': self.frames,
  104. 'fps': self.fps,
  105. 'path': self.path,
  106. 'filename': self.__file.name + self.__file.extension,
  107. 'results': list(map(lambda r: r.serialize(), self.results())),
  108. 'predictions': list(map(lambda r: r.serialize(), self.predictions())),
  109. }