Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
bob
bob.bio.video
Commits
7be992a7
Commit
7be992a7
authored
Feb 09, 2018
by
Amir MOHAMMADI
Browse files
Add a failsafevideo wrapper
parent
2d2ebde7
Changes
3
Hide whitespace changes
Inline
Side-by-side
bob/bio/video/annotator/FailSafeVideo.py
0 → 100644
View file @
7be992a7
from
collections
import
OrderedDict
from
bob.bio.face.annotator
import
Base
,
min_face_size_validator
from
..
import
utils
import
logging
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.
Attributes
----------
annotators : list
A list of annotators to try
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.
required_keys : list
A list of keys that should be available in annotations to stop trying
different annotators.
validator : callable
A function that takes the annotations and validates it.
"""
def
__init__
(
self
,
annotators
,
required_keys
,
max_age
=
20
,
validator
=
min_face_size_validator
,
**
kwargs
):
super
(
FailSafeVideo
,
self
).
__init__
(
**
kwargs
)
assert
max_age
>
0
,
"max_age: `{}' cannot be less than 1"
.
format
(
max_age
)
self
.
annotators
=
list
(
annotators
)
self
.
required_keys
=
list
(
required_keys
)
self
.
max_age
=
max_age
self
.
validator
=
validator
def
annotate
(
self
,
frames
,
**
kwargs
):
if
isinstance
(
frames
,
utils
.
FrameContainer
):
frames
=
frames
.
as_array
()
annotations
=
OrderedDict
()
current
=
{}
age
=
0
for
i
,
frame
in
enumerate
(
frames
):
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
current
=
{}
if
current
is
not
annot
:
logger
.
debug
(
"Annotator `%s' failed."
,
annotator
)
annotations
[
str
(
i
)]
=
current
return
annotations
bob/bio/video/annotator/Wrapper.py
View file @
7be992a7
...
...
@@ -2,72 +2,11 @@ from collections import OrderedDict
from
bob.bio.face.annotator
import
Base
from
bob.ip.facedetect
import
bounding_box_from_annotation
from
bob.bio.base
import
load_resource
from
bob.bio.face.annotator
import
min_face_size_validator
from
..
import
utils
def
normalize_annotations
(
annotations
,
validator
,
max_age
=-
1
):
"""Normalizes the annotations of one video sequence. It fills the
annotations for frames from previous ones if the annotation for the current
frame is not valid.
Parameters
----------
annotations : dict
A dict of dict where the keys to the first dict are frame indices as
strings (starting from 0). The inside dicts contain annotations for
that frame.
validator : callable
Takes a dict (annotations) and returns True if the annotations are
valid. This can be check based on minimal face size for example.
max_age : :obj:`int`, optional
An integer indicating for a how many frames a detected face is valid if
no detection occurs after such frame. A value of -1 == forever
Yields
------
str
The index of frame.
dict
The corrected annotations of the frame.
"""
# the annotations for the current frame
current
=
{}
age
=
0
for
k
,
annot
in
annotations
.
items
():
if
annot
and
validator
(
annot
):
current
=
annot
age
=
0
elif
max_age
<
0
or
age
<
max_age
:
age
+=
1
else
:
# no detections and age is larger than maximum allowed
current
=
{}
yield
k
,
current
def
min_face_size_validator
(
annotations
,
min_face_size
=
32
):
"""Validates annotations based on face's minimal size.
Parameters
----------
annotations : dict
The annotations in dictionary format.
min_face_size : int, optional
The minimal size of a face.
Returns
-------
bool
True, if the face is large enough.
"""
bbx
=
bounding_box_from_annotation
(
source
=
'direct'
,
**
annotations
)
if
bbx
.
size
<
32
:
return
False
return
True
class
Wrapper
(
Base
):
"""Annotates video files.
This annotator does not support annotating only select frames of a video.
...
...
@@ -98,7 +37,7 @@ class Wrapper(Base):
self
.
max_age
=
max_age
# load annotator configuration
if
isinstance
(
annotator
,
basestring
):
if
isinstance
(
annotator
,
str
):
self
.
annotator
=
load_resource
(
annotator
,
"annotator"
)
def
annotate
(
self
,
frames
,
**
kwargs
):
...
...
bob/bio/video/annotator/__init__.py
View file @
7be992a7
from
.Wrapper
import
Wrapper
,
normalize_annotations
,
min_face_size_validator
from
.Wrapper
import
Wrapper
from
.FailSafeVideo
import
FailSafeVideo
def
normalize_annotations
(
annotations
,
validator
,
max_age
=-
1
):
"""Normalizes the annotations of one video sequence. It fills the
annotations for frames from previous ones if the annotation for the current
frame is not valid.
Parameters
----------
annotations : dict
A dict of dict where the keys to the first dict are frame indices as
strings (starting from 0). The inside dicts contain annotations for
that frame.
validator : callable
Takes a dict (annotations) and returns True if the annotations are
valid. This can be check based on minimal face size for example.
max_age : :obj:`int`, optional
An integer indicating for a how many frames a detected face is valid if
no detection occurs after such frame. A value of -1 == forever
Yields
------
str
The index of frame.
dict
The corrected annotations of the frame.
"""
# the annotations for the current frame
current
=
{}
age
=
0
for
k
,
annot
in
annotations
.
items
():
if
annot
and
validator
(
annot
):
current
=
annot
age
=
0
elif
max_age
<
0
or
age
<
max_age
:
age
+=
1
else
:
# no detections and age is larger than maximum allowed
current
=
{}
yield
k
,
current
# gets sphinx autodoc done right - don't remove it
def
__appropriate__
(
*
args
):
"""Says object was actually declared here, and not in the import module.
Fixing sphinx warnings of not being able to find classes, when path is
shortened.
Parameters
----------
*args
An iterable of objects to modify
Resolves `Sphinx referencing issues
<https://github.com/sphinx-doc/sphinx/issues/3048>`
"""
for
obj
in
args
:
obj
.
__module__
=
__name__
__appropriate__
(
Wrapper
,
FailSafeVideo
,
)
__all__
=
[
_
for
_
in
dir
()
if
not
_
.
startswith
(
'_'
)]
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment