Commit d0e385c5 authored by Amir MOHAMMADI's avatar Amir MOHAMMADI

Add replay mobile interface

parent 0a0d3c2f
...@@ -2,8 +2,11 @@ import six ...@@ -2,8 +2,11 @@ import six
import collections import collections
import import
import import
import logging
from . import Base, normalize_annotations from . import Base, normalize_annotations
logger = logging.getLogger(__name__)
class Wrapper(Base): class Wrapper(Base):
"""Annotates video files using the provided image annotator. """Annotates video files using the provided image annotator.
...@@ -54,6 +57,7 @@ class Wrapper(Base): ...@@ -54,6 +57,7 @@ class Wrapper(Base):
""" """
annotations = collections.OrderedDict() annotations = collections.OrderedDict()
for i, frame in self.frame_ids_and_frames(frames): for i, frame in self.frame_ids_and_frames(frames):
logger.debug("Annotating frame %s", i)
annotations[i] = self.annotator(frame, **kwargs) annotations[i] = self.annotator(frame, **kwargs)
if self.normalize: if self.normalize:
annotations = collections.OrderedDict(normalize_annotations( annotations = collections.OrderedDict(normalize_annotations(
from import ReplayMobileVideoBioDatabase
database = ReplayMobileVideoBioDatabase(protocol='grandtest-licit')
from .database import VideoBioFile from .database import VideoBioFile
from .mobio import MobioBioDatabase from .mobio import MobioBioDatabase
from .youtube import YoutubeBioDatabase from .youtube import YoutubeBioDatabase
from .replaymobile import ReplayMobileVideoBioDatabase
# gets sphinx autodoc done right - don't remove it # gets sphinx autodoc done right - don't remove it
...@@ -15,12 +16,14 @@ def __appropriate__(*args): ...@@ -15,12 +16,14 @@ def __appropriate__(*args):
<>` <>`
""" """
for obj in args: obj.__module__ = __name__ for obj in args:
obj.__module__ = __name__
__appropriate__( __appropriate__(
VideoBioFile, VideoBioFile,
MobioBioDatabase, MobioBioDatabase,
YoutubeBioDatabase, YoutubeBioDatabase,
) ReplayMobileVideoBioDatabase,
__all__ = [_ for _ in dir() if not _.startswith('_')] __all__ = [_ for _ in dir() if not _.startswith('_')]
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
""" The Replay-Mobile Database for face spoofing implementation of interface."""
from .database import VideoBioFile
from import BioDatabase
from bob.extension import rc
from import FrameSelector
class ReplayMobileVideoBioFile(VideoBioFile):
"""VideoBioFile implementation of the Replay Mobile Database"""
def __init__(self, f):
super(ReplayMobileVideoBioFile, self).__init__(client_id=f.client_id, path=f.path,
self._f = f
def load(self, directory=None, extension='.mov',
vid = self._f.load(directory=directory, extension=extension)
return frame_selector(vid)
def annotations(self):
return self._f.annotations
def frames(self):
return self._f.frames
def number_of_frames(self):
return self._f.number_of_frames
def frame_shape(self):
return self._f.frame_shape
class ReplayMobileVideoBioDatabase(BioDatabase):
ReplayMobile database implementation of :py:class:`` interface.
It is an extension of an SQL-based database interface, which directly talks to ReplayMobile database, for
verification experiments (good to use in framework).
def __init__(self,
from bob.db.replaymobile import Database as LowLevelDatabase
self._db = LowLevelDatabase(
# Since the high level API expects different group names than what the
# low level API offers, you need to convert them when necessary
self.low_level_group_names = (
'train', 'devel',
'test') # group names in the low-level database interface
self.high_level_group_names = (
'world', 'dev',
'eval') # names are expected to be like that in objects() function
# call base class constructors to open a session to the database
super(ReplayMobileVideoBioDatabase, self).__init__(
def original_directory(self):
return self._db.original_directory
def original_directory(self, value):
self._db.original_directory = value
def original_extension(self):
return self._db.original_extension
def original_extension(self, value):
self._db.original_extension = value
def annotation_directory(self):
return self._db.annotation_directory
def annotation_directory(self, value):
self._db.annotation_directory = value
def annotation_extension(self):
return self._db.annotation_extension
def annotation_extension(self, value):
self._db.annotation_extension = value
def annotation_type(self):
return self._db.annotation_type
def annotation_type(self, value):
self._db.annotation_type = value
def protocol_names(self):
"""Returns all registered protocol names
Here I am going to hack and double the number of protocols
with -licit and -spoof. This is done for running vulnerability
names = [ + '-licit' for p in self._db.protocols()]
names += [ + '-spoof' for p in self._db.protocols()]
return names
def groups(self):
return self.high_level_group_names
def model_ids_with_protocol(self, groups=None, protocol=None, **kwargs):
# since the low-level API does not support verification
# straight-forward-ly, we improvise.
files = self._db.objects(groups=groups, protocol=protocol,
cls='enroll', **kwargs)
return sorted(set(f.client_id for f in files))
def objects(self, groups=None, protocol=None, purposes=None, model_ids=None, **kwargs):
if protocol == '.':
protocol = None
protocol = self.check_parameter_for_validity(
protocol, "protocol", self.protocol_names(), 'grandtest-licit')
groups = self.check_parameters_for_validity(
groups, "group", self.groups(), self.groups())
purposes = self.check_parameters_for_validity(
purposes, "purpose", ('enroll', 'probe'), ('enroll', 'probe'))
purposes = list(purposes)
groups = self.convert_names_to_lowlevel(
groups, self.low_level_group_names, self.high_level_group_names)
# protocol licit is not defined in the low level API
# so do a hack here.
if '-licit' in protocol:
# for licit we return the grandtest protocol
protocol = protocol.replace('-licit', '')
# The low-level API has only "attack", "real", "enroll" and "probe"
# should translate to "real" or "attack" depending on the protocol.
# enroll does not to change.
if 'probe' in purposes:
if len(purposes) == 1:
# making the model_ids to None will return all clients
# which make the impostor data also available.
model_ids = None
elif model_ids:
raise NotImplementedError(
'Currently returning both enroll and probe for '
'specific client(s) in the licit protocol is not '
'supported. Please specify one purpose only.')
elif '-spoof' in protocol:
protocol = protocol.replace('-spoof', '')
# you need to replace probe with attack and real for the spoof
# protocols. You can add the real here also to create positives
# scores also but usually you get these scores when you run the
# licit protocol
if 'probe' in purposes:
# now, query the actual Replay database
objects = self._db.objects(
groups=groups, protocol=protocol, cls=purposes, clients=model_ids,
# make sure to return File representation of a file, not the database
# one also make sure you replace client ids with attack
retval = []
for f in objects:
if f.is_real():
temp = ReplayMobileVideoBioFile(f)
attack = f.get_attack()
temp.client_id = 'attack/{}'.format(
attack.attack_device, attack.attack_support)
for f in retval:
f.original_directory = self.original_directory
return retval
def arrange_by_client(self, files):
client_files = {}
for file in files:
if str(file.client_id) not in client_files:
client_files[str(file.client_id)] = []
files_by_clients = []
for client in sorted(client_files.keys()):
return files_by_clients
def annotations(self, file):
return file.annotations
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment