FailSafeVideo.py 2.41 KB
Newer Older
1
2
3
from . import Base
import bob.bio.face
import collections
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
4
import logging
5
import six
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
6
7
8
9
10
11
12
13
14
15
16

logger = logging.getLogger(__name__)


class FailSafeVideo(Base):
  """A fail-safe video annotator.
  It tries several annotators in order and tries the next one if the previous
  one fails. However, the difference between this annotator and
  :any:`bob.bio.base.annotator.FailSafe` is that this one tries to use
  annotations from older frames (if valid) before trying the next annotator.

17
18
19
20
21
22
  .. warning::

      You must be careful in using this annotator since different annotators
      could have different results. For example the bounding box of one
      annotator be totally different from another annotator.

23
  Parameters
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
24
  ----------
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
25
  annotators : :any:`list`
26
      A list of annotators to try.
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
27
28
29
30
  max_age : int
      The maximum number of frames that an annotation is valid for next frames.
      This value should be positive. If you want to set max_age to infinite,
      then you can use the :any:`bob.bio.video.annotator.Wrapper` instead.
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
31
  validator : ``callable``
32
      A function that takes the annotations of a frame and validates it.
33
34
35


  Please see :any:`Base` for more accepted parameters.
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
36
37
  """

38
39
40
  def __init__(self, annotators, max_age=15,
               validator=bob.bio.face.annotator.min_face_size_validator,
               **kwargs):
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
41
42
    super(FailSafeVideo, self).__init__(**kwargs)
    assert max_age > 0, "max_age: `{}' cannot be less than 1".format(max_age)
43
44
45
46
47
    self.annotators = []
    for annotator in annotators:
      if isinstance(annotator, six.string_types):
        annotator = bob.bio.base.load_resource(annotator, 'annotator')
      self.annotators.append(annotator)
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
48
49
50
51
    self.max_age = max_age
    self.validator = validator

  def annotate(self, frames, **kwargs):
52
53
54
    """See :any:`Base.annotate`
    """
    annotations = collections.OrderedDict()
55
    current = None
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
56
    age = 0
57
    for i, frame in self.frame_ids_and_frames(frames):
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
58
59
60
61
62
63
64
65
66
67
      for annotator in self.annotators:
        annot = annotator.annotate(frame, **kwargs)
        if annot and self.validator(annot):
          current = annot
          age = 0
          break
        elif age < self.max_age:
          age += 1
          break
        else:  # no detections and age is larger than maximum allowed
68
          current = None
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
69
70
71
72

        if current is not annot:
          logger.debug("Annotator `%s' failed.", annotator)

73
      annotations[i] = current
Amir MOHAMMADI's avatar
Amir MOHAMMADI committed
74
    return annotations