MediaFile.py 4.3 KB

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