Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
bob.pad.face
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
bob
bob.pad.face
Commits
7c72e080
Commit
7c72e080
authored
5 years ago
by
Amir MOHAMMADI
Browse files
Options
Downloads
Patches
Plain Diff
[replaymobile][replay][msu_mfsd] improve interfaces to make files independent
parent
006b0c9e
Branches
Branches containing commit
Tags
Tags containing commit
1 merge request
!104
Improve high level database interfaces
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
bob/pad/face/database/msu_mfsd.py
+49
-44
49 additions, 44 deletions
bob/pad/face/database/msu_mfsd.py
bob/pad/face/database/replay.py
+103
-58
103 additions, 58 deletions
bob/pad/face/database/replay.py
bob/pad/face/database/replay_mobile.py
+3
-36
3 additions, 36 deletions
bob/pad/face/database/replay_mobile.py
with
155 additions
and
138 deletions
bob/pad/face/database/msu_mfsd.py
+
49
−
44
View file @
7c72e080
#!/usr/bin/env python2
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#==============================================================================
# Used in ReplayMobilePadFile class
from
bob.bio.video
import
FrameSelector
,
FrameContainer
from
bob.bio.video
import
FrameSelector
,
FrameContainer
from
bob.pad.face.database
import
VideoPadFile
# Used in MsuMfsdPadFile class
from
bob.pad.face.database
import
VideoPadFile
# Used in MsuMfsdPadFile class
from
bob.pad.base.database
import
PadDatabase
from
bob.pad.base.database
import
PadDatabase
from
bob.extension
import
rc
import
os
import
os
import
numpy
as
np
import
numpy
as
np
#==============================================================================
class
MsuMfsdPadFile
(
VideoPadFile
):
class
MsuMfsdPadFile
(
VideoPadFile
):
"""
"""
A high level implementation of the File class for the MSU MFSD database.
A high level implementation of the File class for the MSU MFSD database.
...
@@ -40,18 +34,20 @@ class MsuMfsdPadFile(VideoPadFile):
...
@@ -40,18 +34,20 @@ class MsuMfsdPadFile(VideoPadFile):
if
f
.
is_real
():
if
f
.
is_real
():
attack_type
=
None
attack_type
=
None
else
:
else
:
attack_type
=
'
attack
'
attack_type
=
"
attack
"
# attack_type is a string and I decided to make it like this for this
# attack_type is a string and I decided to make it like this for this
# particular database. You can do whatever you want for your own database.
# particular database. You can do whatever you want for your own database.
super
(
MsuMfsdPadFile
,
self
).
__init__
(
super
(
MsuMfsdPadFile
,
self
).
__init__
(
client_id
=
f
.
client_id
,
client_id
=
f
.
client_id
,
path
=
f
.
path
,
attack_type
=
attack_type
,
file_id
=
f
.
id
path
=
f
.
path
,
)
attack_type
=
attack_type
,
file_id
=
f
.
id
)
def
load
(
self
,
#==========================================================================
directory
=
None
,
def
load
(
self
,
directory
=
None
,
extension
=
None
,
frame_selector
=
FrameSelector
(
selection_style
=
'
all
'
)):
extension
=
None
,
frame_selector
=
FrameSelector
(
selection_style
=
"
all
"
),
):
"""
"""
Overridden version of the load method defined in the ``VideoPadFile``.
Overridden version of the load method defined in the ``VideoPadFile``.
...
@@ -76,26 +72,27 @@ class MsuMfsdPadFile(VideoPadFile):
...
@@ -76,26 +72,27 @@ class MsuMfsdPadFile(VideoPadFile):
for further details.
for further details.
"""
"""
_
,
extension
=
os
.
path
.
splitext
(
_
,
extension
=
os
.
path
.
splitext
(
self
.
f
.
videofile
())
# get file extension
self
.
f
.
videofile
())
# get file extension
video_data_array
=
self
.
f
.
load
(
video_data_array
=
self
.
f
.
load
(
directory
=
directory
,
extension
=
extension
)
directory
=
directory
,
extension
=
extension
)
return
frame_selector
(
video_data_array
)
return
frame_selector
(
video_data_array
)
#==============================================================================
class
MsuMfsdPadDatabase
(
PadDatabase
):
class
MsuMfsdPadDatabase
(
PadDatabase
):
"""
"""
A high level implementation of the Database class for the MSU MFSD database.
A high level implementation of the Database class for the MSU MFSD database.
"""
"""
def
__init__
(
def
__init__
(
self
,
self
,
protocol
=
'
grandtest
'
,
# grandtest is the default protocol for this database
protocol
=
"
grandtest
"
,
# grandtest is the default protocol for this database
original_directory
=
None
,
original_directory
=
None
,
original_extension
=
None
,
original_extension
=
None
,
**
kwargs
):
annotation_directory
=
None
,
annotation_extension
=
'
.json
'
,
annotation_type
=
'
json
'
,
**
kwargs
):
"""
"""
**Parameters:**
**Parameters:**
...
@@ -119,19 +116,24 @@ class MsuMfsdPadDatabase(PadDatabase):
...
@@ -119,19 +116,24 @@ class MsuMfsdPadDatabase(PadDatabase):
# Since the high level API expects different group names than what the low
# Since the high level API expects different group names than what the low
# level API offers, you need to convert them when necessary
# level API offers, you need to convert them when necessary
self
.
low_level_group_names
=
(
self
.
low_level_group_names
=
(
'
train
'
,
'
devel
'
,
"
train
"
,
'
test
'
)
# group names in the low-level database interface
"
devel
"
,
"
test
"
,
)
# group names in the low-level database interface
self
.
high_level_group_names
=
(
self
.
high_level_group_names
=
(
'
train
'
,
'
dev
'
,
"
train
"
,
'
eval
'
)
# names are expected to be like that in objects() function
"
dev
"
,
"
eval
"
,
)
# names are expected to be like that in objects() function
# Always use super to call parent class methods.
# Always use super to call parent class methods.
super
(
MsuMfsdPadDatabase
,
self
).
__init__
(
super
(
MsuMfsdPadDatabase
,
self
).
__init__
(
name
=
'
msu-mfsd
'
,
name
=
"
msu-mfsd
"
,
protocol
=
protocol
,
protocol
=
protocol
,
original_directory
=
original_directory
,
original_directory
=
original_directory
,
original_extension
=
original_extension
,
original_extension
=
original_extension
,
**
kwargs
)
**
kwargs
)
@property
@property
def
original_directory
(
self
):
def
original_directory
(
self
):
...
@@ -141,13 +143,9 @@ class MsuMfsdPadDatabase(PadDatabase):
...
@@ -141,13 +143,9 @@ class MsuMfsdPadDatabase(PadDatabase):
def
original_directory
(
self
,
value
):
def
original_directory
(
self
,
value
):
self
.
db
.
original_directory
=
value
self
.
db
.
original_directory
=
value
#==========================================================================
def
objects
(
def
objects
(
self
,
self
,
groups
=
None
,
protocol
=
None
,
purposes
=
None
,
model_ids
=
None
,
**
kwargs
groups
=
None
,
):
protocol
=
None
,
purposes
=
None
,
model_ids
=
None
,
**
kwargs
):
"""
"""
This function returns lists of MsuMfsdPadFile objects, which fulfill the given restrictions.
This function returns lists of MsuMfsdPadFile objects, which fulfill the given restrictions.
...
@@ -179,16 +177,21 @@ class MsuMfsdPadDatabase(PadDatabase):
...
@@ -179,16 +177,21 @@ class MsuMfsdPadDatabase(PadDatabase):
# Convert group names to low-level group names here.
# Convert group names to low-level group names here.
groups
=
self
.
convert_names_to_lowlevel
(
groups
=
self
.
convert_names_to_lowlevel
(
groups
,
self
.
low_level_group_names
,
self
.
high_level_group_names
)
groups
,
self
.
low_level_group_names
,
self
.
high_level_group_names
)
# Since this database was designed for PAD experiments, nothing special
# Since this database was designed for PAD experiments, nothing special
# needs to be done here.
# needs to be done here.
files
=
self
.
db
.
objects
(
group
=
groups
,
cls
=
purposes
,
**
kwargs
)
files
=
self
.
db
.
objects
(
group
=
groups
,
cls
=
purposes
,
**
kwargs
)
files
=
[
MsuMfsdPadFile
(
f
)
for
f
in
files
]
files
=
[
MsuMfsdPadFile
(
f
)
for
f
in
files
]
for
f
in
files
:
f
.
original_directory
=
self
.
original_directory
f
.
annotation_directory
=
self
.
annotation_directory
f
.
annotation_extension
=
self
.
annotation_extension
f
.
annotation_type
=
self
.
annotation_type
return
files
return
files
#==========================================================================
def
annotations
(
self
,
f
):
def
annotations
(
self
,
f
):
"""
"""
Return annotations for a given file object ``f``, which is an instance
Return annotations for a given file object ``f``, which is an instance
...
@@ -220,12 +223,14 @@ class MsuMfsdPadDatabase(PadDatabase):
...
@@ -220,12 +223,14 @@ class MsuMfsdPadDatabase(PadDatabase):
for
frame_annots
in
annots
:
for
frame_annots
in
annots
:
topleft
=
(
np
.
int
(
frame_annots
[
2
]),
np
.
int
(
frame_annots
[
1
]))
topleft
=
(
np
.
int
(
frame_annots
[
2
]),
np
.
int
(
frame_annots
[
1
]))
bottomright
=
(
np
.
int
(
frame_annots
[
2
]
+
frame_annots
[
4
]),
bottomright
=
(
np
.
int
(
frame_annots
[
1
]
+
frame_annots
[
3
]))
np
.
int
(
frame_annots
[
2
]
+
frame_annots
[
4
]),
np
.
int
(
frame_annots
[
1
]
+
frame_annots
[
3
]),
)
annotations
[
str
(
np
.
int
(
frame_annots
[
0
]))]
=
{
annotations
[
str
(
np
.
int
(
frame_annots
[
0
]))]
=
{
'
topleft
'
:
topleft
,
"
topleft
"
:
topleft
,
'
bottomright
'
:
bottomright
"
bottomright
"
:
bottomright
,
}
}
return
annotations
return
annotations
This diff is collapsed.
Click to expand it.
bob/pad/face/database/replay.py
+
103
−
58
View file @
7c72e080
#!/usr/bin/env python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
# Used in ReplayMobilePadFile class
from
bob.pad.base.database
import
PadDatabase
# Used in ReplayMobilePadFile class
from
bob.pad.base.database
import
PadDatabase
from
bob.pad.face.database
import
VideoPadFile
# Used in ReplayPadFile class
from
bob.pad.face.database
import
VideoPadFile
# Used in ReplayPadFile class
from
bob.pad.face.utils
import
frames
,
number_of_frames
from
bob.extension
import
rc
from
bob.extension
import
rc
from
bob.ip.facedetect
import
expected_eye_positions
,
BoundingBox
from
bob.db.base.annotations
import
read_annotation_file
REPLAY_ATTACK_FRAME_SHAPE
=
(
3
,
240
,
320
)
class
ReplayPadFile
(
VideoPadFile
):
class
ReplayPadFile
(
VideoPadFile
):
...
@@ -35,16 +37,73 @@ class ReplayPadFile(VideoPadFile):
...
@@ -35,16 +37,73 @@ class ReplayPadFile(VideoPadFile):
if
f
.
is_real
():
if
f
.
is_real
():
attack_type
=
None
attack_type
=
None
else
:
else
:
attack_type
=
'
attack
'
attack_type
=
"
attack
"
# attack_type is a string and I decided to make it like this for this
# attack_type is a string and I decided to make it like this for this
# particular database. You can do whatever you want for your own
# particular database. You can do whatever you want for your own
# database.
# database.
super
(
ReplayPadFile
,
self
).
__init__
(
super
(
ReplayPadFile
,
self
).
__init__
(
client_id
=
f
.
client_id
,
client_id
=
f
.
client_id
,
path
=
f
.
path
,
attack_type
=
attack_type
,
file_id
=
f
.
id
path
=
f
.
path
,
)
attack_type
=
attack_type
,
file_id
=
f
.
id
)
@property
def
frame_shape
(
self
):
"""
Returns the size of each frame in this database.
Returns
-------
(int, int, int)
The (#Channels, Height, Width) which is (3, 240, 320).
"""
return
REPLAY_ATTACK_FRAME_SHAPE
@property
def
annotations
(
self
):
"""
Return annotations as a dictionary of dictionaries.
If the file object has an attribute of annotation_directory, it will read
annotations from there instead of loading annotations that are shipped with the
database.
Returns
-------
annotations : :py:class:`dict`
A dictionary containing the annotations for each frame in the
video. Dictionary structure:
``annotations = {
'
1
'
: frame1_dict,
'
2
'
: frame1_dict, ...}``.Where
``frameN_dict = {
'
topleft
'
: (row, col),
'
bottomright
'
: (row, col)}``
is the dictionary defining the coordinates of the face bounding box
in frame N.
"""
if
(
hasattr
(
self
,
"
annotation_directory
"
)
and
self
.
annotation_directory
is
not
None
):
path
=
self
.
make_path
(
self
.
annotation_directory
,
extension
=
"
.json
"
)
return
read_annotation_file
(
path
,
annotation_type
=
"
json
"
)
# numpy array containing the face bounding box data for each video
# frame, returned data format described in the f.bbx() method of the
# low level interface
annots
=
self
.
f
.
bbx
(
directory
=
self
.
original_directory
)
annotations
=
{}
# dictionary to return
for
fn
,
frame_annots
in
enumerate
(
annots
):
topleft
=
(
frame_annots
[
2
],
frame_annots
[
1
])
bottomright
=
(
frame_annots
[
2
]
+
frame_annots
[
4
],
frame_annots
[
1
]
+
frame_annots
[
3
],
)
annotations
[
str
(
fn
)]
=
{
"
topleft
"
:
topleft
,
"
bottomright
"
:
bottomright
}
size
=
(
bottomright
[
0
]
-
topleft
[
0
],
bottomright
[
1
]
-
topleft
[
1
])
bounding_box
=
BoundingBox
(
topleft
,
size
)
annotations
[
str
(
fn
)].
update
(
expected_eye_positions
(
bounding_box
))
return
annotations
class
ReplayPadDatabase
(
PadDatabase
):
class
ReplayPadDatabase
(
PadDatabase
):
...
@@ -54,12 +113,14 @@ class ReplayPadDatabase(PadDatabase):
...
@@ -54,12 +113,14 @@ class ReplayPadDatabase(PadDatabase):
"""
"""
def
__init__
(
def
__init__
(
self
,
self
,
# grandtest is the default protocol for this database
# grandtest is the default protocol for this database
protocol
=
'
grandtest
'
,
protocol
=
"
grandtest
"
,
original_directory
=
rc
[
'
bob.db.replay.directory
'
],
original_directory
=
rc
[
"
bob.db.replay.directory
"
],
original_extension
=
'
.mov
'
,
original_extension
=
"
.mov
"
,
**
kwargs
):
annotation_directory
=
None
,
**
kwargs
):
"""
"""
Parameters
Parameters
----------
----------
...
@@ -86,19 +147,25 @@ class ReplayPadDatabase(PadDatabase):
...
@@ -86,19 +147,25 @@ class ReplayPadDatabase(PadDatabase):
# Since the high level API expects different group names than what the
# Since the high level API expects different group names than what the
# low level API offers, you need to convert them when necessary
# low level API offers, you need to convert them when necessary
self
.
low_level_group_names
=
(
self
.
low_level_group_names
=
(
'
train
'
,
'
devel
'
,
"
train
"
,
'
test
'
)
# group names in the low-level database interface
"
devel
"
,
"
test
"
,
)
# group names in the low-level database interface
self
.
high_level_group_names
=
(
self
.
high_level_group_names
=
(
'
train
'
,
'
dev
'
,
"
train
"
,
'
eval
'
)
# names are expected to be like that in objects() function
"
dev
"
,
"
eval
"
,
)
# names are expected to be like that in objects() function
# Always use super to call parent class methods.
# Always use super to call parent class methods.
super
(
ReplayPadDatabase
,
self
).
__init__
(
super
(
ReplayPadDatabase
,
self
).
__init__
(
name
=
'
replay
'
,
name
=
"
replay
"
,
protocol
=
protocol
,
protocol
=
protocol
,
original_directory
=
original_directory
,
original_directory
=
original_directory
,
original_extension
=
original_extension
,
original_extension
=
original_extension
,
**
kwargs
)
annotation_directory
=
annotation_directory
,
**
kwargs
)
@property
@property
def
original_directory
(
self
):
def
original_directory
(
self
):
...
@@ -108,12 +175,9 @@ class ReplayPadDatabase(PadDatabase):
...
@@ -108,12 +175,9 @@ class ReplayPadDatabase(PadDatabase):
def
original_directory
(
self
,
value
):
def
original_directory
(
self
,
value
):
self
.
db
.
original_directory
=
value
self
.
db
.
original_directory
=
value
def
objects
(
self
,
def
objects
(
groups
=
None
,
self
,
groups
=
None
,
protocol
=
None
,
purposes
=
None
,
model_ids
=
None
,
**
kwargs
protocol
=
None
,
):
purposes
=
None
,
model_ids
=
None
,
**
kwargs
):
"""
"""
This function returns lists of ReplayPadFile objects, which fulfill the
This function returns lists of ReplayPadFile objects, which fulfill the
given restrictions.
given restrictions.
...
@@ -146,12 +210,19 @@ class ReplayPadDatabase(PadDatabase):
...
@@ -146,12 +210,19 @@ class ReplayPadDatabase(PadDatabase):
# Convert group names to low-level group names here.
# Convert group names to low-level group names here.
groups
=
self
.
convert_names_to_lowlevel
(
groups
=
self
.
convert_names_to_lowlevel
(
groups
,
self
.
low_level_group_names
,
self
.
high_level_group_names
)
groups
,
self
.
low_level_group_names
,
self
.
high_level_group_names
)
# Since this database was designed for PAD experiments, nothing special
# Since this database was designed for PAD experiments, nothing special
# needs to be done here.
# needs to be done here.
files
=
self
.
db
.
objects
(
files
=
self
.
db
.
objects
(
protocol
=
protocol
,
groups
=
groups
,
cls
=
purposes
,
**
kwargs
)
protocol
=
protocol
,
groups
=
groups
,
cls
=
purposes
,
**
kwargs
)
files
=
[
ReplayPadFile
(
f
)
for
f
in
files
]
files
=
[
ReplayPadFile
(
f
)
for
f
in
files
]
# set the attributes
for
f
in
files
:
f
.
original_directory
=
self
.
original_directory
f
.
original_extension
=
self
.
original_extension
f
.
annotation_directory
=
self
.
annotation_directory
return
files
return
files
def
annotations
(
self
,
f
):
def
annotations
(
self
,
f
):
...
@@ -178,26 +249,7 @@ class ReplayPadDatabase(PadDatabase):
...
@@ -178,26 +249,7 @@ class ReplayPadDatabase(PadDatabase):
is the dictionary defining the coordinates of the face bounding box
is the dictionary defining the coordinates of the face bounding box
in frame N.
in frame N.
"""
"""
return
f
.
annotations
# numpy array containing the face bounding box data for each video
# frame, returned data format described in the f.bbx() method of the
# low level interface
annots
=
f
.
f
.
bbx
(
directory
=
self
.
original_directory
)
annotations
=
{}
# dictionary to return
for
fn
,
frame_annots
in
enumerate
(
annots
):
topleft
=
(
frame_annots
[
2
],
frame_annots
[
1
])
bottomright
=
(
frame_annots
[
2
]
+
frame_annots
[
4
],
frame_annots
[
1
]
+
frame_annots
[
3
])
annotations
[
str
(
fn
)]
=
{
'
topleft
'
:
topleft
,
'
bottomright
'
:
bottomright
}
return
annotations
def
frames
(
self
,
padfile
):
def
frames
(
self
,
padfile
):
"""
Yields the frames of the padfile one by one.
"""
Yields the frames of the padfile one by one.
...
@@ -212,11 +264,7 @@ class ReplayPadDatabase(PadDatabase):
...
@@ -212,11 +264,7 @@ class ReplayPadDatabase(PadDatabase):
:any:`numpy.array`
:any:`numpy.array`
A frame of the video. The size is (3, 240, 320).
A frame of the video. The size is (3, 240, 320).
"""
"""
vfilename
=
padfile
.
make_path
(
return
padfile
.
frames
directory
=
self
.
original_directory
,
extension
=
self
.
original_extension
)
for
retval
in
frames
(
vfilename
):
yield
retval
def
number_of_frames
(
self
,
padfile
):
def
number_of_frames
(
self
,
padfile
):
"""
Returns the number of frames in a video file.
"""
Returns the number of frames in a video file.
...
@@ -231,10 +279,7 @@ class ReplayPadDatabase(PadDatabase):
...
@@ -231,10 +279,7 @@ class ReplayPadDatabase(PadDatabase):
int
int
The number of frames.
The number of frames.
"""
"""
vfilename
=
padfile
.
make_path
(
return
padfile
.
number_of_frames
directory
=
self
.
original_directory
,
extension
=
self
.
original_extension
)
return
number_of_frames
(
vfilename
)
@property
@property
def
frame_shape
(
self
):
def
frame_shape
(
self
):
...
@@ -245,4 +290,4 @@ class ReplayPadDatabase(PadDatabase):
...
@@ -245,4 +290,4 @@ class ReplayPadDatabase(PadDatabase):
(int, int, int)
(int, int, int)
The (#Channels, Height, Width) which is (3, 240, 320).
The (#Channels, Height, Width) which is (3, 240, 320).
"""
"""
return
(
3
,
240
,
320
)
return
REPLAY_ATTACK_FRAME_SHAPE
This diff is collapsed.
Click to expand it.
bob/pad/face/database/replay_mobile.py
+
3
−
36
View file @
7c72e080
...
@@ -5,48 +5,13 @@
...
@@ -5,48 +5,13 @@
from
bob.bio.video
import
FrameSelector
from
bob.bio.video
import
FrameSelector
from
bob.pad.base.database
import
PadDatabase
from
bob.pad.base.database
import
PadDatabase
from
bob.pad.face.database
import
VideoPadFile
from
bob.pad.face.database
import
VideoPadFile
from
bob.pad.face.utils
import
frames
,
number_of_frames
from
bob.pad.face.utils
import
number_of_frames
from
bob.db.base.annotations
import
read_annotation_file
from
bob.db.base.annotations
import
read_annotation_file
import
numpy
from
bob.extension
import
rc
from
bob.extension
import
rc
REPLAYMOBILE_FRAME_SHAPE
=
(
3
,
1280
,
720
)
REPLAYMOBILE_FRAME_SHAPE
=
(
3
,
1280
,
720
)
def
replaymobile_annotations
(
lowlevelfile
,
original_directory
):
# numpy array containing the face bounding box data for each video
# frame, returned data format described in the f.bbx() method of the
# low level interface
annots
=
lowlevelfile
.
bbx
(
directory
=
original_directory
)
annotations
=
{}
# dictionary to return
for
fn
,
frame_annots
in
enumerate
(
annots
):
topleft
=
(
frame_annots
[
1
],
frame_annots
[
0
])
bottomright
=
(
frame_annots
[
1
]
+
frame_annots
[
3
],
frame_annots
[
0
]
+
frame_annots
[
2
])
annotations
[
str
(
fn
)]
=
{
'
topleft
'
:
topleft
,
'
bottomright
'
:
bottomright
}
return
annotations
def
replaymobile_frames
(
lowlevelfile
,
original_directory
):
vfilename
=
lowlevelfile
.
make_path
(
directory
=
original_directory
,
extension
=
'
.mov
'
)
is_not_tablet
=
not
lowlevelfile
.
is_tablet
()
for
frame
in
frames
(
vfilename
):
frame
=
numpy
.
rollaxis
(
frame
,
2
,
1
)
if
is_not_tablet
:
frame
=
frame
[:,
::
-
1
,
:]
yield
frame
class
ReplayMobilePadFile
(
VideoPadFile
):
class
ReplayMobilePadFile
(
VideoPadFile
):
"""
"""
A high level implementation of the File class for the Replay-Mobile
A high level implementation of the File class for the Replay-Mobile
...
@@ -116,6 +81,7 @@ class ReplayMobilePadFile(VideoPadFile):
...
@@ -116,6 +81,7 @@ class ReplayMobilePadFile(VideoPadFile):
@property
@property
def
annotations
(
self
):
def
annotations
(
self
):
from
bob.db.replaymobile.models
import
replaymobile_annotations
if
self
.
annotation_directory
is
not
None
:
if
self
.
annotation_directory
is
not
None
:
# return the external annotations
# return the external annotations
annotations
=
read_annotation_file
(
annotations
=
read_annotation_file
(
...
@@ -129,6 +95,7 @@ class ReplayMobilePadFile(VideoPadFile):
...
@@ -129,6 +95,7 @@ class ReplayMobilePadFile(VideoPadFile):
@property
@property
def
frames
(
self
):
def
frames
(
self
):
from
bob.db.replaymobile.models
import
replaymobile_frames
return
replaymobile_frames
(
self
.
f
,
self
.
original_directory
)
return
replaymobile_frames
(
self
.
f
,
self
.
original_directory
)
@property
@property
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
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!
Save comment
Cancel
Please
register
or
sign in
to comment