|
6 | 6 | import mmif
|
7 | 7 | from mmif import Annotation, Document, Mmif
|
8 | 8 | from mmif.utils.timeunit_helper import convert
|
9 |
| -from mmif.vocabulary import DocumentTypes |
| 9 | +from mmif.vocabulary import DocumentTypes, AnnotationTypes |
10 | 10 |
|
11 | 11 | for cv_dep in ('cv2', 'ffmpeg', 'PIL'):
|
12 | 12 | try:
|
@@ -127,6 +127,42 @@ def extract_mid_frame(mmif: Mmif, time_frame: Annotation, as_PIL: bool = False):
|
127 | 127 | return extract_frames_as_images(vd, [get_mid_framenum(mmif, time_frame)], as_PIL=as_PIL)[0]
|
128 | 128 |
|
129 | 129 |
|
| 130 | +def get_representative_framenum(mmif: Mmif, time_frame: Annotation): |
| 131 | + """ |
| 132 | + Calculates the representative frame number from an annotation. |
| 133 | +
|
| 134 | + :param mmif: :py:class:`~mmif.serialize.mmif.Mmif` instance |
| 135 | + :param time_frame: :py:class:`~mmif.serialize.annotation.Annotation` instance that holds a time interval annotation containing a `representatives` property (``"@type": ".../TimeFrame/..."``) |
| 136 | + :return: representative frame number as an integer |
| 137 | + """ |
| 138 | + if 'representatives' not in time_frame.properties: |
| 139 | + raise ValueError(f'The time frame {time_frame.id} does not have a representative.') |
| 140 | + timeunit = time_frame.get_property('timeUnit') |
| 141 | + video_document = mmif[time_frame.get_property('document')] |
| 142 | + fps = get_framerate(video_document) |
| 143 | + representatives = time_frame.get_property('representatives') |
| 144 | + top_representative_id = representatives[0] |
| 145 | + try: |
| 146 | + representative_timepoint_anno = mmif[time_frame._parent_view_id+time_frame.id_delimiter+top_representative_id] |
| 147 | + except KeyError: |
| 148 | + raise ValueError(f'Representative timepoint {top_representative_id} not found in any view.') |
| 149 | + return convert(representative_timepoint_anno.get_property('timePoint'), timeunit, 'frame', fps) |
| 150 | + |
| 151 | + |
| 152 | +def extract_representative_frame(mmif: Mmif, time_frame: Annotation, as_PIL: bool = False): |
| 153 | + """ |
| 154 | + Extracts the representative frame of an annotation as a numpy ndarray or PIL Image. |
| 155 | +
|
| 156 | + :param mmif: :py:class:`~mmif.serialize.mmif.Mmif` instance |
| 157 | + :param time_frame: :py:class:`~mmif.serialize.annotation.Annotation` instance that holds a time interval annotation (``"@type": ".../TimeFrame/..."``) |
| 158 | + :param as_PIL: return :py:class:`~PIL.Image.Image` instead of :py:class:`~numpy.ndarray` |
| 159 | + :return: frame as a :py:class:`numpy.ndarray` or :py:class:`PIL.Image.Image` |
| 160 | + """ |
| 161 | + video_document = mmif[time_frame.get_property('document')] |
| 162 | + rep_frame_num = get_representative_framenum(mmif, time_frame) |
| 163 | + return extract_frames_as_images(video_document, [rep_frame_num], as_PIL=as_PIL)[0] |
| 164 | + |
| 165 | + |
130 | 166 | def sample_frames(start_frame: int, end_frame: int, sample_rate: float = 1) -> List[int]:
|
131 | 167 | """
|
132 | 168 | Helper function to sample frames from a time interval.
|
|
0 commit comments