In [1]:
%pylab inline
In [2]:
from pyannote.core import Annotation
Annotation
instances are used to describe sets of annotated temporal fragments.
For instance, one can use an Annotation
to store the result of speaker identification approach applied on an episode of The Big Bang Theory TV series.
In [3]:
annotation = Annotation(
uri='TheBigBangTheory.Season01.Episode01',
modality='speaker'
)
For instance, to represent a dialogue between Penny and Leonard, we could do the following:
In [4]:
from pyannote.core import Segment
annotation[Segment(3, 5)] = 'Penny'
annotation[Segment(5.5, 7)] = 'Leonard'
annotation[Segment(8, 10)] = 'Penny'
annotation
Out[4]:
Now, suppose (super-annoying) Sheldon speaks over Penny's second speech turn.
In [5]:
annotation[Segment(8, 10)] = 'Sheldon'
annotation
Out[5]:
Damn, Sheldon! That's not what we wanted! We did not want to replace Penny by Sheldon. Instead, we wanted to show that both characters are speaking at the very same time.
To achieve this, we need to create a new track for the same segment.
In [6]:
segment = Segment(8, 10)
annotation[segment, annotation.new_track(segment)] = 'Penny'
annotation
Out[6]:
That's much better! A track cannot be identified by a segment alone: it is uniquely identified by a 2-tuple (segment, track_identifier).
In fact, the new_track method is simply an helper function to help you generate new track identifiers for a given segment. And the previous lines are in fact shortcuts for the following:
In [7]:
annotation = Annotation(
uri='TheBigBangTheory.Season01.Episode01',
modality='speaker'
)
annotation[Segment(3, 5), '_'] = 'Penny'
annotation[Segment(5.5, 7), '_',] = 'Leonard'
annotation[Segment(8, 10), '_'] = 'Penny'
annotation[Segment(8, 10), 'anything'] = 'Sheldon'
annotation
Out[7]:
_
is the default track identifier (in case you are sure that each segment has only one associated track). Generally, you should avoid using the shortcut annotation[segment]
and always add a track identifier of your choosing.
In [8]:
for segment in annotation.itersegments():
print segment
In [9]:
for segment, track in annotation.itertracks():
print segment, track
In [10]:
for segment, track, label in annotation.itertracks(label=True):
print segment, track, label
One can use the get_timeline method to obtain a timeline made of all segments (not tracks!) in the annotation
In [11]:
annotation.get_timeline()
Out[11]:
Get all tracks for a given segment
In [12]:
annotation.get_tracks(Segment(8, 10))
Out[12]:
Check whether a given track exists
In [13]:
annotation.has_track(Segment(8, 10), '---')
Out[13]:
One can re-initialize tracks as incrementing integer using retrack method. This also makes sure that no two tracks have the same identifier.
In [14]:
for segment, track in annotation.retrack().itertracks():
print segment, track
Get (sorted) list of unique labels
In [15]:
annotation.labels()
Out[15]:
List of labels for a given segment. Read the help message for more options.
In [16]:
annotation.get_labels(Segment(8, 10))
Out[16]:
One may want to be more precise on the identiy of each speaker and replace character names by actor names. We can use translate to do just that:
In [17]:
mapping = {'Penny': 'Kaley Cuoco', 'Sheldon': 'Jim Parsons', 'Leonard': 'Johnny Galecki'}
annotation.translate(mapping)
Out[17]:
In [18]:
# this also works
annotation % mapping
Out[18]:
The crop method works the same way it does for timeline instances.
In [19]:
annotation
Out[19]:
In [20]:
segment = Segment(6, 9)
segment
Out[20]:
In [21]:
annotation.crop(segment)
Out[21]:
The subset method allows to extract annotations based on their labels.
In [22]:
male_characters = set(['Sheldon', 'Leonard'])
annotation.subset(male_characters)
Out[22]:
In [23]:
# all but male characters
annotation.subset(male_characters, invert=True)
Out[23]:
In [24]:
# timeline made of Penny's segments
annotation.label_timeline('Penny')
Out[24]:
In [25]:
# total Penny's speech duration
print 'Penny spoke during %f seconds' % annotation.label_duration('Penny')
In [26]:
# label chart based on their duration
annotation.chart()
Out[26]:
In [27]:
# who is the biggest speaker?
annotation.argmax()
Out[27]:
co_iter works the same way as for timeline except it iterates over overlapping (segment, track) tuples.
You can always try the following...
Who knows? It might give you the information you are looking for!
In [28]:
help(Annotation)