From fe101e246db30efbbef6b910f8cff28dfcdc7b26 Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Fri, 22 Jun 2018 14:16:27 +0200
Subject: [PATCH 01/22] [cvpr14] extract_utils: get the updated master version

---
 bob/rppg/cvpr14/extract_utils.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bob/rppg/cvpr14/extract_utils.py b/bob/rppg/cvpr14/extract_utils.py
index 56c9664..1deed77 100644
--- a/bob/rppg/cvpr14/extract_utils.py
+++ b/bob/rppg/cvpr14/extract_utils.py
@@ -48,7 +48,7 @@ def kp66_to_mask(image, keypoints, indent=10, plot=False):
     The points corresponding to vertices of the mask.
   
   """
-  assert keypoints.shape[0] == 66, "You should provide a set 66 keypoints"
+  assert keypoints.shape[0] == 66  or keypoints.shape[0] == 68, "You should provide a set of 66 (DRMF) or 68 (dlib ) keypoints"
 
   if plot:
     imkey = numpy.copy(image)
-- 
GitLab


From e9fcfe1f3e969d0f3ad0a69078c56b6d64446ffe Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Fri, 22 Jun 2018 15:46:18 +0200
Subject: [PATCH 02/22] [utils] add a function to get parameters from either
 configuration file or command-line

---
 bob/rppg/base/utils.py | 43 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/bob/rppg/base/utils.py b/bob/rppg/base/utils.py
index 9b64fae..3775213 100644
--- a/bob/rppg/base/utils.py
+++ b/bob/rppg/base/utils.py
@@ -99,3 +99,46 @@ def build_bandpass_filter(fs, order, plot=False):
     pyplot.show()
 
   return b
+
+
+def get_parameter(args, configuration, keyword, default):
+  """ Get the right value for a parameter
+
+  The parameters are either defined in a separate configuration file
+  or given directly via command-line. Note that the command-line
+  has priority over the configuration file.
+
+  As a convention, parameters made with more than one word 
+  are provided with an underscore in the configuration file, and with an
+  hyphen in the command-line:
+
+    - configuration:  batch_size=64
+    - command line:   --batch-size=64
+
+  Parameters
+  ----------
+  args: dictionary
+    The arguments as parsed from the command line.
+  configuration: object
+    The arguments given by the configuration file.
+  keyword: string
+    the keyword for the parameter to process (in the "configuration" style)
+  default: 
+    The default value of the parameter
+
+  Returns
+  -------
+  arg:
+    The right value for the given keyword argument
+
+  """
+ 
+  args_kw = '--' + keyword.replace('_', '-')
+  _type = type(default)
+  arg = _type(args[args_kw])
+  if hasattr(configuration, keyword):
+    arg = getattr(configuration, keyword)
+  if _type(args[args_kw]) is not default:
+    arg = _type(args[args_kw])
+  return arg
+
-- 
GitLab


From 2248c3b8c423d3c9a7fb663da0a952641f280e16 Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Fri, 22 Jun 2018 15:46:58 +0200
Subject: [PATCH 03/22] [cvpr14] added script to load database thanks to a
 configuration file

---
 bob/rppg/cvpr14/script/extract_pulses.py | 255 +++++++++++++++++++++++
 setup.py                                 |   1 +
 2 files changed, 256 insertions(+)
 create mode 100644 bob/rppg/cvpr14/script/extract_pulses.py

diff --git a/bob/rppg/cvpr14/script/extract_pulses.py b/bob/rppg/cvpr14/script/extract_pulses.py
new file mode 100644
index 0000000..88ba6bb
--- /dev/null
+++ b/bob/rppg/cvpr14/script/extract_pulses.py
@@ -0,0 +1,255 @@
+#!/usr/bin/env python
+# encoding: utf-8
+
+"""Extract pulses according to Li's CVPR 2014 algorithm 
+
+Usage:
+  %(prog)s <configuration>
+           [--protocol=<string>] [--subset=<string> ...]
+           [--dbdir=<path>] [--facedir=<path>] [--bgdir=<path>] 
+           [--npoints=<int>] [--indent=<int>] [--quality=<float>] [--distance=<int>]
+           [--wholeface] [--overwrite] [--verbose ...] [--plot] [--gridcount]
+
+  %(prog)s (--help | -h)
+  %(prog)s (--version | -V)
+
+
+Options:
+  -h, --help                Show this screen
+  -V, --version             Show version
+  -p, --protocol=<string>   Protocol [default: all].
+  -s, --subset=<string>     Data subset to load. If nothing is provided 
+                            all the sets will be loaded.
+  -f, --facedir=<path>      The path to the directory where signal extracted 
+                            from the face area will be stored [default: face]
+  -b, --bgdir=<path>        The path to the directory where signal extracted 
+                            from the background area will be stored [default: background]
+  -n, --npoints=<int>       Number of good features to track [default: 40]
+  -i, --indent=<int>        Indent (in percent of the face width) to apply to 
+                            keypoints to get the mask [default: 10]
+  -q, --quality=<float>     Quality level of the good features to track
+                            [default: 0.01]
+  -e, --distance=<int>      Minimum distance between detected good features to
+                            track [default: 10]
+  -O, --overwrite           By default, we don't overwrite existing files. The
+                            processing will skip those so as to go faster. If you
+                            still would like me to overwrite them, set this flag.
+  -v, --verbose             Increases the verbosity (may appear multiple times)
+  -P, --plot                Set this flag if you'd like to follow-up the algorithm
+                            execution graphically. We'll plot some interactions.
+  -g, --gridcount           Prints the number of objects to process and exits.
+  -w, --wholeface           Consider the whole face region instead of the mask.
+
+
+Example:
+
+  To run the pulse extractor: 
+
+    $ %(prog)s config.py -v
+
+See '%(prog)s --help' for more information.
+
+"""
+
+from __future__ import print_function
+
+import os
+import sys
+import pkg_resources
+
+from bob.core.log import setup
+logger = setup("bob.rppg.base")
+
+from docopt import docopt
+
+from bob.extension.config import load
+
+version = pkg_resources.require('bob.rppg.base')[0].version
+
+import numpy
+import bob.io.base
+import bob.ip.facedetect
+
+from ...base.utils import get_parameter
+from ...base.utils import crop_face
+
+from ..extract_utils import kp66_to_mask
+from ..extract_utils import get_good_features_to_track
+from ..extract_utils import track_features
+from ..extract_utils import find_transformation
+from ..extract_utils import get_current_mask_points
+from ..extract_utils import get_mask 
+from ..extract_utils import compute_average_colors_mask
+from ..extract_utils import compute_average_colors_wholeface
+
+def main(user_input=None):
+
+  # Parse the command-line arguments
+  if user_input is not None:
+      arguments = user_input
+  else:
+      arguments = sys.argv[1:]
+
+  prog = os.path.basename(sys.argv[0])
+  completions = dict(prog=prog, version=version,)
+  args = docopt(__doc__ % completions, argv=arguments, version='Signal extractor for videos (%s)' % version,)
+
+  # if the user wants more verbosity, lowers the logging level
+  from bob.core.log import set_verbosity_level
+  set_verbosity_level(logger, args['--verbose'])
+
+  # load configuration file
+  configuration = load([os.path.join(args['<configuration>'])])
+  
+  # get various parameters, either from config file or command-line 
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', '')
+  facedir = get_parameter(args, configuration, 'facedir', 'face')
+  bgdir = get_parameter(args, configuration, 'bgdir', 'bg')
+  npoints = get_parameter(args, configuration, 'npoints', 40)
+  indent = get_parameter(args, configuration, 'indent', 10)
+  quality = get_parameter(args, configuration, 'quality', 0.01)
+  distance = get_parameter(args, configuration, 'distance', 10)
+  overwrite = get_parameter(args, configuration, 'overwrite', False)
+  plot = get_parameter(args, configuration, 'plot', False)
+  gridcount = get_parameter(args, configuration, 'gridcount', False)
+  wholeface = get_parameter(args, configuration, 'wholeface', False)
+  verbosity_level = get_parameter(args, configuration, 'verbose', 0)
+  
+  # TODO: find a way to check protocol names - Guillaume HEUSCH, 22-06-2018
+  if hasattr(configuration, 'database'):
+    objects = configuration.database.objects(args['--protocol'], args['--subset'])
+  else:
+    logger.error("Please provide a database in your configuration file !")
+    sys.exit()
+
+  # if we are on a grid environment, just find what I have to process.
+  sge = False
+  try:
+    sge = os.environ.has_key('SGE_TASK_ID') # python2
+  except AttributeError:
+    sge = 'SGE_TASK_ID' in os.environ # python3
+    
+  if sge:
+    pos = int(os.environ['SGE_TASK_ID']) - 1
+    if pos >= len(objects):
+      raise RuntimeError("Grid request for job {} on a setup with {} jobs".format(pos, len(objects)))
+    objects = [objects[pos]]
+
+  if args['--gridcount']:
+    print(len(objects))
+    sys.exit()
+
+  # does the actual work - for every video in the available dataset, 
+  # extract the signals and dumps the results to the corresponding directory
+  for obj in objects:
+
+    # expected output file
+    output_face = obj.make_path(args['--facedir'], '.hdf5')
+    output_bg = obj.make_path(args['--bgdir'], '.hdf5')
+
+    # if output exists and not overwriting, skip this file
+    if (os.path.exists(output_face) and os.path.exists(output_bg)) and not args['--overwrite']:
+      logger.info("Skipping output file `%s': already exists, use --overwrite to force an overwrite", output_face)
+      continue
+    
+    # load video
+    video = obj.load_video(configuration.dbdir)
+    logger.info("Processing input video from `%s'...", video.filename)
+
+    # load the result of face detection
+    bounding_boxes = obj.load_face_detection() 
+
+    # average green color in the mask area  
+    face_color = numpy.zeros(len(video), dtype='float64')
+    # average green color in the background area
+    bg_color = numpy.zeros(len(video), dtype='float64')
+
+    # loop on video frames
+    for i, frame in enumerate(video):
+      logger.debug("Processing frame %d/%d...", i+1, len(video))
+
+      if i == 0:
+        # first frame:
+        # -> load the keypoints detected by DMRF
+        # -> infer the mask from the keypoints
+        # -> detect the face
+        # -> get "good features" inside the face
+        if not bool(args['--wholeface']):
+          kpts = obj.load_drmf_keypoints()
+          mask_points, mask = kp66_to_mask(frame, kpts, int(args['--indent']), bool(args['--plot']))
+
+        try: 
+          bbox = bounding_boxes[i]
+        except NameError:
+          bbox, quality = bob.ip.facedetect.detect_single_face(frame)
+        
+        # define the face width for the whole sequence
+        facewidth = bbox.size[1]
+        face = crop_face(frame, bbox, facewidth)
+        
+        if not bool(args['--wholeface']):
+          good_features = get_good_features_to_track(face,int(args['--npoints']), 
+              float(args['--quality']), int(args['--distance']), bool(args['--plot']))
+      else:
+        # subsequent frames:
+        # -> crop the face with the bounding_boxes of the previous frame (so
+        #    that faces are of the same size)
+        # -> get the projection of the corners detected in the previous frame
+        # -> find the (affine) transformation relating previous corners with
+        #    current corners
+        # -> apply this transformation to the mask
+        face = crop_face(frame, prev_bb, facewidth)
+        if not bool(args['--wholeface']):
+          good_features = track_features(prev_face, face, prev_features, bool(args['--plot']))
+          project = find_transformation(prev_features, good_features)
+          if project is None: 
+            logger.warn("Sequence {0}, frame {1} : No projection was found"
+                " between previous and current frame, mask from previous frame will be used"
+                .format(obj.path, i))
+          else:
+            mask_points = get_current_mask_points(mask_points, project)
+
+      # update stuff for the next frame:
+      # -> the previous face is the face in this frame, with its bbox (and not
+      #    with the previous one)
+      # -> the features to be tracked on the next frame are re-detected
+      try: 
+        prev_bb = bounding_boxes[i]
+      except NameError:
+        bb, quality = bob.ip.facedetect.detect_single_face(frame)
+        prev_bb = bb
+
+      
+      if not bool(args['--wholeface']):
+        prev_face = crop_face(frame, prev_bb, facewidth)
+        prev_features = get_good_features_to_track(face, int(args['--npoints']),
+            float(args['--quality']), int(args['--distance']),
+            bool(args['--plot']))
+        if prev_features is None:
+          logger.warn("Sequence {0}, frame {1} No features to track"  
+              " detected in the current frame, using the previous ones"
+              .format(obj.path, i))
+          prev_features = good_features
+
+        # get the bottom face region average colors
+        face_mask = get_mask(frame, mask_points)
+        face_color[i] = compute_average_colors_mask(frame, face_mask, bool(args['--plot']))
+      else:
+        face_color[i] = compute_average_colors_wholeface(face, bool(args['--plot']))
+
+      # get the background region average colors
+      bg_mask = numpy.zeros((frame.shape[1], frame.shape[2]), dtype=bool)
+      bg_mask[:100, :100] = True
+      bg_color[i] = compute_average_colors_mask(frame, bg_mask, bool(args['--plot']))
+
+    # saves the data into an HDF5 file with a '.hdf5' extension
+    out_facedir = os.path.dirname(output_face)
+    if not os.path.exists(out_facedir): bob.io.base.create_directories_safe(out_facedir)
+    bob.io.base.save(face_color, output_face)
+    logger.info("Output file saved to `%s'...", output_face)
+
+    out_bgdir = os.path.dirname(output_bg)
+    if not os.path.exists(out_bgdir): bob.io.base.create_directories_safe(out_bgdir)
+    bob.io.base.save(bg_color, output_bg)
+    logger.info("Output file saved to `%s'...", output_bg)
diff --git a/setup.py b/setup.py
index 9615800..0867f42 100644
--- a/setup.py
+++ b/setup.py
@@ -32,6 +32,7 @@ setup(
 
   entry_points={
     'console_scripts': [
+      'cvpr14_extract_pulses.py = bob.rppg.cvpr14.script.extract_pulses:main',
       'cvpr14_extract_signals.py = bob.rppg.cvpr14.script.extract_signals:main',
       'cvpr14_video2skin.py = bob.rppg.cvpr14.script.video2skin:main',
       'cvpr14_illumination.py = bob.rppg.cvpr14.script.illumination_rectification:main',
-- 
GitLab


From fb362624fe5217cb55b4f4f0561b64297b628ab2 Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Mon, 25 Jun 2018 16:24:56 +0200
Subject: [PATCH 04/22] [cvpr14] added configuration files to scripts, getting
 rid of bob.db.* dependencies

---
 bob/rppg/base/script/compute_performance.py   |  92 ++++++--------
 bob/rppg/base/script/frequency_analysis.py    |  92 +++++++-------
 bob/rppg/base/utils.py                        |   2 +-
 bob/rppg/cvpr14/script/extract_pulses.py      |  45 ++++---
 bob/rppg/cvpr14/script/filter.py              | 106 +++++++---------
 .../script/illumination_rectification.py      | 106 +++++++---------
 bob/rppg/cvpr14/script/motion_elimination.py  | 115 ++++++++----------
 7 files changed, 245 insertions(+), 313 deletions(-)

diff --git a/bob/rppg/base/script/compute_performance.py b/bob/rppg/base/script/compute_performance.py
index 4e3ad22..b120996 100644
--- a/bob/rppg/base/script/compute_performance.py
+++ b/bob/rppg/base/script/compute_performance.py
@@ -1,11 +1,12 @@
 #!/usr/bin/env python
 # encoding: utf-8
 
-"""Generate resutls from heart rate computation (%(version)s)
+"""Generate results from heart rate computation (%(version)s)
   
 Usage:
-  %(prog)s (hci | cohface) [--protocol=<string>] [--subset=<string> ...] 
-           [--verbose ...] [--plot] [--outdir=<path>] [--indir=<path>] 
+  %(prog)s <configuration>
+           [--protocol=<string>] [--subset=<string> ...] 
+           [--verbose ...] [--plot] [--resultdir=<path>] [--hrdir=<path>] 
            [--overwrite] 
 
   %(prog)s (--help | -h)
@@ -20,21 +21,17 @@ Options:
   -p, --protocol=<string>   Protocol [default: all].
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
-  -i, --indir=<path>        The path to the saved heart rate values on your disk. 
-  -o, --outdir=<path>       The path to the output directory where the results
+  -i, --hrdir=<path>        The path to the saved heart rate values on your disk. 
+  -o, --resultdir=<path>       The path to the output directory where the results
                             will be stored [default: performances].
   -O, --overwrite           By default, we don't overwrite existing files. 
                             Set this flag if you want to overwrite existing files.
 
 Examples:
 
-  To run the results generation for the cohface database
+  To run the results generation 
 
-    $ %(prog)s cohface -v
-
-  You can change the output directory using the `-o' flag:
-
-    $ %(prog)s hci -v -o /path/to/result/directory
+    $ %(prog)s config.py -v
 
 
 See '%(prog)s --help' for more information.
@@ -50,6 +47,9 @@ logger = setup("bob.rppg.base")
 
 from docopt import docopt
 
+from bob.extension.config import load
+from bob.rppg.base.utils import get_parameter
+
 version = pkg_resources.require('bob.rppg.base')[0].version
 
 import numpy
@@ -67,45 +67,28 @@ def main(user_input=None):
   completions = dict(prog=prog, version=version,)
   args = docopt(__doc__ % completions, argv=arguments, version='Signal extractor for videos (%s)' % version,)
 
+  # load configuration file
+  configuration = load([os.path.join(args['<configuration>'])])
+
+  # get various parameters, either from config file or command-line 
+  protocol = get_parameter(args, configuration, 'protocol', '')
+  subset = get_parameter(args, configuration, 'subset', 'all')
+  hrdir = get_parameter(args, configuration, 'hrdir', 'hr')
+  resultdir = get_parameter(args, configuration, 'resultdir', 'results')
+  overwrite = get_parameter(args, configuration, 'overwrite', False)
+  plot = get_parameter(args, configuration, 'plot', False)
+  verbosity_level = get_parameter(args, configuration, 'verbose', 0)
+  
   # if the user wants more verbosity, lowers the logging level
   from bob.core.log import set_verbosity_level
   set_verbosity_level(logger, args['--verbose'])
 
-  # chooses the database driver to use
-  if args['cohface']:
-    import bob.db.cohface
-    if os.path.isdir(bob.db.cohface.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.cohface.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir']
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.cohface.Database(dbdir)
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'clean') or (args['--protocol'] == 'natural')):
-      logger.warning("Protocol should be either 'clean', 'natural' or 'all' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
-
-  elif args['hci']:
-    import bob.db.hci_tagging
-    import bob.db.hci_tagging.driver
-    if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir'] 
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.hci_tagging.Database()
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'cvpr14')):
-      logger.warning("Protocol should be either 'all' or 'cvpr14' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
+  # TODO: find a way to check protocol names - Guillaume HEUSCH, 22-06-2018
+  if hasattr(configuration, 'database'):
+    objects = configuration.database.objects(protocol, subset)
+  else:
+    logger.error("Please provide a database in your configuration file !")
+    sys.exit()
 
   # errors
   errors = []
@@ -118,20 +101,19 @@ def main(user_input=None):
   ################
   ### LET'S GO ###
   ################
-  outdir = args['--outdir']
   
   # if output dir exists and not overwriting, stop 
-  if os.path.exists(outdir) and not args['--overwrite']:
-    logger.info("Skipping output `%s': already exists, use --overwrite to force an overwrite", outdir)
+  if os.path.exists(resultdir) and not overwrite:
+    logger.info("Skipping output `%s': already exists, use --overwrite to force an overwrite", resultdir)
     sys.exit()
   else: 
-    bob.io.base.create_directories_safe(outdir)
+    bob.io.base.create_directories_safe(resultdir)
 
   for obj in objects:
 
     # load the heart rate 
     logger.debug("Loading computed heart rate from `%s'...", obj.path)
-    hr_file = obj.make_path(args['--indir'], '.hdf5')
+    hr_file = obj.make_path(hrdir, '.hdf5')
     try:
       hr = bob.io.base.load(hr_file)
     except (IOError, RuntimeError) as e:
@@ -169,7 +151,7 @@ def main(user_input=None):
   logger.info(pearson_text)
 
   # statistics in a text file
-  stats_filename = os.path.join(outdir, 'stats.txt')
+  stats_filename = os.path.join(resultdir, 'stats.txt')
   stats_file = open(stats_filename, 'w')
   stats_file.write(rmse_text + "\n")
   stats_file.write(mean_err_percent_text + "\n")
@@ -185,7 +167,7 @@ def main(user_input=None):
   pyplot.xlabel('Ground truth [bpm]')
   pyplot.ylabel('Estimated heart-rate [bpm]')
   ax.set_title('Scatter plot')
-  scatter_file = os.path.join(outdir, 'scatter.png')
+  scatter_file = os.path.join(resultdir, 'scatter.png')
   pyplot.savefig(scatter_file)
 
   # histogram of error
@@ -193,7 +175,7 @@ def main(user_input=None):
   ax2 = f2.add_subplot(1,1,1)
   ax2.hist(errors, bins=50, )
   ax2.set_title('Distribution of the error')
-  distribution_file = os.path.join(outdir, 'error_distribution.png')
+  distribution_file = os.path.join(resultdir, 'error_distribution.png')
   pyplot.savefig(distribution_file)
 
   # distribution of HR
@@ -204,7 +186,7 @@ def main(user_input=None):
   pyplot.hist(inferred, label='Estimated HR', color='b', **histoargs)
   pyplot.ylabel("Test set")
 
-  if bool(args['--plot']):
+  if plot:
     pyplot.show()
   
   return 0
diff --git a/bob/rppg/base/script/frequency_analysis.py b/bob/rppg/base/script/frequency_analysis.py
index 223871d..c564721 100644
--- a/bob/rppg/base/script/frequency_analysis.py
+++ b/bob/rppg/base/script/frequency_analysis.py
@@ -1,11 +1,12 @@
 #!/usr/bin/env python
 # encoding: utf-8
 
-"""Frequency analysis of the filtered color signals to get the heart-rate (%(version)s)
+"""Frequency analysis of the pulse signal to get the heart-rate (%(version)s)
 
 Usage:
-  %(prog)s (cohface | hci) [--protocol=<string>] [--subset=<string> ...]  
-           [--verbose ...] [--plot] [--indir=<path>] [--outdir=<path>] 
+  %(prog)s <configuration>
+           [--protocol=<string>] [--subset=<string> ...]  
+           [--verbose ...] [--plot] [--pulsedir=<path>] [--hrdir=<path>] 
            [--framerate=<int>] [--nsegments=<int>] [--nfft=<int>] 
            [--overwrite] 
 
@@ -22,9 +23,9 @@ Options:
   -p, --protocol=<string>   Protocol [default: all].
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
-  -i, --indir=<path>        The path to the saved filtered signals on your disk
+  -i, --pulsedir=<path>        The path to the saved filtered signals on your disk
                             [default: filtered].
-  -o, --outdir=<path>       The path to the output directory where the resulting
+  -o, --hrdir=<path>       The path to the output directory where the resulting
                             color signals will be stored [default: heart-rate].
   -O, --overwrite           By default, we don't overwrite existing files. The
                             processing will skip those so as to go faster. If you
@@ -58,6 +59,9 @@ logger = setup("bob.rppg.base")
 
 from docopt import docopt
 
+from bob.extension.config import load
+from bob.rppg.base.utils import get_parameter
+
 version = pkg_resources.require('bob.rppg.base')[0].version
 
 import numpy
@@ -75,45 +79,34 @@ def main(user_input=None):
   completions = dict(prog=prog, version=version,)
   args = docopt(__doc__ % completions, argv=arguments, version='Signal extractor for videos (%s)' % version,)
 
+  # load configuration file
+  configuration = load([os.path.join(args['<configuration>'])])
+
+  # get various parameters, either from config file or command-line 
+  protocol = get_parameter(args, configuration, 'protocol', '')
+  subset = get_parameter(args, configuration, 'subset', 'all')
+  pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
+  hrdir = get_parameter(args, configuration, 'hrdir', 'hr')
+  framerate = get_parameter(args, configuration, 'framerate', 61)
+  nsegments = get_parameter(args, configuration, 'nsegments', 12)
+  nfft = get_parameter(args, configuration, 'nfft', 8192)
+  overwrite = get_parameter(args, configuration, 'overwrite', False)
+  plot = get_parameter(args, configuration, 'plot', False)
+  verbosity_level = get_parameter(args, configuration, 'verbose', 0)
+ 
+  print(nsegments)
+  print(nfft)
+
   # if the user wants more verbosity, lowers the logging level
   from bob.core.log import set_verbosity_level
   set_verbosity_level(logger, args['--verbose'])
-
-  # chooses the database driver to use
-  if args['cohface']:
-    import bob.db.cohface
-    if os.path.isdir(bob.db.cohface.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.cohface.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir']
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.cohface.Database(dbdir)
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'clean') or (args['--protocol'] == 'natural')):
-      logger.warning("Protocol should be either 'clean', 'natural' or 'all' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
-
-  elif args['hci']:
-    import bob.db.hci_tagging
-    import bob.db.hci_tagging.driver
-    if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir'] 
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.hci_tagging.Database()
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'cvpr14')):
-      logger.warning("Protocol should be either 'all' or 'cvpr14' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
+ 
+  # TODO: find a way to check protocol names - Guillaume HEUSCH, 22-06-2018
+  if hasattr(configuration, 'database'):
+    objects = configuration.database.objects(protocol, subset)
+  else:
+    logger.error("Please provide a database in your configuration file !")
+    sys.exit()
 
   ################
   ### LET'S GO ###
@@ -121,39 +114,38 @@ def main(user_input=None):
   for obj in objects:
 
     # expected output file
-    output = obj.make_path(args['--outdir'], '.hdf5')
+    output = obj.make_path(hrdir, '.hdf5')
 
     # if output exists and not overwriting, skip this file
-    if os.path.exists(output) and not args['--overwrite']:
+    if os.path.exists(output) and not overwrite:
       logger.info("Skipping output file `%s': already exists, use --overwrite to force an overwrite", output)
       continue
 
     # load the filtered color signals of shape (3, nb_frames)
     logger.info("Frequency analysis of color signals from `%s'...", obj.path)
-    filtered_file = obj.make_path(args['--indir'], '.hdf5')
+    filtered_file = obj.make_path(pulsedir, '.hdf5')
     try:
       signal = bob.io.base.load(filtered_file)
     except (IOError, RuntimeError) as e:
       logger.warn("Skipping file `%s' (no color signals file available)", obj.path)
       continue
 
-    if bool(args['--plot']):
+    if plot:
       from matplotlib import pyplot
       pyplot.plot(range(signal.shape[0]), signal, 'g')
       pyplot.title('Filtered green signal')
       pyplot.show()
 
     # find the segment length, such that we have 8 50% overlapping segments (Matlab's default)
-    segment_length = (2*signal.shape[0]) // (int(args['--nsegments']) + 1) 
+    segment_length = (2*signal.shape[0]) // (nsegments + 1) 
 
     # the number of points for FFT should be larger than the segment length ...
-    if int(args['--nfft']) < segment_length:
+    if nfft < segment_length:
       logger.warn("Skipping file `%s' (nfft < nperseg)", obj.path)
       continue
 
-    nfft = int(args['--nfft'])
     from scipy.signal import welch
-    green_f, green_psd = welch(signal, int(args['--framerate']), nperseg=segment_length, nfft=nfft)
+    green_f, green_psd = welch(signal, framerate, nperseg=segment_length, nfft=nfft)
 
     # find the max of the frequency spectrum in the range of interest
     first = numpy.where(green_f > 0.7)[0]
@@ -166,7 +158,7 @@ def main(user_input=None):
     hr = f_max*60.0
     logger.info("Heart rate = {0}".format(hr))
 
-    if bool(args['--plot']):
+    if plot:
       from matplotlib import pyplot
       pyplot.semilogy(green_f, green_psd, 'g')
       xmax, xmin, ymax, ymin = pyplot.axis()
diff --git a/bob/rppg/base/utils.py b/bob/rppg/base/utils.py
index 3775213..1a1d189 100644
--- a/bob/rppg/base/utils.py
+++ b/bob/rppg/base/utils.py
@@ -138,7 +138,7 @@ def get_parameter(args, configuration, keyword, default):
   arg = _type(args[args_kw])
   if hasattr(configuration, keyword):
     arg = getattr(configuration, keyword)
-  if _type(args[args_kw]) is not default:
+  if _type(args[args_kw]) is not default and not hasattr(configuration, keyword):
     arg = _type(args[args_kw])
   return arg
 
diff --git a/bob/rppg/cvpr14/script/extract_pulses.py b/bob/rppg/cvpr14/script/extract_pulses.py
index 88ba6bb..2d3794f 100644
--- a/bob/rppg/cvpr14/script/extract_pulses.py
+++ b/bob/rppg/cvpr14/script/extract_pulses.py
@@ -17,7 +17,7 @@ Usage:
 Options:
   -h, --help                Show this screen
   -V, --version             Show version
-  -p, --protocol=<string>   Protocol [default: all].
+  -p, --protocol=<string>   Protocol.
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the sets will be loaded.
   -f, --facedir=<path>      The path to the directory where signal extracted 
@@ -94,10 +94,6 @@ def main(user_input=None):
   completions = dict(prog=prog, version=version,)
   args = docopt(__doc__ % completions, argv=arguments, version='Signal extractor for videos (%s)' % version,)
 
-  # if the user wants more verbosity, lowers the logging level
-  from bob.core.log import set_verbosity_level
-  set_verbosity_level(logger, args['--verbose'])
-
   # load configuration file
   configuration = load([os.path.join(args['<configuration>'])])
   
@@ -116,9 +112,13 @@ def main(user_input=None):
   wholeface = get_parameter(args, configuration, 'wholeface', False)
   verbosity_level = get_parameter(args, configuration, 'verbose', 0)
   
+  # if the user wants more verbosity, lowers the logging level
+  from bob.core.log import set_verbosity_level
+  set_verbosity_level(logger, verbosity_level)
+  
   # TODO: find a way to check protocol names - Guillaume HEUSCH, 22-06-2018
   if hasattr(configuration, 'database'):
-    objects = configuration.database.objects(args['--protocol'], args['--subset'])
+    objects = configuration.database.objects(protocol, subset)
   else:
     logger.error("Please provide a database in your configuration file !")
     sys.exit()
@@ -136,7 +136,7 @@ def main(user_input=None):
       raise RuntimeError("Grid request for job {} on a setup with {} jobs".format(pos, len(objects)))
     objects = [objects[pos]]
 
-  if args['--gridcount']:
+  if gridcount:
     print(len(objects))
     sys.exit()
 
@@ -145,11 +145,11 @@ def main(user_input=None):
   for obj in objects:
 
     # expected output file
-    output_face = obj.make_path(args['--facedir'], '.hdf5')
-    output_bg = obj.make_path(args['--bgdir'], '.hdf5')
+    output_face = obj.make_path(facedir, '.hdf5')
+    output_bg = obj.make_path(bgdir, '.hdf5')
 
     # if output exists and not overwriting, skip this file
-    if (os.path.exists(output_face) and os.path.exists(output_bg)) and not args['--overwrite']:
+    if (os.path.exists(output_face) and os.path.exists(output_bg)) and not overwrite:
       logger.info("Skipping output file `%s': already exists, use --overwrite to force an overwrite", output_face)
       continue
     
@@ -175,9 +175,9 @@ def main(user_input=None):
         # -> infer the mask from the keypoints
         # -> detect the face
         # -> get "good features" inside the face
-        if not bool(args['--wholeface']):
+        if not wholeface:
           kpts = obj.load_drmf_keypoints()
-          mask_points, mask = kp66_to_mask(frame, kpts, int(args['--indent']), bool(args['--plot']))
+          mask_points, mask = kp66_to_mask(frame, kpts, indent, plot)
 
         try: 
           bbox = bounding_boxes[i]
@@ -188,9 +188,8 @@ def main(user_input=None):
         facewidth = bbox.size[1]
         face = crop_face(frame, bbox, facewidth)
         
-        if not bool(args['--wholeface']):
-          good_features = get_good_features_to_track(face,int(args['--npoints']), 
-              float(args['--quality']), int(args['--distance']), bool(args['--plot']))
+        if not wholeface:
+          good_features = get_good_features_to_track(face, npoints, quality, distance, plot)
       else:
         # subsequent frames:
         # -> crop the face with the bounding_boxes of the previous frame (so
@@ -200,8 +199,8 @@ def main(user_input=None):
         #    current corners
         # -> apply this transformation to the mask
         face = crop_face(frame, prev_bb, facewidth)
-        if not bool(args['--wholeface']):
-          good_features = track_features(prev_face, face, prev_features, bool(args['--plot']))
+        if not wholeface:
+          good_features = track_features(prev_face, face, prev_features, plot)
           project = find_transformation(prev_features, good_features)
           if project is None: 
             logger.warn("Sequence {0}, frame {1} : No projection was found"
@@ -221,11 +220,9 @@ def main(user_input=None):
         prev_bb = bb
 
       
-      if not bool(args['--wholeface']):
+      if not wholeface:
         prev_face = crop_face(frame, prev_bb, facewidth)
-        prev_features = get_good_features_to_track(face, int(args['--npoints']),
-            float(args['--quality']), int(args['--distance']),
-            bool(args['--plot']))
+        prev_features = get_good_features_to_track(face, npoints, quality, distance, plot)
         if prev_features is None:
           logger.warn("Sequence {0}, frame {1} No features to track"  
               " detected in the current frame, using the previous ones"
@@ -234,14 +231,14 @@ def main(user_input=None):
 
         # get the bottom face region average colors
         face_mask = get_mask(frame, mask_points)
-        face_color[i] = compute_average_colors_mask(frame, face_mask, bool(args['--plot']))
+        face_color[i] = compute_average_colors_mask(frame, face_mask, plot)
       else:
-        face_color[i] = compute_average_colors_wholeface(face, bool(args['--plot']))
+        face_color[i] = compute_average_colors_wholeface(face, plot)
 
       # get the background region average colors
       bg_mask = numpy.zeros((frame.shape[1], frame.shape[2]), dtype=bool)
       bg_mask[:100, :100] = True
-      bg_color[i] = compute_average_colors_mask(frame, bg_mask, bool(args['--plot']))
+      bg_color[i] = compute_average_colors_mask(frame, bg_mask, plot)
 
     # saves the data into an HDF5 file with a '.hdf5' extension
     out_facedir = os.path.dirname(output_face)
diff --git a/bob/rppg/cvpr14/script/filter.py b/bob/rppg/cvpr14/script/filter.py
index d4a165c..0b353bc 100644
--- a/bob/rppg/cvpr14/script/filter.py
+++ b/bob/rppg/cvpr14/script/filter.py
@@ -1,12 +1,13 @@
 #!/usr/bin/env python
 # encoding: utf-8
 
-"""Filtering of color signal (%(version)s)
+"""Filtering (%(version)s)
 
 Usage:
-  %(prog)s (cohface | hci) [--protocol=<string>] [--subset=<string> ...]  
-           [--verbose ...] [--plot] [--indir=<path>] [--outdir=<path>]
-           [--lambda=<int>] [--window=<int>] [--framerate=<int>] [--order=<int>]
+  %(prog)s <configuration>
+           [--protocol=<string>] [--subset=<string> ...]  
+           [--verbose ...] [--plot] [--motiondir=<path>] [--pulsedir=<path>]
+           [--Lambda=<int>] [--window=<int>] [--framerate=<int>] [--order=<int>]
            [--overwrite] [--gridcount]
 
   %(prog)s (--help | -h)
@@ -22,11 +23,11 @@ Options:
   -p, --protocol=<string>   Protocol [default: all].
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
-  -i, --indir=<path>        The path to the saved signals to be filtered on
+  -i, --motiondir=<path>        The path to the saved signals to be filtered on
                             your disk [default: motion].
-  -o, --outdir=<path>       The path to the output directory where the resulting
+  -o, --pulsedir=<path>       The path to the output directory where the resulting
                             color signals will be stored [default: filtered].
-  --lambda=<int>            Lambda parameter for detrending (see article) [default: 300]
+  --Lambda=<int>            Lambda parameter for detrending (see article) [default: 300]
   --window=<int>            Moving window length [default: 23]
   -f, --framerate=<int>     Frame-rate of the video sequence [default: 61]
   --order=<int>             Bandpass filter order [default: 128]
@@ -37,13 +38,9 @@ Options:
 
 Examples:
 
-  To run the filters on the cohface database
+  To run the filters 
 
-    $ %(prog)s cohface -v
-
-  You can change the output directory using the `-o' flag:
-
-    $ %(prog)s hci -v -o /path/to/result/directory
+    $ %(prog)s config.py -v
 
 
 See '%(prog)s --help' for more information.
@@ -67,6 +64,8 @@ logger = bob.core.log.setup("bob.rppg.base")
 
 from docopt import docopt
 
+from bob.extension.config import load
+
 version = pkg_resources.require('bob.rppg.base')[0].version
 
 import numpy
@@ -75,6 +74,7 @@ import bob.io.base
 from ..filter_utils import detrend
 from ..filter_utils import average 
 from ...base.utils import build_bandpass_filter 
+from ...base.utils import get_parameter
 
 def main(user_input=None):
 
@@ -88,45 +88,33 @@ def main(user_input=None):
   completions = dict(prog=prog, version=version,)
   args = docopt(__doc__ % completions, argv=arguments, version='Filtering for signals (%s)' % version,)
 
+  # load configuration file
+  configuration = load([os.path.join(args['<configuration>'])])
+  
+  # get various parameters, either from config file or command-line 
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', '')
+  motiondir = get_parameter(args, configuration, 'motiondir', 'motion')
+  pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
+  Lambda = get_parameter(args, configuration, 'Lambda', 300)
+  window = get_parameter(args, configuration, 'window', 23)
+  framerate = get_parameter(args, configuration, 'framerate', 61)
+  order = get_parameter(args, configuration, 'order', 128)
+  overwrite = get_parameter(args, configuration, 'overwrite', False)
+  plot = get_parameter(args, configuration, 'plot', False)
+  gridcount = get_parameter(args, configuration, 'gridcount', False)
+  verbosity_level = get_parameter(args, configuration, 'verbose', 0)
+
   # if the user wants more verbosity, lowers the logging level
   from bob.core.log import set_verbosity_level
-  set_verbosity_level(logger, args['--verbose'])
+  set_verbosity_level(logger, verbosity_level)
  
-  # chooses the database driver to use
-  if args['cohface']:
-    import bob.db.cohface
-    if os.path.isdir(bob.db.cohface.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.cohface.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir']
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.cohface.Database(dbdir)
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'clean') or (args['--protocol'] == 'natural')):
-      logger.warning("Protocol should be either 'clean', 'natural' or 'all' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
-
-  elif args['hci']:
-    import bob.db.hci_tagging
-    import bob.db.hci_tagging.driver
-    if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir'] 
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.hci_tagging.Database()
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'cvpr14')):
-      logger.warning("Protocol should be either 'all' or 'cvpr14' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
+  # TODO: find a way to check protocol names - Guillaume HEUSCH, 22-06-2018
+  if hasattr(configuration, 'database'):
+    objects = configuration.database.objects(protocol, subset)
+  else:
+    logger.error("Please provide a database in your configuration file !")
+    sys.exit()
 
   # if we are on a grid environment, just find what I have to process.
   sge = False
@@ -141,12 +129,12 @@ def main(user_input=None):
       raise RuntimeError("Grid request for job {} on a setup with {} jobs".format(pos, len(objects)))
     objects = [objects[pos]]
 
-  if args['--gridcount']:
+  if gridcount:
     print(len(objects))
     sys.exit()
 
   # build the bandpass filter one and for all
-  b = build_bandpass_filter(float(args['--framerate']), int(args['--order']), bool(args['--plot']))
+  b = build_bandpass_filter(framerate, order, plot)
 
   ################
   ### LET'S GO ###
@@ -154,16 +142,16 @@ def main(user_input=None):
   for obj in objects:
 
     # expected output file
-    output = obj.make_path(args['--outdir'], '.hdf5')
+    output = obj.make_path(pulsedir, '.hdf5')
 
     # if output exists and not overwriting, skip this file
-    if os.path.exists(output) and not args['--overwrite']:
+    if os.path.exists(output) and not overwrite:
       logger.info("Skipping output file `%s': already exists, use --overwrite to force an overwrite", output)
       continue
 
     # load the corrected color signals of shape (3, nb_frames)
     logger.info("Filtering in signal from `%s'...", obj.path)
-    motion_file = obj.make_path(args['--indir'], '.hdf5')
+    motion_file = obj.make_path(motiondir, '.hdf5')
     try:
       motion_corrected_signal = bob.io.base.load(motion_file)
     except (IOError, RuntimeError) as e:
@@ -177,15 +165,15 @@ def main(user_input=None):
       continue
 
     # detrend
-    green_detrend = detrend(motion_corrected_signal, int(args['--lambda']))
+    green_detrend = detrend(motion_corrected_signal, Lambda)
     # average
-    green_averaged = average(green_detrend, int(args['--window']))
+    green_averaged = average(green_detrend, window)
     # bandpass
     from scipy.signal import filtfilt
     green_bandpassed = filtfilt(b, numpy.array([1]), green_averaged)
 
     # plot the result
-    if bool(args['--plot']):
+    if plot:
       from matplotlib import pyplot
       f, ax = pyplot.subplots(4, sharex=True)
       ax[0].plot(range(motion_corrected_signal.shape[0]), motion_corrected_signal, 'g')
@@ -201,8 +189,8 @@ def main(user_input=None):
     output_data = numpy.copy(green_bandpassed)
 
     # saves the data into an HDF5 file with a '.hdf5' extension
-    outdir = os.path.dirname(output)
-    if not os.path.exists(outdir): bob.io.base.create_directories_safe(outdir)
+    pulse_outdir = os.path.dirname(output)
+    if not os.path.exists(pulse_outdir): bob.io.base.create_directories_safe(pulse_outdir)
     bob.io.base.save(output_data, output)
     logger.info("Output file saved to `%s'...", output)
   
diff --git a/bob/rppg/cvpr14/script/illumination_rectification.py b/bob/rppg/cvpr14/script/illumination_rectification.py
index 25470a3..7053bbb 100644
--- a/bob/rppg/cvpr14/script/illumination_rectification.py
+++ b/bob/rppg/cvpr14/script/illumination_rectification.py
@@ -1,14 +1,15 @@
 #!/usr/bin/env python
 # encoding: utf-8
 
-"""Illumination rectification for database videos (%(version)s)
+"""Illumination rectification (%(version)s)
 
 Usage:
-  %(prog)s (cohface | hci) [--protocol=<string>] [--subset=<string> ...] 
-           [--verbose ...] [--plot]
-           [--facedir=<path>][--bgdir=<path>] [--outdir=<path>] 
+  %(prog)s <configuration>
+           [--protocol=<string>] [--subset=<string> ...] 
+           [--facedir=<path>][--bgdir=<path>] [--illumdir=<path>] 
            [--start=<int>] [--end=<int>] [--step=<float>] 
            [--length=<int>] [--overwrite] [--gridcount]
+           [--verbose ...] [--plot]
 
   %(prog)s (--help | -h)
   %(prog)s (--version | -V)
@@ -27,7 +28,7 @@ Options:
                             green color on the face region [default: face].
   -b, --bgdir=<path>        The path to the directory containing the average
                             green color on the background [default: background]
-  -o, --outdir=<path>       The path to the output directory where the resulting
+  -o, --illumdir=<path>       The path to the output directory where the resulting
                             corrected signal will be stored [default: illumination]
   -s, --start=<int>         Index of the starting frame [default: 0].
   -e, --end=<int>           Index of the ending frame. If set to zero, the
@@ -41,13 +42,9 @@ Options:
 
 Examples:
 
-  To run the illumination rectification on the hci database
-
-    $ %(prog)s hci -v
-
-  You can change the output directory using the `-o' flag:
+  To run the illumination rectification 
 
-    $ %(prog)s hci -v -o /path/to/result/directory
+    $ %(prog)s config.py -v
 
 
 See '%(prog)s --help' for more information.
@@ -65,11 +62,14 @@ logger = bob.core.log.setup("bob.rppg.base")
 
 from docopt import docopt
 
+from bob.extension.config import load
+
 version = pkg_resources.require('bob.rppg.base')[0].version
 
 import numpy
 import bob.io.base
 
+from ...base.utils import get_parameter
 from ..illum_utils import rectify_illumination
 
 def main(user_input=None):
@@ -84,46 +84,34 @@ def main(user_input=None):
   completions = dict(prog=prog, version=version,)
   args = docopt(__doc__ % completions, argv=arguments, version='Illumination rectification for videos (%s)' % version,)
 
+  # load configuration file
+  configuration = load([os.path.join(args['<configuration>'])])
+
+  # get various parameters, either from config file or command-line 
+  protocol = get_parameter(args, configuration, 'protocol', '')
+  subset = get_parameter(args, configuration, 'subset', 'all')
+  facedir = get_parameter(args, configuration, 'facedir', 'face')
+  bgdir = get_parameter(args, configuration, 'bgdir', 'bg')
+  illumdir = get_parameter(args, configuration, 'illumdir', 'illumination')
+  start = get_parameter(args, configuration, 'start', 0)
+  end = get_parameter(args, configuration, 'end', 0)
+  step = get_parameter(args, configuration, 'step', 0.05)
+  length = get_parameter(args, configuration, 'length', 1)
+  overwrite = get_parameter(args, configuration, 'overwrite', False)
+  plot = get_parameter(args, configuration, 'plot', False)
+  gridcount = get_parameter(args, configuration, 'gridcount', False)
+  verbosity_level = get_parameter(args, configuration, 'verbose', 0)
+
   # if the user wants more verbosity, lowers the logging level
   from bob.core.log import set_verbosity_level
-  set_verbosity_level(logger, args['--verbose'])
-
-  # chooses the database driver to use
-  if args['cohface']:
-    import bob.db.cohface
-    if os.path.isdir(bob.db.cohface.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.cohface.DATABASE_LOCATION
-    elif args['--facedir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--facedir']
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.cohface.Database(dbdir)
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'clean') or (args['--protocol'] == 'natural')):
-      logger.warning("Protocol should be either 'clean', 'natural' or 'all' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
-
-  elif args['hci']:
-    import bob.db.hci_tagging
-    import bob.db.hci_tagging.driver
-    if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
-    elif args['--facedir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--facedir'] 
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.hci_tagging.Database()
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'cvpr14')):
-      logger.warning("Protocol should be either 'all' or 'cvpr14' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
+  set_verbosity_level(logger, verbosity_level)
 
+  # TODO: find a way to check protocol names - Guillaume HEUSCH, 22-06-2018
+  if hasattr(configuration, 'database'):
+    objects = configuration.database.objects(protocol, subset)
+  else:
+    logger.error("Please provide a database in your configuration file !")
+    sys.exit()
 
   # if we are on a grid environment, just find what I have to process.
   sge = False
@@ -138,7 +126,7 @@ def main(user_input=None):
       raise RuntimeError("Grid request for job {} on a setup with {} jobs".format(pos, len(objects)))
     objects = [objects[pos]]
 
-  if args['--gridcount']:
+  if gridcount:
     print(len(objects))
     sys.exit()
 
@@ -148,16 +136,16 @@ def main(user_input=None):
   for obj in objects:
 
     # expected output file
-    output = obj.make_path(args['--outdir'], '.hdf5')
+    output = obj.make_path(illumdir, '.hdf5')
     logger.debug("expected output file -> {0}".format(output))
 
     # if output exists and not overwriting, skip this file
-    if os.path.exists(output) and not args['--overwrite']:
+    if os.path.exists(output) and not overwrite:
       logger.info("Skipping output file `%s': already exists, use --overwrite to force an overwrite", output)
       continue
 
     # load the color signal of the face
-    face_file = obj.make_path(args['--facedir'], '.hdf5')
+    face_file = obj.make_path(facedir, '.hdf5')
     try:
       face = bob.io.base.load(face_file)
     except (IOError, RuntimeError) as e:
@@ -165,7 +153,7 @@ def main(user_input=None):
       continue
 
     # load the color signal of the background
-    bg_file = obj.make_path(args['--bgdir'], '.hdf5')
+    bg_file = obj.make_path(bgdir, '.hdf5')
     try:
       bg = bob.io.base.load(bg_file)
     except (IOError, RuntimeError) as e:
@@ -174,8 +162,8 @@ def main(user_input=None):
 
     # indices where to start and to end the processing
     logger.debug("Sequence length = {0}".format(face.shape[0]))
-    start_index = int(args['--start'])
-    end_index = int(args['--end'])
+    start_index = start
+    end_index = end
     if (end_index == 0):
       end_index = face.shape[0]
     if end_index > face.shape[0]:
@@ -190,9 +178,9 @@ def main(user_input=None):
     logger.debug("Processing %d frames...", face.shape[0])
 
     # apply NLMS filtering
-    corrected_green = rectify_illumination(face, bg, float(args['--step']), int(args['--length']))
+    corrected_green = rectify_illumination(face, bg, step, length)
 
-    if bool(args['--plot']):
+    if plot:
       from matplotlib import pyplot
       f, axarr = pyplot.subplots(3, sharex=True)
       axarr[0].plot(range(face.shape[0]), face, 'g')
@@ -204,8 +192,8 @@ def main(user_input=None):
       pyplot.show()
 
     # saves the data into an HDF5 file with a '.hdf5' extension
-    outdir = os.path.dirname(output)
-    if not os.path.exists(outdir): bob.io.base.create_directories_safe(outdir)
+    outputdir = os.path.dirname(output)
+    if not os.path.exists(outputdir): bob.io.base.create_directories_safe(outputdir)
     bob.io.base.save(corrected_green, output)
     logger.info("Output file saved to `%s'...", output)
 
diff --git a/bob/rppg/cvpr14/script/motion_elimination.py b/bob/rppg/cvpr14/script/motion_elimination.py
index 374c76d..b0ad81b 100644
--- a/bob/rppg/cvpr14/script/motion_elimination.py
+++ b/bob/rppg/cvpr14/script/motion_elimination.py
@@ -1,11 +1,12 @@
 #!/usr/bin/env python
 # encoding: utf-8
 
-"""Non Rigid Motion Elimination for color signals (%(version)s)
+"""Non Rigid Motion Elimination (%(version)s)
 
 Usage:
-  %(prog)s (cohface | hci) [--protocol=<string>] [--subset=<string> ...] 
-           [--verbose ...] [--plot] [--indir=<path>] [--outdir=<path>]
+  %(prog)s <configuration>
+           [--protocol=<string>] [--subset=<string> ...] 
+           [--verbose ...] [--plot] [--illumdir=<path>] [--motiondir=<path>]
            [--seglength=<int>] [--save-threshold=<path>] [--load-threshold=<path>]
            [--cutoff=<float>] [--cvpr14] [--overwrite]
 
@@ -22,9 +23,9 @@ Options:
   -p, --protocol=<string>       Protocol [default: all].
   -s, --subset=<string>         Data subset to load. If nothing is provided 
                                 all the data sets will be loaded.
-  -i, --indir=<path>            The path to the saved illumination corrected signal
+  -i, --illumdir=<path>            The path to the saved illumination corrected signal
                                 on your disk [default: illumination].
-  -o, --outdir=<path>           The path to the output directory where the resulting
+  -o, --motiondir=<path>           The path to the output directory where the resulting
                                 motion corrected signals will be stored
                                 [default: motion].
   -L, --seglength=<int>         The length of the segments [default: 61]
@@ -43,17 +44,9 @@ Options:
 
 Examples:
 
-  To run the motion elimination for the cohface database
+  To run the motion elimination 
 
-    $ %(prog)s cohface -v
-
-  To just run a preliminary benchmark tests on the first 10 videos, do:
-
-    $ %(prog)s cohface -v -l 10
-
-  You can change the output directory using the `-o' flag:
-
-    $ %(prog)s hci -v -o /path/to/result/directory
+    $ %(prog)s config.py -v
 
 
 See '%(prog)s --help' for more information.
@@ -69,11 +62,14 @@ logger = bob.core.log.setup("bob.rppg.base")
 
 from docopt import docopt
 
+from bob.extension.config import load
+
 version = pkg_resources.require('bob.rppg.base')[0].version
 
 import numpy
 import bob.io.base
 
+from ...base.utils import get_parameter
 from ..motion_utils import build_segments
 from ..motion_utils import prune_segments 
 from ..motion_utils import build_final_signal 
@@ -91,55 +87,44 @@ def main(user_input=None):
   completions = dict(prog=prog, version=version,)
   args = docopt(__doc__ % completions, argv=arguments, version='Non-rigid motion elimination for videos (%s)' % version,)
 
+  # load configuration file
+  configuration = load([os.path.join(args['<configuration>'])])
+
+  # get various parameters, either from config file or command-line 
+  protocol = get_parameter(args, configuration, 'protocol', '')
+  subset = get_parameter(args, configuration, 'subset', 'all')
+  illumdir = get_parameter(args, configuration, 'illumdir', 'illumination')
+  motiondir = get_parameter(args, configuration, 'motiondir', 'motion')
+  seglength = get_parameter(args, configuration, 'seglength', 61)
+  cutoff = get_parameter(args, configuration, 'cutoff', 0.05)
+  save_threshold = get_parameter(args, configuration, 'save-threshold', 'threshold.txt')
+  load_threshold = get_parameter(args, configuration, 'load-threshold', '')
+  cvpr14 = get_parameter(args, configuration, 'cvpr14', False)
+  overwrite = get_parameter(args, configuration, 'overwrite', False)
+  plot = get_parameter(args, configuration, 'plot', False)
+  verbosity_level = get_parameter(args, configuration, 'verbose', 0)
+ 
+  print(load_threshold)
   # if the user wants more verbosity, lowers the logging level
   from bob.core.log import set_verbosity_level
   set_verbosity_level(logger, args['--verbose'])
 
-  # chooses the database driver to use
-  if args['cohface']:
-    import bob.db.cohface
-    if os.path.isdir(bob.db.cohface.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.cohface.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir']
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.cohface.Database(dbdir)
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'clean') or (args['--protocol'] == 'natural')):
-      logger.warning("Protocol should be either 'clean', 'natural' or 'all' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
-
-  elif args['hci']:
-    import bob.db.hci_tagging
-    import bob.db.hci_tagging.driver
-    if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir'] 
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.hci_tagging.Database()
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'cvpr14')):
-      logger.warning("Protocol should be either 'all' or 'cvpr14' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
+  # TODO: find a way to check protocol names - Guillaume HEUSCH, 22-06-2018
+  if hasattr(configuration, 'database'):
+    objects = configuration.database.objects(protocol, subset)
+  else:
+    logger.error("Please provide a database in your configuration file !")
+    sys.exit()
 
   # determine the threshold for the standard deviation to be applied to the segments
   # this part is not executed if a threshold is provided
-  if (args['--load-threshold']) == 'None':
+  if load_threshold == 'None':
     all_stds = []
     for obj in objects:
 
       # load the llumination corrected signal
       logger.debug("Computing standard deviations in color signals from `%s'...", obj.path)
-      illum_file = obj.make_path(args['--indir'], '.hdf5')
+      illum_file = obj.make_path(illumdir, '.hdf5')
       try:
         color = bob.io.base.load(illum_file)
       except (IOError, RuntimeError) as e:
@@ -152,7 +137,7 @@ def main(user_input=None):
         continue
       
       # get the standard deviation in the segments
-      green_segments, __ = build_segments(color, int(args['--seglength']))
+      green_segments, __ = build_segments(color, seglength)
       std_green = numpy.std(green_segments, 1, ddof=1)
       all_stds.extend(std_green.tolist())
 
@@ -160,34 +145,34 @@ def main(user_input=None):
 
     # sort the std and find the 5% at the top to get the threshold
     sorted_stds = sorted(all_stds, reverse=True)
-    cut_index = int(float(args['--cutoff']) * len(all_stds)) + 1
+    cut_index = int(cutoff * len(all_stds)) + 1
     threshold = sorted_stds[cut_index]
-    logger.info("The threshold was {0} (removing {1} percent of the largest segments)".format(threshold, 100*float(args['--cutoff'])))
+    logger.info("The threshold was {0} (removing {1} percent of the largest segments)".format(threshold, 100*cutoff))
 
     # write threshold to file
-    f = open(args['--save-threshold'], 'w')
+    f = open(save_threshold, 'w')
     f.write(str(threshold))
     f.close()
 
   else:
     # load threshold
-    f = open(args['--load-threshold'], 'r')
+    f = open(load_threshold, 'r')
     threshold = float(f.readline().rstrip())
 
     # cut segments where the std is too large
     for obj in objects:
 
       # expected output file
-      output = obj.make_path(args['--outdir'], '.hdf5')
+      output = obj.make_path(motiondir, '.hdf5')
 
       # if output exists and not overwriting, skip this file
-      if os.path.exists(output) and not args['--overwrite']:
+      if os.path.exists(output) and not overwrite:
         logger.info("Skipping output file `%s': already exists, use --overwrite to force an overwrite", output)
         continue
 
       # load the color signals
       logger.debug("Eliminating motion in color signals from `%s'...", obj.path)
-      illum_file = obj.make_path(args['--indir'], '.hdf5')
+      illum_file = obj.make_path(illumdir, '.hdf5')
       try:
         color = bob.io.base.load(illum_file)
       except (IOError, RuntimeError) as e:
@@ -201,7 +186,7 @@ def main(user_input=None):
         continue
 
       # divide the signals into segments
-      green_segments, end_index = build_segments(color, int(args['--seglength']))
+      green_segments, end_index = build_segments(color, seglength)
       # remove segments with high variability
       pruned_segments, gaps, cut_index = prune_segments(green_segments, threshold)
       
@@ -209,12 +194,12 @@ def main(user_input=None):
       if pruned_segments.shape[0] == 0:
         logger.warn("All segments have been discared in {0}".format(obj.path))
         continue
-      if bool(args['--cvpr14']):
+      if cvpr14:
         corrected_green = build_final_signal_cvpr14(pruned_segments, gaps)
       else:
         corrected_green = build_final_signal(pruned_segments, gaps)
      
-      if bool(args['--plot']):
+      if plot:
         from matplotlib import pyplot
         f, axarr = pyplot.subplots(2, sharex=True)
         axarr[0].plot(range(end_index), color[:end_index], 'g')
@@ -229,8 +214,8 @@ def main(user_input=None):
         pyplot.show()
 
       # saves the data into an HDF5 file with a '.hdf5' extension
-      outdir = os.path.dirname(output)
-      if not os.path.exists(outdir): bob.io.base.create_directories_safe(outdir)
+      outputdir = os.path.dirname(output)
+      if not os.path.exists(outputdir): bob.io.base.create_directories_safe(outputdir)
       bob.io.base.save(corrected_green, output)
       logger.info("Output file saved to `%s'...", output)
 
-- 
GitLab


From 99cfd1d9e3c6bfa420faf808064c3d6231cd955b Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Mon, 25 Jun 2018 16:52:01 +0200
Subject: [PATCH 05/22] [chrom] added config file as argument

---
 bob/rppg/chrom/script/extract_pulse.py        | 119 ++++----
 ...lses.py => extract_face_and_bg_signals.py} |   0
 bob/rppg/cvpr14/script/extract_signals.py     | 267 ------------------
 3 files changed, 57 insertions(+), 329 deletions(-)
 rename bob/rppg/cvpr14/script/{extract_pulses.py => extract_face_and_bg_signals.py} (100%)
 delete mode 100644 bob/rppg/cvpr14/script/extract_signals.py

diff --git a/bob/rppg/chrom/script/extract_pulse.py b/bob/rppg/chrom/script/extract_pulse.py
index dc0dbe4..cd0edbd 100644
--- a/bob/rppg/chrom/script/extract_pulse.py
+++ b/bob/rppg/chrom/script/extract_pulse.py
@@ -4,7 +4,8 @@
 """Pulse extraction using CHROM algorithm (%(version)s)
 
 Usage:
-  %(prog)s (cohface | hci) [--protocol=<string>] [--subset=<string> ...]
+  %(prog)s <configuration>
+           [--protocol=<string>] [--subset=<string> ...]
            [--dbdir=<path>] [--outdir=<path>]
            [--start=<int>] [--end=<int>] [--motion=<float>]
            [--threshold=<float>] [--skininit]
@@ -19,11 +20,11 @@ Usage:
 Options:
   -h, --help                Show this screen
   -V, --version             Show version
-  -p, --protocol=<string>   Protocol [default: all].
+  -p, --protocol=<string>   Protocol.
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
-  -d, --dbdir=<path>        The path to the database on your disk. If not set,
-                            defaults to Idiap standard locations.
+  -d, --dbdir=<path>        The path to the directory where video sequences are stored 
+                            from the face area will be stored [default: pulse]
   -o, --outdir=<path>       The path to the directory where signal extracted 
                             from the face area will be stored [default: pulse]
   --start=<int>             Starting frame index [default: 0].
@@ -48,9 +49,9 @@ Options:
 
 Example:
 
-  To run the pulse extraction for the cohface database
+  To run the pulse extraction 
 
-    $ %(prog)s cohface -v
+    $ %(prog)s config.py -v
 
 See '%(prog)s --help' for more information.
 
@@ -66,6 +67,9 @@ logger = setup("bob.rppg.base")
 
 from docopt import docopt
 
+from bob.extension.config import load
+from ...base.utils import get_parameter
+
 version = pkg_resources.require('bob.rppg.base')[0].version
 
 import numpy
@@ -93,45 +97,36 @@ def main(user_input=None):
   completions = dict(prog=prog, version=version,)
   args = docopt(__doc__ % completions, argv=arguments, version='Signal extractor for videos (%s)' % version,)
 
+  # load configuration file
+  configuration = load([os.path.join(args['<configuration>'])])
+  
+  # get various parameters, either from config file or command-line 
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', '')
+  outdir = get_parameter(args, configuration, 'outdir', 'pulse')
+  dbdir = get_parameter(args, configuration, 'dbdir', '')
+  start = get_parameter(args, configuration, 'start', 0)
+  end = get_parameter(args, configuration, 'end', 0)
+  motion = get_parameter(args, configuration, 'motion', 0.0)
+  threshold = get_parameter(args, configuration, 'threshold', 0.5)
+  skininit = get_parameter(args, configuration, 'skininit', False)
+  framerate = get_parameter(args, configuration, 'framerate', 61)
+  order = get_parameter(args, configuration, 'order', 128)
+  window = get_parameter(args, configuration, 'window', 0)
+  overwrite = get_parameter(args, configuration, 'overwrite', False)
+  plot = get_parameter(args, configuration, 'plot', False)
+  gridcount = get_parameter(args, configuration, 'gridcount', False)
+  verbosity_level = get_parameter(args, configuration, 'verbose', 0)
+  
   # if the user wants more verbosity, lowers the logging level
   from bob.core.log import set_verbosity_level
-  set_verbosity_level(logger, args['--verbose'])
-
-  # chooses the database driver to use
-  if args['cohface']:
-    import bob.db.cohface
-    if os.path.isdir(bob.db.cohface.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.cohface.DATABASE_LOCATION
-    elif args['--dbdir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--dbdir']
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.cohface.Database(dbdir)
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'clean') or (args['--protocol'] == 'natural')):
-      logger.warning("Protocol should be either 'clean', 'natural' or 'all' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
-
-  elif args['hci']:
-    import bob.db.hci_tagging
-    import bob.db.hci_tagging.driver
-    if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
-    elif args['--dbdir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--dbdir'] 
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.hci_tagging.Database()
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'cvpr14')):
-      logger.warning("Protocol should be either 'all' or 'cvpr14' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
+  set_verbosity_level(logger, verbosity_level)
+
+  if hasattr(configuration, 'database'):
+    objects = configuration.database.objects(protocol, subset)
+  else:
+    logger.error("Please provide a database in your configuration file !")
+    sys.exit()
 
   # if we are on a grid environment, just find what I have to process.
   sge = False
@@ -146,22 +141,22 @@ def main(user_input=None):
       raise RuntimeError("Grid request for job {} on a setup with {} jobs".format(pos, len(objects)))
     objects = [objects[pos]]
 
-  if args['--gridcount']:
+  if gridcount:
     print(len(objects))
     sys.exit()
 
   # build the bandpass filter one and for all
-  bandpass_filter = build_bandpass_filter(float(args['--framerate']), int(args['--order']), bool(args['--plot']))
+  bandpass_filter = build_bandpass_filter(framerate, order, plot)
 
   # does the actual work - for every video in the available dataset, 
   # extract the signals and dumps the results to the corresponding directory
   for obj in objects:
 
     # expected output file
-    output = obj.make_path(args['--outdir'], '.hdf5')
+    output = obj.make_path(outdir, '.hdf5')
 
     # if output exists and not overwriting, skip this file
-    if os.path.exists(output) and not args['--overwrite']:
+    if os.path.exists(output) and not overwrite:
       logger.info("Skipping output file `%s': already exists, use --overwrite to force an overwrite", output)
       continue
     
@@ -171,8 +166,8 @@ def main(user_input=None):
 
     # indices where to start and to end the processing
     logger.debug("Sequence length = {0}".format(len(video)))
-    start_index = int(args['--start'])
-    end_index = int(args['--end'])
+    start_index = start
+    end_index = end
     if (end_index == 0):
       end_index = len(video) 
     if end_index > len(video):
@@ -185,7 +180,7 @@ def main(user_input=None):
       nb_frames = end_index - start_index
 
     # the grayscale difference between two consecutive frames (for stable frame selection)
-    if bool(args['--motion']):
+    if motion:
       diff_motion = numpy.zeros((nb_frames-1, 1),  dtype='float64')
 
     # load the result of face detection
@@ -211,24 +206,24 @@ def main(user_input=None):
           bbox, quality = bob.ip.facedetect.detect_single_face(frame)
 
         # motion difference (if asked for)
-        if float(args['--motion']) > 0 and (i < (len(video) - 1)) and (counter > 0):
+        if motion > 0 and (i < (len(video) - 1)) and (counter > 0):
           current = crop_face(frame, bbox, bbox.size[1])
           diff_motion[counter-1] = compute_gray_diff(face, current)
         
         face = crop_face(frame, bbox, bbox.size[1])
 
-        if bool(args['--plot']) and args['--verbose'] >= 2:
+        if plot and verbosity_level >= 2:
           from matplotlib import pyplot
           pyplot.imshow(numpy.rollaxis(numpy.rollaxis(face, 2),2))
           pyplot.show()
 
         # skin filter
-        if counter == 0 or bool(args['--skininit']):
+        if counter == 0 or skininit:
           skin_filter.estimate_gaussian_parameters(face)
           logger.debug("Skin color parameters:\nmean\n{0}\ncovariance\n{1}".format(skin_filter.mean, skin_filter.covariance))
-        skin_mask = skin_filter.get_skin_mask(face, float(args['--threshold']))
+        skin_mask = skin_filter.get_skin_mask(face, threshold)
 
-        if bool(args['--plot']) and args['--verbose'] >= 2:
+        if plot and verbosity_level >= 2:
           from matplotlib import pyplot
           skin_mask_image = numpy.copy(face)
           skin_mask_image[:, skin_mask] = 255
@@ -260,14 +255,14 @@ def main(user_input=None):
         break
 
     # select the most stable number of consecutive frames, if asked for
-    if float(args['--motion']) > 0:
-      n_stable_frames_to_keep = int(float(args['--motion']) * nb_frames)
+    if motion > 0:
+      n_stable_frames_to_keep = int(motion * nb_frames)
       logger.info("Number of stable frames kept for motion -> {0}".format(n_stable_frames_to_keep))
       index = select_stable_frames(diff_motion, n_stable_frames_to_keep)
       logger.info("Stable segment -> {0} - {1}".format(index, index + n_stable_frames_to_keep))
       chrom = chrom[index:(index + n_stable_frames_to_keep),:]
 
-    if bool(args['--plot']):
+    if plot:
       from matplotlib import pyplot
       f, axarr = pyplot.subplots(2, sharex=True)
       axarr[0].plot(range(chrom.shape[0]), chrom[:, 0], 'k')
@@ -283,7 +278,7 @@ def main(user_input=None):
     x_bandpassed = filtfilt(bandpass_filter, numpy.array([1]), chrom[:, 0])
     y_bandpassed = filtfilt(bandpass_filter, numpy.array([1]), chrom[:, 1])
 
-    if bool(args['--plot']):
+    if plot:
       from matplotlib import pyplot
       f, axarr = pyplot.subplots(2, sharex=True)
       axarr[0].plot(range(x_bandpassed.shape[0]), x_bandpassed, 'k')
@@ -297,8 +292,8 @@ def main(user_input=None):
     pulse = x_bandpassed - alpha * y_bandpassed
 
     # overlap-add if window_size != 0
-    if int(args['--window']) > 0:
-      window_size = int(args['--window'])
+    if window > 0:
+      window_size = window
       window_stride = window_size / 2
       for w in range(0, (len(pulse)-window_size), window_stride):
         pulse[w:w+window_size] = 0.0
@@ -309,7 +304,7 @@ def main(user_input=None):
         sw *= numpy.hanning(window_size)
         pulse[w:w+window_size] += sw
     
-    if bool(args['--plot']):
+    if plot:
       from matplotlib import pyplot
       f, axarr = pyplot.subplots(1)
       pyplot.plot(range(pulse.shape[0]), pulse, 'k')
diff --git a/bob/rppg/cvpr14/script/extract_pulses.py b/bob/rppg/cvpr14/script/extract_face_and_bg_signals.py
similarity index 100%
rename from bob/rppg/cvpr14/script/extract_pulses.py
rename to bob/rppg/cvpr14/script/extract_face_and_bg_signals.py
diff --git a/bob/rppg/cvpr14/script/extract_signals.py b/bob/rppg/cvpr14/script/extract_signals.py
deleted file mode 100644
index 6b8bf5d..0000000
--- a/bob/rppg/cvpr14/script/extract_signals.py
+++ /dev/null
@@ -1,267 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-"""Extract mean green color on face and background regions
-
-Usage:
-  %(prog)s (cohface | hci) [--protocol=<string>] [--subset=<string> ...]
-           [--dbdir=<path>] [--facedir=<path>] [--bgdir=<path>] 
-           [--npoints=<int>] [--indent=<int>] [--quality=<float>] [--distance=<int>]
-           [--wholeface]
-           [--overwrite] [--verbose ...] [--plot] [--gridcount]
-
-  %(prog)s (--help | -h)
-  %(prog)s (--version | -V)
-
-
-Options:
-  -h, --help                Show this screen
-  -V, --version             Show version
-  -p, --protocol=<string>   Protocol [default: all].
-  -s, --subset=<string>     Data subset to load. If nothing is provided 
-                            all the data sets will be loaded.
-  -d, --dbdir=<path>        The path to the database on your disk. If not set,
-                            defaults to Idiap standard locations.
-  -f, --facedir=<path>      The path to the directory where signal extracted 
-                            from the face area will be stored [default: face]
-  -b, --bgdir=<path>        The path to the directory where signal extracted 
-                            from the background area will be stored [default: background]
-  -n, --npoints=<int>       Number of good features to track [default: 40]
-  -i, --indent=<int>        Indent (in percent of the face width) to apply to 
-                            keypoints to get the mask [default: 10]
-  -q, --quality=<float>     Quality level of the good features to track
-                            [default: 0.01]
-  -e, --distance=<int>      Minimum distance between detected good features to
-                            track [default: 10]
-  -O, --overwrite           By default, we don't overwrite existing files. The
-                            processing will skip those so as to go faster. If you
-                            still would like me to overwrite them, set this flag.
-  -v, --verbose             Increases the verbosity (may appear multiple times)
-  -P, --plot                Set this flag if you'd like to follow-up the algorithm
-                            execution graphically. We'll plot some interactions.
-  -g, --gridcount           Prints the number of objects to process and exits.
-  -w, --wholeface           Consider the whole face region instead of the mask.
-
-
-Example:
-
-  To run the signal extractor for the cohface database
-
-    $ %(prog)s cohface -v
-
-See '%(prog)s --help' for more information.
-
-"""
-
-from __future__ import print_function
-
-import os
-import sys
-import pkg_resources
-
-from bob.core.log import set_verbosity_level
-from bob.core.log import setup
-logger = setup("bob.rppg.base")
-
-from docopt import docopt
-
-version = pkg_resources.require('bob.rppg.base')[0].version
-
-import numpy
-import bob.io.base
-import bob.ip.facedetect
-
-from ...base.utils import crop_face
-
-from ..extract_utils import kp66_to_mask
-from ..extract_utils import get_good_features_to_track
-from ..extract_utils import track_features
-from ..extract_utils import find_transformation
-from ..extract_utils import get_current_mask_points
-from ..extract_utils import get_mask 
-from ..extract_utils import compute_average_colors_mask
-from ..extract_utils import compute_average_colors_wholeface
-
-def main(user_input=None):
-
-  # Parse the command-line arguments
-  if user_input is not None:
-      arguments = user_input
-  else:
-      arguments = sys.argv[1:]
-
-  prog = os.path.basename(sys.argv[0])
-  completions = dict(prog=prog, version=version,)
-  args = docopt(__doc__ % completions, argv=arguments, version='Signal extractor for videos (%s)' % version,)
-
-  # if the user wants more verbosity, lowers the logging level
-  set_verbosity_level(logger, args['--verbose'])
-
-  # TODO: change that to configuration file - Guillaume HEUSCH, 19-06-2018
-  
-  # chooses the database driver to use
-  if args['cohface']:
-    import bob.db.cohface
-    if os.path.isdir(bob.db.cohface.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.cohface.DATABASE_LOCATION
-    elif args['--dbdir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--dbdir']
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.cohface.Database(dbdir)
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'clean') or (args['--protocol'] == 'natural')):
-      logger.warning("Protocol should be either 'clean', 'natural' or 'all' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
-
-  elif args['hci']:
-    import bob.db.hci_tagging
-    import bob.db.hci_tagging.driver
-    if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
-    elif args['--dbdir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--dbdir'] 
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.hci_tagging.Database()
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'cvpr14')):
-      logger.warning("Protocol should be either 'all' or 'cvpr14' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
-
-  # if we are on a grid environment, just find what I have to process.
-  sge = False
-  try:
-    sge = os.environ.has_key('SGE_TASK_ID') # python2
-  except AttributeError:
-    sge = 'SGE_TASK_ID' in os.environ # python3
-    
-  if sge:
-    pos = int(os.environ['SGE_TASK_ID']) - 1
-    if pos >= len(objects):
-      raise RuntimeError("Grid request for job {} on a setup with {} jobs".format(pos, len(objects)))
-    objects = [objects[pos]]
-
-  if args['--gridcount']:
-    print(len(objects))
-    sys.exit()
-
-  # does the actual work - for every video in the available dataset, 
-  # extract the signals and dumps the results to the corresponding directory
-  for obj in objects:
-
-    # expected output file
-    output_face = obj.make_path(args['--facedir'], '.hdf5')
-    output_bg = obj.make_path(args['--bgdir'], '.hdf5')
-
-    # if output exists and not overwriting, skip this file
-    if (os.path.exists(output_face) and os.path.exists(output_bg)) and not args['--overwrite']:
-      logger.info("Skipping output file `%s': already exists, use --overwrite to force an overwrite", output_face)
-      continue
-    
-    # load video
-    video = obj.load_video(dbdir)
-    logger.info("Processing input video from `%s'...", video.filename)
-
-    # load the result of face detection
-    bounding_boxes = obj.load_face_detection() 
-
-    # average green color in the mask area  
-    face_color = numpy.zeros(len(video), dtype='float64')
-    # average green color in the background area
-    bg_color = numpy.zeros(len(video), dtype='float64')
-
-    # loop on video frames
-    for i, frame in enumerate(video):
-      logger.debug("Processing frame %d/%d...", i+1, len(video))
-
-      if i == 0:
-        # first frame:
-        # -> load the keypoints detected by DMRF
-        # -> infer the mask from the keypoints
-        # -> detect the face
-        # -> get "good features" inside the face
-        if not bool(args['--wholeface']):
-          kpts = obj.load_drmf_keypoints()
-          mask_points, mask = kp66_to_mask(frame, kpts, int(args['--indent']), bool(args['--plot']))
-
-        try: 
-          bbox = bounding_boxes[i]
-        except NameError:
-          bbox, quality = bob.ip.facedetect.detect_single_face(frame)
-        
-        # define the face width for the whole sequence
-        facewidth = bbox.size[1]
-        face = crop_face(frame, bbox, facewidth)
-        
-        if not bool(args['--wholeface']):
-          good_features = get_good_features_to_track(face,int(args['--npoints']), 
-              float(args['--quality']), int(args['--distance']), bool(args['--plot']))
-      else:
-        # subsequent frames:
-        # -> crop the face with the bounding_boxes of the previous frame (so
-        #    that faces are of the same size)
-        # -> get the projection of the corners detected in the previous frame
-        # -> find the (affine) transformation relating previous corners with
-        #    current corners
-        # -> apply this transformation to the mask
-        face = crop_face(frame, prev_bb, facewidth)
-        if not bool(args['--wholeface']):
-          good_features = track_features(prev_face, face, prev_features, bool(args['--plot']))
-          project = find_transformation(prev_features, good_features)
-          if project is None: 
-            logger.warn("Sequence {0}, frame {1} : No projection was found"
-                " between previous and current frame, mask from previous frame will be used"
-                .format(obj.path, i))
-          else:
-            mask_points = get_current_mask_points(mask_points, project)
-
-      # update stuff for the next frame:
-      # -> the previous face is the face in this frame, with its bbox (and not
-      #    with the previous one)
-      # -> the features to be tracked on the next frame are re-detected
-      try: 
-        prev_bb = bounding_boxes[i]
-      except NameError:
-        bb, quality = bob.ip.facedetect.detect_single_face(frame)
-        prev_bb = bb
-
-      
-      if not bool(args['--wholeface']):
-        prev_face = crop_face(frame, prev_bb, facewidth)
-        prev_features = get_good_features_to_track(face, int(args['--npoints']),
-            float(args['--quality']), int(args['--distance']),
-            bool(args['--plot']))
-        if prev_features is None:
-          logger.warn("Sequence {0}, frame {1} No features to track"  
-              " detected in the current frame, using the previous ones"
-              .format(obj.path, i))
-          prev_features = good_features
-
-        # get the bottom face region average colors
-        face_mask = get_mask(frame, mask_points)
-        face_color[i] = compute_average_colors_mask(frame, face_mask, bool(args['--plot']))
-      else:
-        face_color[i] = compute_average_colors_wholeface(face, bool(args['--plot']))
-
-      # get the background region average colors
-      bg_mask = numpy.zeros((frame.shape[1], frame.shape[2]), dtype=bool)
-      bg_mask[:100, :100] = True
-      bg_color[i] = compute_average_colors_mask(frame, bg_mask, bool(args['--plot']))
-
-    # saves the data into an HDF5 file with a '.hdf5' extension
-    out_facedir = os.path.dirname(output_face)
-    if not os.path.exists(out_facedir): bob.io.base.create_directories_safe(out_facedir)
-    bob.io.base.save(face_color, output_face)
-    logger.info("Output file saved to `%s'...", output_face)
-
-    out_bgdir = os.path.dirname(output_bg)
-    if not os.path.exists(out_bgdir): bob.io.base.create_directories_safe(out_bgdir)
-    bob.io.base.save(bg_color, output_bg)
-    logger.info("Output file saved to `%s'...", output_bg)
-- 
GitLab


From a591024303cdf36efa968ca3775f5e2da07667a8 Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Mon, 25 Jun 2018 16:52:43 +0200
Subject: [PATCH 06/22] [cvpr14] removed unecessary dbdir argument when
 extracting face and bg signals

---
 bob/rppg/cvpr14/script/extract_face_and_bg_signals.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bob/rppg/cvpr14/script/extract_face_and_bg_signals.py b/bob/rppg/cvpr14/script/extract_face_and_bg_signals.py
index 2d3794f..ecb6dcc 100644
--- a/bob/rppg/cvpr14/script/extract_face_and_bg_signals.py
+++ b/bob/rppg/cvpr14/script/extract_face_and_bg_signals.py
@@ -6,7 +6,7 @@
 Usage:
   %(prog)s <configuration>
            [--protocol=<string>] [--subset=<string> ...]
-           [--dbdir=<path>] [--facedir=<path>] [--bgdir=<path>] 
+           [--facedir=<path>] [--bgdir=<path>] 
            [--npoints=<int>] [--indent=<int>] [--quality=<float>] [--distance=<int>]
            [--wholeface] [--overwrite] [--verbose ...] [--plot] [--gridcount]
 
-- 
GitLab


From 862495243ef8086a0c853a7f6762b4c0f79dadd0 Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Tue, 26 Jun 2018 09:45:24 +0200
Subject: [PATCH 07/22] [utils] fixed the function to get parameters: priority
 given to command line

---
 bob/rppg/base/utils.py | 28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/bob/rppg/base/utils.py b/bob/rppg/base/utils.py
index 1a1d189..32a8e90 100644
--- a/bob/rppg/base/utils.py
+++ b/bob/rppg/base/utils.py
@@ -132,13 +132,29 @@ def get_parameter(args, configuration, keyword, default):
     The right value for the given keyword argument
 
   """
- 
+  
+  # get the keyword in a "docopt" friendly format
   args_kw = '--' + keyword.replace('_', '-')
+  
+  # get the type of this argument
   _type = type(default)
-  arg = _type(args[args_kw])
+
+  # get the default value 
+  arg_default = default 
+
+  # get the argument in the configuration file 
   if hasattr(configuration, keyword):
-    arg = getattr(configuration, keyword)
-  if _type(args[args_kw]) is not default and not hasattr(configuration, keyword):
-    arg = _type(args[args_kw])
-  return arg
+    arg_config = getattr(configuration, keyword)
+
+  # get the argument from the command-line
+  arg_command = _type(args[args_kw])
+ 
+  # if the argument was not specified in the config file
+  if not hasattr(configuration, keyword):
+    return arg_command
+  else:
+    if (arg_command == arg_default):
+      return arg_config
+    else:
+      return arg_command
 
-- 
GitLab


From efc3f0810211545bae414b06b1342dd5ce224cbe Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Tue, 26 Jun 2018 10:05:27 +0200
Subject: [PATCH 08/22] [cvpr14] fix issue with default protocol name

---
 bob/rppg/cvpr14/script/extract_face_and_bg_signals.py | 2 +-
 bob/rppg/cvpr14/script/filter.py                      | 4 ++--
 bob/rppg/cvpr14/script/illumination_rectification.py  | 4 ++--
 bob/rppg/cvpr14/script/motion_elimination.py          | 4 ++--
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/bob/rppg/cvpr14/script/extract_face_and_bg_signals.py b/bob/rppg/cvpr14/script/extract_face_and_bg_signals.py
index ecb6dcc..261906c 100644
--- a/bob/rppg/cvpr14/script/extract_face_and_bg_signals.py
+++ b/bob/rppg/cvpr14/script/extract_face_and_bg_signals.py
@@ -98,7 +98,7 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
   
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  protocol = get_parameter(args, configuration, 'protocol', 'None')
   subset = get_parameter(args, configuration, 'subset', '')
   facedir = get_parameter(args, configuration, 'facedir', 'face')
   bgdir = get_parameter(args, configuration, 'bgdir', 'bg')
diff --git a/bob/rppg/cvpr14/script/filter.py b/bob/rppg/cvpr14/script/filter.py
index 0b353bc..2bcd7cc 100644
--- a/bob/rppg/cvpr14/script/filter.py
+++ b/bob/rppg/cvpr14/script/filter.py
@@ -20,7 +20,7 @@ Options:
   -V, --version             Show version
   -P, --plot                Set this flag if you'd like to follow-up the algorithm
                             execution graphically. We'll plot some interactions.
-  -p, --protocol=<string>   Protocol [default: all].
+  -p, --protocol=<string>   Protocol.
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
   -i, --motiondir=<path>        The path to the saved signals to be filtered on
@@ -92,7 +92,7 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
   
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  protocol = get_parameter(args, configuration, 'protocol', 'None')
   subset = get_parameter(args, configuration, 'subset', '')
   motiondir = get_parameter(args, configuration, 'motiondir', 'motion')
   pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
diff --git a/bob/rppg/cvpr14/script/illumination_rectification.py b/bob/rppg/cvpr14/script/illumination_rectification.py
index 7053bbb..cecbe41 100644
--- a/bob/rppg/cvpr14/script/illumination_rectification.py
+++ b/bob/rppg/cvpr14/script/illumination_rectification.py
@@ -21,7 +21,7 @@ Options:
   -V, --version             Show version
   -P, --plot                Set this flag if you'd like to follow-up the algorithm
                             execution graphically. We'll plot some interactions.
-  -p, --protocol=<string>   Protocol [default: all].
+  -p, --protocol=<string>   Protocol.
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
   -f, --facedir=<path>      The path to the directory containing the average
@@ -88,7 +88,7 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
 
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', '')
+  protocol = get_parameter(args, configuration, 'protocol', 'None')
   subset = get_parameter(args, configuration, 'subset', 'all')
   facedir = get_parameter(args, configuration, 'facedir', 'face')
   bgdir = get_parameter(args, configuration, 'bgdir', 'bg')
diff --git a/bob/rppg/cvpr14/script/motion_elimination.py b/bob/rppg/cvpr14/script/motion_elimination.py
index b0ad81b..800af75 100644
--- a/bob/rppg/cvpr14/script/motion_elimination.py
+++ b/bob/rppg/cvpr14/script/motion_elimination.py
@@ -20,7 +20,7 @@ Options:
   -V, --version                 Show version
   -P, --plot                    Set this flag if you'd like to follow-up the algorithm
                                 execution graphically. We'll plot some interactions.
-  -p, --protocol=<string>       Protocol [default: all].
+  -p, --protocol=<string>       Protocol.
   -s, --subset=<string>         Data subset to load. If nothing is provided 
                                 all the data sets will be loaded.
   -i, --illumdir=<path>            The path to the saved illumination corrected signal
@@ -91,7 +91,7 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
 
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', '')
+  protocol = get_parameter(args, configuration, 'protocol', 'None')
   subset = get_parameter(args, configuration, 'subset', 'all')
   illumdir = get_parameter(args, configuration, 'illumdir', 'illumination')
   motiondir = get_parameter(args, configuration, 'motiondir', 'motion')
-- 
GitLab


From 89c9c8c8786419fbd78db0bc591c28f93fd622dc Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Tue, 26 Jun 2018 10:57:10 +0200
Subject: [PATCH 09/22] [chrom, base] fixed parameters / arguments names and
 default values

---
 bob/rppg/base/script/compute_performance.py | 10 +++++-----
 bob/rppg/base/script/frequency_analysis.py  | 15 ++++++--------
 bob/rppg/chrom/script/extract_pulse.py      | 22 ++++++++++-----------
 3 files changed, 22 insertions(+), 25 deletions(-)

diff --git a/bob/rppg/base/script/compute_performance.py b/bob/rppg/base/script/compute_performance.py
index b120996..687f926 100644
--- a/bob/rppg/base/script/compute_performance.py
+++ b/bob/rppg/base/script/compute_performance.py
@@ -18,12 +18,12 @@ Options:
   -V, --version             Show version
   -v, --verbose             Increases the verbosity (may appear multiple times)
   -P, --plot                Set this flag if you'd like to see some plots. 
-  -p, --protocol=<string>   Protocol [default: all].
+  -p, --protocol=<string>   Protocol.
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
-  -i, --hrdir=<path>        The path to the saved heart rate values on your disk. 
-  -o, --resultdir=<path>       The path to the output directory where the results
-                            will be stored [default: performances].
+  -i, --hrdir=<path>        The path to the saved heart rate values on your disk [default: hr]. 
+  -o, --resultdir=<path>    The path to the output directory where the results
+                            will be stored [default: results].
   -O, --overwrite           By default, we don't overwrite existing files. 
                             Set this flag if you want to overwrite existing files.
 
@@ -71,7 +71,7 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
 
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', '')
+  protocol = get_parameter(args, configuration, 'protocol', 'None')
   subset = get_parameter(args, configuration, 'subset', 'all')
   hrdir = get_parameter(args, configuration, 'hrdir', 'hr')
   resultdir = get_parameter(args, configuration, 'resultdir', 'results')
diff --git a/bob/rppg/base/script/frequency_analysis.py b/bob/rppg/base/script/frequency_analysis.py
index c564721..7a3a619 100644
--- a/bob/rppg/base/script/frequency_analysis.py
+++ b/bob/rppg/base/script/frequency_analysis.py
@@ -20,13 +20,13 @@ Options:
   -V, --version             Show version
   -P, --plot                Set this flag if you'd like to follow-up the algorithm
                             execution graphically. We'll plot some interactions.
-  -p, --protocol=<string>   Protocol [default: all].
+  -p, --protocol=<string>   Protocol.
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
-  -i, --pulsedir=<path>        The path to the saved filtered signals on your disk
-                            [default: filtered].
-  -o, --hrdir=<path>       The path to the output directory where the resulting
-                            color signals will be stored [default: heart-rate].
+  -i, --pulsedir=<path>     The path to the saved filtered signals on your disk
+                            [default: pulse].
+  -o, --hrdir=<path>        The path to the output directory where the resulting
+                            color signals will be stored [default: hr].
   -O, --overwrite           By default, we don't overwrite existing files. The
                             processing will skip those so as to go faster. If you
                             still would like me to overwrite them, set this flag.
@@ -83,7 +83,7 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
 
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', '')
+  protocol = get_parameter(args, configuration, 'protocol', 'None')
   subset = get_parameter(args, configuration, 'subset', 'all')
   pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
   hrdir = get_parameter(args, configuration, 'hrdir', 'hr')
@@ -93,9 +93,6 @@ def main(user_input=None):
   overwrite = get_parameter(args, configuration, 'overwrite', False)
   plot = get_parameter(args, configuration, 'plot', False)
   verbosity_level = get_parameter(args, configuration, 'verbose', 0)
- 
-  print(nsegments)
-  print(nfft)
 
   # if the user wants more verbosity, lowers the logging level
   from bob.core.log import set_verbosity_level
diff --git a/bob/rppg/chrom/script/extract_pulse.py b/bob/rppg/chrom/script/extract_pulse.py
index cd0edbd..45fd049 100644
--- a/bob/rppg/chrom/script/extract_pulse.py
+++ b/bob/rppg/chrom/script/extract_pulse.py
@@ -6,7 +6,7 @@
 Usage:
   %(prog)s <configuration>
            [--protocol=<string>] [--subset=<string> ...]
-           [--dbdir=<path>] [--outdir=<path>]
+           [--pulsedir=<path>]
            [--start=<int>] [--end=<int>] [--motion=<float>]
            [--threshold=<float>] [--skininit]
            [--framerate=<int>] [--order=<int>]
@@ -23,9 +23,7 @@ Options:
   -p, --protocol=<string>   Protocol.
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
-  -d, --dbdir=<path>        The path to the directory where video sequences are stored 
-                            from the face area will be stored [default: pulse]
-  -o, --outdir=<path>       The path to the directory where signal extracted 
+  -o, --pulsedir=<path>     The path to the directory where signal extracted 
                             from the face area will be stored [default: pulse]
   --start=<int>             Starting frame index [default: 0].
   --end=<int>               End frame index [default: 0].
@@ -99,12 +97,11 @@ def main(user_input=None):
 
   # load configuration file
   configuration = load([os.path.join(args['<configuration>'])])
-  
+ 
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  protocol = get_parameter(args, configuration, 'protocol', 'None')
   subset = get_parameter(args, configuration, 'subset', '')
-  outdir = get_parameter(args, configuration, 'outdir', 'pulse')
-  dbdir = get_parameter(args, configuration, 'dbdir', '')
+  pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
   start = get_parameter(args, configuration, 'start', 0)
   end = get_parameter(args, configuration, 'end', 0)
   motion = get_parameter(args, configuration, 'motion', 0.0)
@@ -117,12 +114,15 @@ def main(user_input=None):
   plot = get_parameter(args, configuration, 'plot', False)
   gridcount = get_parameter(args, configuration, 'gridcount', False)
   verbosity_level = get_parameter(args, configuration, 'verbose', 0)
-  
+ 
   # if the user wants more verbosity, lowers the logging level
   from bob.core.log import set_verbosity_level
   set_verbosity_level(logger, verbosity_level)
 
+  print(configuration.database)
   if hasattr(configuration, 'database'):
+    print(protocol)
+    print(subset)
     objects = configuration.database.objects(protocol, subset)
   else:
     logger.error("Please provide a database in your configuration file !")
@@ -153,7 +153,7 @@ def main(user_input=None):
   for obj in objects:
 
     # expected output file
-    output = obj.make_path(outdir, '.hdf5')
+    output = obj.make_path(pulsedir, '.hdf5')
 
     # if output exists and not overwriting, skip this file
     if os.path.exists(output) and not overwrite:
@@ -161,7 +161,7 @@ def main(user_input=None):
       continue
     
     # load video
-    video = obj.load_video(dbdir)
+    video = obj.load_video(configuration.dbdir)
     logger.info("Processing input video from `%s'...", video.filename)
 
     # indices where to start and to end the processing
-- 
GitLab


From 4479a26089ff115e77c3cfbff570f8720fcf20d7 Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Tue, 26 Jun 2018 10:58:01 +0200
Subject: [PATCH 10/22] [build] rename console scripts

---
 conda/meta.yaml | 2 +-
 setup.py        | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/conda/meta.yaml b/conda/meta.yaml
index 321013f..1132395 100644
--- a/conda/meta.yaml
+++ b/conda/meta.yaml
@@ -7,7 +7,7 @@ package:
 
 build:
   entry_points:
-    - cvpr14_extract_signals.py = bob.rppg.cvpr14.script.extract_signals:main
+    - cvpr14_extract_face_and_bg_signals.py = bob.rppg.cvpr14.script.extract_face_and_bg_signals:main
     - cvpr14_video2skin.py = bob.rppg.cvpr14.script.video2skin:main
     - cvpr14_illumination.py = bob.rppg.cvpr14.script.illumination_rectification:main
     - cvpr14_motion.py = bob.rppg.cvpr14.script.motion_elimination:main
diff --git a/setup.py b/setup.py
index 0867f42..f58e61b 100644
--- a/setup.py
+++ b/setup.py
@@ -32,8 +32,7 @@ setup(
 
   entry_points={
     'console_scripts': [
-      'cvpr14_extract_pulses.py = bob.rppg.cvpr14.script.extract_pulses:main',
-      'cvpr14_extract_signals.py = bob.rppg.cvpr14.script.extract_signals:main',
+      'cvpr14_extract_face_and_bg_signals.py = bob.rppg.cvpr14.script.extract_face_and_bg_signals:main',
       'cvpr14_video2skin.py = bob.rppg.cvpr14.script.video2skin:main',
       'cvpr14_illumination.py = bob.rppg.cvpr14.script.illumination_rectification:main',
       'cvpr14_motion.py = bob.rppg.cvpr14.script.motion_elimination:main',
@@ -43,7 +42,8 @@ setup(
       'ssr_pulse.py = bob.rppg.ssr.script.spatial_subspace_rotation:main',
       'ssr_pulse_from_mask.py = bob.rppg.ssr.script.ssr_from_mask:main',
       'rppg_get_heart_rate.py = bob.rppg.base.script.frequency_analysis:main',
-      'rppg_compute_performance.py = bob.rppg.base.script.compute_performance:main'
+      'rppg_compute_performance.py = bob.rppg.base.script.compute_performance:main',
+      'rppg_check_differences.py = bob.rppg.base.script.check_differences:main'
       ],
     },
 
-- 
GitLab


From 76160d43a459888be6c41318b923dffaefc43f7e Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Tue, 26 Jun 2018 11:40:05 +0200
Subject: [PATCH 11/22] [chrom] added configuration file to extract pulse from
 mask with CHROM

---
 bob/rppg/chrom/script/extract_pulse.py        |   3 -
 .../chrom/script/extract_pulse_from_mask.py   | 114 ++++++++----------
 2 files changed, 51 insertions(+), 66 deletions(-)

diff --git a/bob/rppg/chrom/script/extract_pulse.py b/bob/rppg/chrom/script/extract_pulse.py
index 45fd049..74d74c3 100644
--- a/bob/rppg/chrom/script/extract_pulse.py
+++ b/bob/rppg/chrom/script/extract_pulse.py
@@ -119,10 +119,7 @@ def main(user_input=None):
   from bob.core.log import set_verbosity_level
   set_verbosity_level(logger, verbosity_level)
 
-  print(configuration.database)
   if hasattr(configuration, 'database'):
-    print(protocol)
-    print(subset)
     objects = configuration.database.objects(protocol, subset)
   else:
     logger.error("Please provide a database in your configuration file !")
diff --git a/bob/rppg/chrom/script/extract_pulse_from_mask.py b/bob/rppg/chrom/script/extract_pulse_from_mask.py
index 0ae3748..6a25c4e 100644
--- a/bob/rppg/chrom/script/extract_pulse_from_mask.py
+++ b/bob/rppg/chrom/script/extract_pulse_from_mask.py
@@ -4,8 +4,9 @@
 """Pulse extraction using CHROM algorithm (%(version)s)
 
 Usage:
-  %(prog)s (cohface | hci) [--protocol=<string>] [--subset=<string> ...]
-           [--dbdir=<path>] [--pulsedir=<path>] 
+  %(prog)s <configuration>
+           [--protocol=<string>] [--subset=<string> ...]
+           [--pulsedir=<path>] 
            [--npoints=<int>] [--indent=<int>] [--quality=<float>] [--distance=<int>]
            [--framerate=<int>] [--order=<int>] [--window=<int>] 
            [--overwrite] [--verbose ...] [--plot] [--gridcount]
@@ -17,13 +18,11 @@ Usage:
 Options:
   -h, --help                Show this screen
   -V, --version             Show version
-  -p, --protocol=<string>   Protocol [default: all].
+  -p, --protocol=<string>   Protocol.
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
-  -d, --dbdir=<path>        The path to the database on your disk. If not set,
-                            defaults to Idiap standard locations.
-  -f, --pulsedir=<path>      The path to the directory where signal extracted 
-                            from the face area will be stored [default: face]
+  -o, --pulsedir=<path>     The path to the directory where signal extracted 
+                            from the face area will be stored [default: pulse].
   -n, --npoints=<int>       Number of good features to track [default: 40]
   -i, --indent=<int>        Indent (in percent of the face width) to apply to 
                             keypoints to get the mask [default: 10]
@@ -46,9 +45,9 @@ Options:
 
 Example:
 
-  To run the pulse extractor for the cohface database
+  To run the pulse extraction 
 
-    $ %(prog)s cohface -v
+    $ %(prog)s config.py -v
 
 See '%(prog)s --help' for more information.
 
@@ -64,6 +63,9 @@ logger = setup("bob.rppg.base")
 
 from docopt import docopt
 
+from bob.extension.config import load
+from ...base.utils import get_parameter
+
 version = pkg_resources.require('bob.rppg.base')[0].version
 
 import numpy
@@ -97,46 +99,35 @@ def main(user_input=None):
   completions = dict(prog=prog, version=version,)
   args = docopt(__doc__ % completions, argv=arguments, version='Signal extractor for videos (%s)' % version,)
 
+  # load configuration file
+  configuration = load([os.path.join(args['<configuration>'])])
+ 
+  # get various parameters, either from config file or command-line 
+  protocol = get_parameter(args, configuration, 'protocol', 'None')
+  subset = get_parameter(args, configuration, 'subset', '')
+  pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
+  npoints = get_parameter(args, configuration, 'npoints', 40)
+  indent = get_parameter(args, configuration, 'indent', 10)
+  quality = get_parameter(args, configuration, 'quality', 0.01)
+  distance = get_parameter(args, configuration, 'distance', 10)
+  framerate = get_parameter(args, configuration, 'framerate', 61)
+  order = get_parameter(args, configuration, 'order', 128)
+  window = get_parameter(args, configuration, 'window', 0)
+  overwrite = get_parameter(args, configuration, 'overwrite', False)
+  plot = get_parameter(args, configuration, 'plot', False)
+  gridcount = get_parameter(args, configuration, 'gridcount', False)
+  verbosity_level = get_parameter(args, configuration, 'verbose', 0)
+
   # if the user wants more verbosity, lowers the logging level
   from bob.core.log import set_verbosity_level
-  set_verbosity_level(logger, args['--verbose'])
-
-  # chooses the database driver to use
-  if args['cohface']:
-    import bob.db.cohface
-    if os.path.isdir(bob.db.cohface.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.cohface.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir']
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.cohface.Database(dbdir)
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'clean') or (args['--protocol'] == 'natural')):
-      logger.warning("Protocol should be either 'clean', 'natural' or 'all' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
-
-  elif args['hci']:
-    import bob.db.hci_tagging
-    import bob.db.hci_tagging.driver
-    if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir'] 
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.hci_tagging.Database()
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'cvpr14')):
-      logger.warning("Protocol should be either 'all' or 'cvpr14' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
+  set_verbosity_level(logger, verbosity_level)
 
+  if hasattr(configuration, 'database'):
+    objects = configuration.database.objects(protocol, subset)
+  else:
+    logger.error("Please provide a database in your configuration file !")
+    sys.exit()
+  
   # if we are on a grid environment, just find what I have to process.
   sge = False
   try:
@@ -150,27 +141,27 @@ def main(user_input=None):
       raise RuntimeError("Grid request for job {} on a setup with {} jobs".format(pos, len(objects)))
     objects = [objects[pos]]
 
-  if args['--gridcount']:
+  if gridcount:
     print(len(objects))
     sys.exit()
 
   # build the bandpass filter one and for all
-  bandpass_filter = build_bandpass_filter(float(args['--framerate']), int(args['--order']), bool(args['--plot']))
+  bandpass_filter = build_bandpass_filter(framerate, order, plot)
 
   # does the actual work - for every video in the available dataset, 
   # extract the signals and dumps the results to the corresponding directory
   for obj in objects:
 
     # expected output file
-    output = obj.make_path(args['--pulsedir'], '.hdf5')
+    output = obj.make_path(pulsedir, '.hdf5')
 
     # if output exists and not overwriting, skip this file
-    if (os.path.exists(output)) and not args['--overwrite']:
+    if (os.path.exists(output)) and not overwrite:
       logger.info("Skipping output file `%s': already exists, use --overwrite to force an overwrite", output)
       continue
     
     # load video
-    video = obj.load_video(dbdir)
+    video = obj.load_video(configuration.dbdir)
     logger.info("Processing input video from `%s'...", video.filename)
 
     # number of frames
@@ -194,7 +185,7 @@ def main(user_input=None):
         # -> detect the face
         # -> get "good features" inside the face
         kpts = obj.load_drmf_keypoints()
-        mask_points, mask = kp66_to_mask(frame, kpts, int(args['--indent']), bool(args['--plot']))
+        mask_points, mask = kp66_to_mask(frame, kpts, int(indent), plot)
 
         try: 
           bbox = bounding_boxes[i]
@@ -204,8 +195,7 @@ def main(user_input=None):
         # define the face width for the whole sequence
         facewidth = bbox.size[1]
         face = crop_face(frame, bbox, facewidth)
-        good_features = get_good_features_to_track(face,int(args['--npoints']), 
-            float(args['--quality']), int(args['--distance']), bool(args['--plot']))
+        good_features = get_good_features_to_track(face,npoints, quality, distance, plot)
       else:
         # subsequent frames:
         # -> crop the face with the bounding_boxes of the previous frame (so
@@ -215,7 +205,7 @@ def main(user_input=None):
         #    current corners
         # -> apply this transformation to the mask
         face = crop_face(frame, prev_bb, facewidth)
-        good_features = track_features(prev_face, face, prev_features, bool(args['--plot']))
+        good_features = track_features(prev_face, face, prev_features, plot)
         project = find_transformation(prev_features, good_features)
         if project is None: 
           logger.warn("Sequence {0}, frame {1} : No projection was found"
@@ -235,9 +225,7 @@ def main(user_input=None):
         prev_bb = bb
       
       prev_face = crop_face(frame, prev_bb, facewidth)
-      prev_features = get_good_features_to_track(face, int(args['--npoints']),
-        float(args['--quality']), int(args['--distance']),
-        bool(args['--plot']))
+      prev_features = get_good_features_to_track(face, npoints, quality, distance, plot)
       if prev_features is None:
         logger.warn("Sequence {0}, frame {1} No features to track"  
             " detected in the current frame, using the previous ones"
@@ -246,7 +234,7 @@ def main(user_input=None):
 
       # get the mask 
       face_mask = get_mask(frame, mask_points)
-      if bool(args['--plot']) and args['--verbose'] >= 2:
+      if plot and verbosity_level >= 2:
         from matplotlib import pyplot
         mask_image = numpy.copy(frame)
         mask_image[:, face_mask] = 255
@@ -267,7 +255,7 @@ def main(user_input=None):
     x_bandpassed = filtfilt(bandpass_filter, numpy.array([1]), chrom[:, 0])
     y_bandpassed = filtfilt(bandpass_filter, numpy.array([1]), chrom[:, 1])
 
-    if bool(args['--plot']):
+    if plot:
       from matplotlib import pyplot
       f, axarr = pyplot.subplots(2, sharex=True)
       axarr[0].plot(range(x_bandpassed.shape[0]), x_bandpassed, 'k')
@@ -281,8 +269,8 @@ def main(user_input=None):
     pulse = x_bandpassed - alpha * y_bandpassed
 
     # overlap-add if window_size != 0
-    if int(args['--window']) > 0:
-      window_size = int(args['--window'])
+    if int(window) > 0:
+      window_size = int(window)
       window_stride = window_size / 2
       for w in range(0, (len(pulse)-window_size), window_stride):
         pulse[w:w+window_size] = 0.0
@@ -293,7 +281,7 @@ def main(user_input=None):
         sw *= numpy.hanning(window_size)
         pulse[w:w+window_size] += sw
     
-    if bool(args['--plot']):
+    if plot:
       from matplotlib import pyplot
       f, axarr = pyplot.subplots(1)
       pyplot.plot(range(pulse.shape[0]), pulse, 'k')
-- 
GitLab


From 79ae1c3d4661736899551fc759a05534ee5eb640 Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Tue, 26 Jun 2018 13:36:59 +0200
Subject: [PATCH 12/22] [ssr] added configuration files for SSR scripts

---
 .../ssr/script/spatial_subspace_rotation.py   | 122 +++++++-----------
 bob/rppg/ssr/script/ssr_from_mask.py          | 113 +++++++---------
 2 files changed, 100 insertions(+), 135 deletions(-)

diff --git a/bob/rppg/ssr/script/spatial_subspace_rotation.py b/bob/rppg/ssr/script/spatial_subspace_rotation.py
index c74d23b..a9010a5 100644
--- a/bob/rppg/ssr/script/spatial_subspace_rotation.py
+++ b/bob/rppg/ssr/script/spatial_subspace_rotation.py
@@ -4,9 +4,10 @@
 """Pulse extraction using 2SR algorithm (%(version)s)
 
 Usage:
-  %(prog)s (cohface | hci) [--protocol=<string>] [--subset=<string> ...] 
+  %(prog)s <configuration>
+           [--protocol=<string>] [--subset=<string> ...] 
            [--verbose ...] [--plot]
-           [--dbdir=<path>] [--outdir=<path>]
+           [--pulsedir=<path>]
            [--threshold=<float>] [--skininit] 
            [--stride=<int>] [--start=<int>] [--end=<int>] 
            [--overwrite] [--gridcount]
@@ -21,12 +22,10 @@ Options:
   -V, --version             Show version
   -P, --plot                Set this flag if you'd like to follow-up the algorithm
                             execution graphically. We'll plot some interactions.
-  -p, --protocol=<string>   Protocol [default: all].
+  -p, --protocol=<string>   Protocol.
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
-  -D, --dbdir=<path>        The path to the database on your disk. If not set,
-                            defaults to Idiap standard locations.
-  -o, --outdir=<path>       The path to the output directory where the resulting
+  -o, --pulsedir=<path>       The path to the output directory where the resulting
                             pulse signal will be stored [default: pulse].
   --threshold=<float>       Threshold on the skin probability map [default: 0.5].
   --skininit                If you want to reinitialize the skin model at each frame.
@@ -42,13 +41,9 @@ Options:
 
 Examples:
 
-  To run the spatial subspace rotation on the hci database
+  To run the spatial subspace rotation algorithm
 
-    $ %(prog)s hci -v
-
-  You can change the output directory using the `-o' flag:
-
-    $ %(prog)s hci -v -o /path/to/result/directory
+    $ %(prog)s config.py -v
 
 
 See '%(prog)s --help' for more information.
@@ -65,6 +60,9 @@ logger = setup("bob.rppg.base")
 
 from docopt import docopt
 
+from bob.extension.config import load
+from ...base.utils import get_parameter
+
 version = pkg_resources.require('bob.rppg.base')[0].version
 
 import numpy
@@ -89,45 +87,32 @@ def main(user_input=None):
   completions = dict(prog=prog, version=version,)
   args = docopt(__doc__ % completions, argv=arguments, version='Signal extractor for videos (%s)' % version,)
 
+  # load configuration file
+  configuration = load([os.path.join(args['<configuration>'])])
+ 
+  # get various parameters, either from config file or command-line 
+  protocol = get_parameter(args, configuration, 'protocol', 'None')
+  subset = get_parameter(args, configuration, 'subset', '')
+  pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
+  start = get_parameter(args, configuration, 'start', 0)
+  end = get_parameter(args, configuration, 'end', 0)
+  threshold = get_parameter(args, configuration, 'threshold', 0.5)
+  skininit = get_parameter(args, configuration, 'skininit', False)
+  stride = get_parameter(args, configuration, 'stride', 61)
+  overwrite = get_parameter(args, configuration, 'overwrite', False)
+  plot = get_parameter(args, configuration, 'plot', False)
+  gridcount = get_parameter(args, configuration, 'gridcount', False)
+  verbosity_level = get_parameter(args, configuration, 'verbose', 0)
+
   # if the user wants more verbosity, lowers the logging level
   from bob.core.log import set_verbosity_level
-  set_verbosity_level(logger, args['--verbose'])
-
-  # chooses the database driver to use
-  if args['cohface']:
-    import bob.db.cohface
-    if os.path.isdir(bob.db.cohface.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.cohface.DATABASE_LOCATION
-    elif args['--dbdir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--dbdir']
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.cohface.Database(dbdir)
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'clean') or (args['--protocol'] == 'natural')):
-      logger.warning("Protocol should be either 'clean', 'natural' or 'all' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
-
-  elif args['hci']:
-    import bob.db.hci_tagging
-    import bob.db.hci_tagging.driver
-    if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
-    elif args['--dbdir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--dbdir'] 
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.hci_tagging.Database()
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'cvpr14')):
-      logger.warning("Protocol should be either 'all' or 'cvpr14' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
+  set_verbosity_level(logger, verbosity_level)
+
+  if hasattr(configuration, 'database'):
+    objects = configuration.database.objects(protocol, subset)
+  else:
+    logger.error("Please provide a database in your configuration file !")
+    sys.exit()
 
   # if we are on a grid environment, just find what I have to process.
   sge = False
@@ -142,28 +127,28 @@ def main(user_input=None):
       raise RuntimeError("Grid request for job {} on a setup with {} jobs".format(pos, len(objects)))
     objects = [objects[pos]]
 
-  if args['--gridcount']:
+  if gridcount:
     print(len(objects))
 
   # does the actual work 
   for obj in objects:
 
     # expected output file
-    output = obj.make_path(args['--outdir'], '.hdf5')
+    output = obj.make_path(pulsedir, '.hdf5')
 
     # if output exists and not overwriting, skip this file
-    if os.path.exists(output) and not args['--overwrite']:
+    if os.path.exists(output) and not overwrite:
       logger.info("Skipping output file `%s': already exists, use --overwrite to force an overwrite", output)
       continue
 
     # load the video sequence into a reader
-    video = obj.load_video(dbdir)
+    video = obj.load_video(configuration.dbdir)
     logger.info("Processing input video from `%s'...", video.filename)
 
     # indices where to start and to end the processing
     logger.debug("Sequence length = {0}".format(len(video)))
-    start_index = int(args['--start'])
-    end_index = int(args['--end'])
+    start_index = int(start)
+    end_index = int(end)
     if (end_index == 0):
       end_index = len(video) 
     if end_index > len(video):
@@ -178,7 +163,7 @@ def main(user_input=None):
     bounding_boxes = obj.load_face_detection()
 
     # the temporal stride
-    temporal_stride = int(args['--stride'])
+    temporal_stride = int(stride)
 
     # the result -> the pulse signal 
     output_data = numpy.zeros(nb_final_frames, dtype='float64')
@@ -201,18 +186,14 @@ def main(user_input=None):
         try:
           if counter == 0:
             # init skin parameters in any cases if it's the first frame
-            skin_pixels = get_skin_pixels(frame, i, 
-               True, float(args['--threshold']), bounding_boxes)
+            skin_pixels = get_skin_pixels(frame, i, True, threshold, bounding_boxes)
           else:
-            skin_pixels = get_skin_pixels(frame, i, 
-               bool(args['--skininit']), float(args['--threshold']), bounding_boxes)
+            skin_pixels = get_skin_pixels(frame, i, skininit, threshold, bounding_boxes)
         except NameError:
           if counter == 0:
-            skin_pixels = get_skin_pixels(frame, i, 
-               bool(args['--skininit']), float(args['--threshold']))
+            skin_pixels = get_skin_pixels(frame, i, skininit, threshold)
           else:
-            skin_pixels = get_skin_pixels(frame, i, 
-               bool(args['--skininit']), float(args['--threshold']))
+            skin_pixels = get_skin_pixels(frame, i, skininit, threshold)
         logger.debug("There are {0} skin pixels in this frame".format(skin_pixels.shape[1]))
         
         # no skin pixels detected, generally due to no face detection
@@ -223,11 +204,9 @@ def main(user_input=None):
           while skin_pixels.shape[1] <= 0:
             
             try:
-              skin_pixels = get_skin_pixels(video[i-k], (i-k),  
-                 bool(args['--skininit']), float(args['--threshold']), bounding_boxes, skin_frame=frame)
+              skin_pixels = get_skin_pixels(video[i-k], (i-k),  skininit, threshold, bounding_boxes, skin_frame=frame)
             except NameError:
-              skin_pixels = get_skin_pixels(video[i-k], (i-k), 
-                 bool(args['--skininit']), float(args['--threshold']), skin_frame=frame)
+              skin_pixels = get_skin_pixels(video[i-k], (i-k), skininit, threshold, skin_frame=frame)
             
             k += 1
           logger.warn("got skin pixels in frame {0}".format(i-k))
@@ -235,15 +214,14 @@ def main(user_input=None):
         # build c matrix and get eigenvectors and eigenvalues
         eigenvalues[:, counter], eigenvectors[:, :, counter] = get_eigen(skin_pixels)
 
-
         # plot the cluster of skin pixels and eigenvectors (see Figure 1) 
-        if bool(args['--plot'])  and args['--verbose'] >= 2:
+        if plot  and verbosity_level >= 2:
           plot_eigenvectors(skin_pixels, eigenvectors[:, :, counter])
 
         # build P and add it to the pulse signal
         if counter >= temporal_stride:
           tau = counter - temporal_stride
-          p = build_P(counter, int(args['--stride']), eigenvectors, eigenvalues)
+          p = build_P(counter, stride, eigenvectors, eigenvalues)
           output_data[tau:counter] += (p - numpy.mean(p)) 
          
         counter += 1
@@ -252,7 +230,7 @@ def main(user_input=None):
         break
 
     # plot the pulse signal
-    if bool(args['--plot']):
+    if plot:
       import matplotlib.pyplot as plt
       fig = plt.figure()
       ax = fig.add_subplot(111)
diff --git a/bob/rppg/ssr/script/ssr_from_mask.py b/bob/rppg/ssr/script/ssr_from_mask.py
index 944926a..4e3eeb5 100644
--- a/bob/rppg/ssr/script/ssr_from_mask.py
+++ b/bob/rppg/ssr/script/ssr_from_mask.py
@@ -4,8 +4,9 @@
 """Pulse extractor using 2SR algorithm (%(version)s)
 
 Usage:
-  %(prog)s (cohface | hci) [--protocol=<string>] [--subset=<string> ...]
-           [--dbdir=<path>] [--pulsedir=<path>] 
+  %(prog)s <configuration>
+           [--protocol=<string>] [--subset=<string> ...] 
+           [--pulsedir=<path>] 
            [--npoints=<int>] [--indent=<int>] [--quality=<float>] [--distance=<int>]
            [--stride=<int>] 
            [--overwrite] [--verbose ...] [--plot] [--gridcount]
@@ -17,13 +18,11 @@ Usage:
 Options:
   -h, --help                Show this screen
   -V, --version             Show version
-  -p, --protocol=<string>   Protocol [default: all].
+  -p, --protocol=<string>   Protocol.
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
-  -d, --dbdir=<path>        The path to the database on your disk. If not set,
-                            defaults to Idiap standard locations.
   -o, --pulsedir=<path>     The path to the directory where signal extracted 
-                            from the face area will be stored [default: face]
+                            from the face area will be stored [default: pulse]
   -n, --npoints=<int>       Number of good features to track [default: 40]
   -i, --indent=<int>        Indent (in percent of the face width) to apply to 
                             keypoints to get the mask [default: 10]
@@ -31,7 +30,7 @@ Options:
                             [default: 0.01]
   -e, --distance=<int>      Minimum distance between detected good features to
                             track [default: 10]
-  --stride=<int>            Temporal stride [default: 20]
+  --stride=<int>            Temporal stride [default: 61]
   -O, --overwrite           By default, we don't overwrite existing files. The
                             processing will skip those so as to go faster. If you
                             still would like me to overwrite them, set this flag.
@@ -43,9 +42,10 @@ Options:
 
 Example:
 
-  To run the pulse extractor for the cohface database
+  To run the spatial subspace rotation algorithm
+
+    $ %(prog)s config.py -v
 
-    $ %(prog)s cohface -v
 
 See '%(prog)s --help' for more information.
 
@@ -61,6 +61,9 @@ logger = setup("bob.rppg.base")
 
 from docopt import docopt
 
+from bob.extension.config import load
+from ...base.utils import get_parameter
+
 version = pkg_resources.require('bob.rppg.base')[0].version
 
 import numpy
@@ -94,46 +97,34 @@ def main(user_input=None):
   completions = dict(prog=prog, version=version,)
   args = docopt(__doc__ % completions, argv=arguments, version='Signal extractor for videos (%s)' % version,)
 
+
+  # load configuration file
+  configuration = load([os.path.join(args['<configuration>'])])
+ 
+  # get various parameters, either from config file or command-line 
+  protocol = get_parameter(args, configuration, 'protocol', 'None')
+  subset = get_parameter(args, configuration, 'subset', '')
+  pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
+  npoints = get_parameter(args, configuration, 'npoints', 40)
+  indent = get_parameter(args, configuration, 'indent', 10)
+  quality = get_parameter(args, configuration, 'quality', 0.01)
+  distance = get_parameter(args, configuration, 'distance', 10)
+  stride = get_parameter(args, configuration, 'stride', 61)
+  overwrite = get_parameter(args, configuration, 'overwrite', False)
+  plot = get_parameter(args, configuration, 'plot', False)
+  gridcount = get_parameter(args, configuration, 'gridcount', False)
+  verbosity_level = get_parameter(args, configuration, 'verbose', 0)
+
   # if the user wants more verbosity, lowers the logging level
   from bob.core.log import set_verbosity_level
-  set_verbosity_level(logger, args['--verbose'])
-
-  # chooses the database driver to use
-  if args['cohface']:
-    import bob.db.cohface
-    if os.path.isdir(bob.db.cohface.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.cohface.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir']
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.cohface.Database(dbdir)
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'clean') or (args['--protocol'] == 'natural')):
-      logger.warning("Protocol should be either 'clean', 'natural' or 'all' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
-
-  elif args['hci']:
-    import bob.db.hci_tagging
-    import bob.db.hci_tagging.driver
-    if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir'] 
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.hci_tagging.Database()
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'cvpr14')):
-      logger.warning("Protocol should be either 'all' or 'cvpr14' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
+  set_verbosity_level(logger, verbosity_level)
 
+  if hasattr(configuration, 'database'):
+    objects = configuration.database.objects(protocol, subset)
+  else:
+    logger.error("Please provide a database in your configuration file !")
+    sys.exit()
+  
   # if we are on a grid environment, just find what I have to process.
   sge = False
   try:
@@ -147,26 +138,26 @@ def main(user_input=None):
       raise RuntimeError("Grid request for job {} on a setup with {} jobs".format(pos, len(objects)))
     objects = [objects[pos]]
 
-  if args['--gridcount']:
+  if gridcount:
     print(len(objects))
 
   # the temporal stride
-  temporal_stride = int(args['--stride'])
+  temporal_stride = stride
 
   # does the actual work - for every video in the available dataset, 
   # extract the signals and dumps the results to the corresponding directory
   for obj in objects:
 
     # expected output file
-    output = obj.make_path(args['--pulsedir'], '.hdf5')
+    output = obj.make_path(pulsedir, '.hdf5')
 
     # if output exists and not overwriting, skip this file
-    if (os.path.exists(output)) and not args['--overwrite']:
+    if (os.path.exists(output)) and not overwrite:
       logger.info("Skipping output file `%s': already exists, use --overwrite to force an overwrite", output)
       continue
     
     # load video
-    video = obj.load_video(dbdir)
+    video = obj.load_video(configuration.dbdir)
     logger.info("Processing input video from `%s'...", video.filename)
     nb_final_frames = len(video)
 
@@ -191,7 +182,7 @@ def main(user_input=None):
         # -> detect the face
         # -> get "good features" inside the face
         kpts = obj.load_drmf_keypoints()
-        mask_points, mask = kp66_to_mask(frame, kpts, int(args['--indent']), bool(args['--plot']))
+        mask_points, mask = kp66_to_mask(frame, kpts, indent, plot)
 
         try: 
           bbox = bounding_boxes[i]
@@ -201,9 +192,7 @@ def main(user_input=None):
         # define the face width for the whole sequence
         facewidth = bbox.size[1]
         face = crop_face(frame, bbox, facewidth)
-        
-        good_features = get_good_features_to_track(face,int(args['--npoints']), 
-            float(args['--quality']), int(args['--distance']), bool(args['--plot']))
+        good_features = get_good_features_to_track(face,npoints, quality, distance, plot)
       else:
         # subsequent frames:
         # -> crop the face with the bounding_boxes of the previous frame (so
@@ -213,7 +202,7 @@ def main(user_input=None):
         #    current corners
         # -> apply this transformation to the mask
         face = crop_face(frame, prev_bb, facewidth)
-        good_features = track_features(prev_face, face, prev_features, bool(args['--plot']))
+        good_features = track_features(prev_face, face, prev_features, plot)
         project = find_transformation(prev_features, good_features)
         if project is None: 
           logger.warn("Sequence {0}, frame {1} : No projection was found"
@@ -234,9 +223,7 @@ def main(user_input=None):
 
       
       prev_face = crop_face(frame, prev_bb, facewidth)
-      prev_features = get_good_features_to_track(face, int(args['--npoints']),
-          float(args['--quality']), int(args['--distance']),
-          bool(args['--plot']))
+      prev_features = get_good_features_to_track(face, npoints, quality, distance, plot)
       if prev_features is None:
         logger.warn("Sequence {0}, frame {1} No features to track"  
             " detected in the current frame, using the previous ones"
@@ -246,7 +233,7 @@ def main(user_input=None):
       # get the bottom face region
       face_mask = get_mask(frame, mask_points)
 
-      if bool(args['--plot']):
+      if plot:
         from matplotlib import pyplot
         mask_image = numpy.copy(frame)
         mask_image[:, face_mask] = 255
@@ -262,17 +249,17 @@ def main(user_input=None):
       eigenvalues[:, i], eigenvectors[:, :, i] = get_eigen(skin_pixels)
 
       # plot the cluster of skin pixels and eigenvectors (see Figure 1) 
-      if bool(args['--plot'])  and args['--verbose'] >= 2:
+      if plot and verbosity_level >= 2:
         plot_eigenvectors(skin_pixels, eigenvectors[:, :, i])
 
       # build P and add it to the pulse signal
       if i >= temporal_stride:
         tau = i - temporal_stride
-        p = build_P(i, int(args['--stride']), eigenvectors, eigenvalues)
+        p = build_P(i, int(stride), eigenvectors, eigenvalues)
         output_data[tau:i] += (p - numpy.mean(p)) 
         
     # plot the pulse signal
-    if bool(args['--plot']):
+    if plot:
       import matplotlib.pyplot as plt
       fig = plt.figure()
       ax = fig.add_subplot(111)
-- 
GitLab


From 12ba5f59450bd6bec27664c1d3cc7844438bbcf1 Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Tue, 26 Jun 2018 14:49:01 +0200
Subject: [PATCH 13/22] [doc] updated user guides to reflect the changes made
 with the usage of configuration files

---
 doc/guide_chrom.rst                           |  46 ++++++-
 doc/guide_cvpr14.rst                          | 123 +++++++++++++++---
 doc/guide_ssr.rst                             |  50 ++++++-
 doc/index.rst                                 |   9 +-
 scripts-article/README.rst                    |  35 -----
 .../chrom-cohface-clean-natural.py            |  64 ---------
 scripts-article/chrom-cohface-clean.py        |  65 ---------
 .../chrom-cohface-complete-face.py            |  65 ---------
 .../chrom-cohface-complete-mask.py            |  68 ----------
 .../chrom-cohface-complete-skin.py            |  65 ---------
 scripts-article/chrom-hci-cvpr14.py           |  63 ---------
 scripts-article/chrom-hci-protocols.py        |  65 ---------
 scripts-article/chrom-xdb-cohface-hci.py      |  64 ---------
 scripts-article/chrom-xdb-hci-cohface.py      |  63 ---------
 scripts-article/li-cohface-clean-natural.py   |  97 --------------
 scripts-article/li-cohface-clean.py           |  97 --------------
 scripts-article/li-cohface-complete-face.py   |  92 -------------
 scripts-article/li-cohface-complete-mask.py   |  97 --------------
 scripts-article/li-cohface-complete-skin.py   |  94 -------------
 scripts-article/li-hci-cvpr14.py              |  96 --------------
 scripts-article/li-hci-protocols.py           |  97 --------------
 scripts-article/li-xdb-cohface-hci.py         |  96 --------------
 scripts-article/li-xdb-hci-cohface.py         |  96 --------------
 scripts-article/ssr-cohface-clean-natural.py  |  62 ---------
 scripts-article/ssr-cohface-clean.py          |  63 ---------
 scripts-article/ssr-cohface-complete-face.py  |  62 ---------
 scripts-article/ssr-cohface-complete-mask.py  |  67 ----------
 scripts-article/ssr-cohface-complete-skin.py  |  64 ---------
 scripts-article/ssr-hci-cvpr14.py             |  61 ---------
 scripts-article/ssr-hci-protocols.py          |  63 ---------
 scripts-article/ssr-xdb-cohface-hci.py        |  62 ---------
 scripts-article/ssr-xdb-hci-cohface.py        |  61 ---------
 32 files changed, 196 insertions(+), 2076 deletions(-)
 delete mode 100644 scripts-article/README.rst
 delete mode 100644 scripts-article/chrom-cohface-clean-natural.py
 delete mode 100644 scripts-article/chrom-cohface-clean.py
 delete mode 100644 scripts-article/chrom-cohface-complete-face.py
 delete mode 100644 scripts-article/chrom-cohface-complete-mask.py
 delete mode 100644 scripts-article/chrom-cohface-complete-skin.py
 delete mode 100644 scripts-article/chrom-hci-cvpr14.py
 delete mode 100644 scripts-article/chrom-hci-protocols.py
 delete mode 100644 scripts-article/chrom-xdb-cohface-hci.py
 delete mode 100644 scripts-article/chrom-xdb-hci-cohface.py
 delete mode 100644 scripts-article/li-cohface-clean-natural.py
 delete mode 100644 scripts-article/li-cohface-clean.py
 delete mode 100644 scripts-article/li-cohface-complete-face.py
 delete mode 100644 scripts-article/li-cohface-complete-mask.py
 delete mode 100644 scripts-article/li-cohface-complete-skin.py
 delete mode 100644 scripts-article/li-hci-cvpr14.py
 delete mode 100644 scripts-article/li-hci-protocols.py
 delete mode 100644 scripts-article/li-xdb-cohface-hci.py
 delete mode 100644 scripts-article/li-xdb-hci-cohface.py
 delete mode 100644 scripts-article/ssr-cohface-clean-natural.py
 delete mode 100644 scripts-article/ssr-cohface-clean.py
 delete mode 100644 scripts-article/ssr-cohface-complete-face.py
 delete mode 100644 scripts-article/ssr-cohface-complete-mask.py
 delete mode 100644 scripts-article/ssr-cohface-complete-skin.py
 delete mode 100644 scripts-article/ssr-hci-cvpr14.py
 delete mode 100644 scripts-article/ssr-hci-protocols.py
 delete mode 100644 scripts-article/ssr-xdb-cohface-hci.py
 delete mode 100644 scripts-article/ssr-xdb-hci-cohface.py

diff --git a/doc/guide_chrom.rst b/doc/guide_chrom.rst
index 076c777..e616258 100644
--- a/doc/guide_chrom.rst
+++ b/doc/guide_chrom.rst
@@ -39,17 +39,55 @@ The mean skin color value is then computed, and projected onto the XY chrominanc
 colorspace. The signals in this colorspace are filtered using a bandpass filter
 before the final pulse signal is built.
 
-
 To extract the pulse signal from video sequences, do the following::
 
-  $ ./bin/chrom_pulse.py cohface -vv
+  $ ./bin/chrom_pulse.py config.py -vv
 
 To see the full options, including parameters and protocols, type:: 
 
   $ ./bin/chrom_pulse.py --help 
 
-The output of this step normally goes into a directory (you can override on
-the options for this application) named ``pulse``.
+As you can see, the script takes a configuration file as argument. This
+configuration file is required to at least specify the database, but can also
+be used to provide various parameters. A full example of configuration is
+given below.
+
+.. code-block:: python
+
+  import os, sys
+
+  # DATABASE
+  import bob.db.hci_tagging
+  import bob.db.hci_tagging.driver
+  if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
+    dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
+  if dbdir == '':
+    print("You should provide a directory where the DB is located")
+    sys.exit()
+  database = bob.db.hci_tagging.Database()
+  protocol = 'cvpr14'
+  framerate = 61
+
+  basedir = 'chrom-hci-cvpr14/'
+
+  # EXTRACT PULSE 
+  pulsedir = basedir + 'pulse'
+  start = 306
+  end = 2136
+  motion = 0
+  threshold = 0.1
+  skininit = True
+  order = 128
+  window = 0
+
+  # FREQUENCY ANALYSIS
+  hrdir = basedir + 'hr'
+  nsegments = 12
+  nfft = 2048
+
+  # RESULTS
+  resultdir = basedir + 'results'
+
 
 .. note::
 
diff --git a/doc/guide_cvpr14.rst b/doc/guide_cvpr14.rst
index 4278ec7..9a23cd2 100644
--- a/doc/guide_cvpr14.rst
+++ b/doc/guide_cvpr14.rst
@@ -22,37 +22,65 @@ The algorithm to retrieve the pulse signal can be divided into several steps:
   3. Eliminating non-rigid motion.
   4. Filtering
 
+All the scripts rely on the usage of a configuration file, which specify the
+database interface, the path where the raw data (i.e. video sequences) are stored
+and various parameters.
+
+Below you can find a (minmal) example of a configuration file.
+
+.. code-block:: python
+
+  import os, sys
+  import bob.db.hci_tagging
+  import bob.db.hci_tagging.driver
+
+  if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
+    dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
+
+  if dbdir == '':
+    print("You should provide a directory where the DB is located")
+    sys.exit()
+
+  database = bob.db.hci_tagging.Database()
+  protocol = 'cvpr14'
+
+As you can see, here you should **at least** have the `database` and 
+the `dbdir` parameters set.
+
 
 Step 1: Extract signals from video sequences
 --------------------------------------------
 
 This scripts first load previously detected facial keypoints to build the mask 
 covering the bottom region of the face (note that the keypoints are not
-provided, but could be obtained using bob.ip.flandmark for instance). Once the
+provided, but could be obtained using `bob.ip.dlib
+<https://gitlab.idiap.ch/bob/bob.ip.dlib>`_ for instance. Once the
 mask has been built, it is tracked across the whole sequence using the
 methodology described in [li-cvpr-2014]_. The face is 
 detected using :py:func:`bob.ip.facedetect.detect_single_face`, and the
-tracking makes usage of openCV (version 2). 
+tracking makes usage of OpenCV. 
 
 To extract the mean green colors the face region and of
-the background across the video sequences of the COHFACE 
-database, do the following::
+the background across the video sequences of the defined database 
+in the configuration file, do the following::
 
-  $ ./bin/cvpr14_extract_signals.py cohface -vv
+  $ ./bin/cvpr14_extract_face_and_bg_signals.py config.py -vv
 
 To see the full options, including parameters and protocols, type:: 
 
-  $ ./bin/cvpr14_extract_signals.py --help 
+  $ ./bin/cvpr14_extract_face_and_bg_signals.py --help 
 
-The output of this step normally goes into directories (you can override on
-the options for this application) named ``face`` and ``background``.
+Note that you can either pass parameters through command-line, or 
+by specififing them in the configuration file. Be aware that
+the command-line overrides the configuration file though.
 
 .. note::
 
    The execution of this script is very slow - mainly due to the face detection. 
-   You can speed it up using the gridtk_ (especially, if you're at Idiap). For example::
+   You can speed it up using the gridtk_ toolbox (especially, if you're at Idiap). 
+   For example::
 
-     $ ./bin/jman sub -t 3490 -- ./bin/cvpr14_extract_signals.py cohface
+     $ ./bin/jman sub -t 3490 -- ./bin/cvpr14_extract_face_and_bg_signals. config.py
 
    The number of jobs (i.e. 3490) is given by typing::
      
@@ -68,10 +96,10 @@ Normalized Linear Mean Square and is then removed from the face signal. To get
 the rectified green signal of the face area, you should execute the following
 script::
 
-  $ ./bin/cvpr14_illumination.py cohface -v
+  $ ./bin/cvpr14_illumination.py config.py -v
 
-This script takes as input the result directories (normally named) ``face`` and
-``background`` and outputs data to a directory named ``illumination``.
+Again, parameters can be passed either through the configuration file or
+the command-line
 
 
 Step 3: Non rigid Motion Elimination
@@ -88,11 +116,6 @@ been eliminated, execute the following commands::
   $ ./bin/cvpr14_motion.py cohface --save-threshold threshold.txt -vv
   $ ./bin/cvpr14_motion.py cohface --load-threshold threshold.txt -vv
 
-This script takes as input the result directory (normally named)
-``illumination`` and outputs data to a directory called
-``motion``. The first call computes the threshold while the second
-one actually discards segments and builds the corrected signals.
-
 
 Step 4: Filtering
 -----------------
@@ -108,8 +131,68 @@ signal, you should execute the following command::
 
   $ ./bin/cvpr14_filter.py cohface -vv
 
-This script normally takes data from a directory called ``motion-eliminated``
-and outputs data to a directory called ``filtered``.
+A Full Configuration File Example
+---------------------------------
+
+.. note::
+
+   This configuration file can (and probably should) be used with all the 
+   scripts mentioned above
+
+.. code-block:: python
+
+  import os, sys
+
+  import bob.db.hci_tagging
+  import bob.db.hci_tagging.driver
+
+  # DATABASE
+  if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
+    dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
+  if dbdir == '':
+    print("You should provide a directory where the DB is located")
+    sys.exit()
+  database = bob.db.hci_tagging.Database()
+  protocol = 'cvpr14'
+
+  basedir = 'li-hci-cvpr14/'
+
+  # EXTRACT FACE AND BACKGROUND
+  facedir = basedir + 'face'
+  bgdir = basedir + 'bg'
+  npoints = 200
+  indent = 10 
+  quality = 0.01
+  distance = 10
+  verbose = 2
+
+  # ILLUMINATION CORRECTION
+  illumdir = basedir + 'illumination'
+  start = 306
+  end = 2136
+  step = 0.05
+  length = 3
+
+  # MOTION ELIMINATION
+  motiondir = basedir + 'motion'
+  seglength = 61
+  cutoff = 0.05
+
+  # FILTERING
+  pulsedir = basedir + 'pulse'
+  Lambda = 300
+  window = 21
+  framerate = 61
+  order = 128
+
+  # FREQUENCY ANALYSIS
+  hrdir = basedir + 'hr'
+  nsegments = 16
+  nfft = 8192
+
+  # RESULTS
+  resultdir = basedir + 'results'
+
 
 .. _gridtk: https://pypi.python.org/pypi/gridtk
 
diff --git a/doc/guide_ssr.rst b/doc/guide_ssr.rst
index c3f5269..b993a26 100644
--- a/doc/guide_ssr.rst
+++ b/doc/guide_ssr.rst
@@ -33,13 +33,53 @@ from each frame image. Hence, a skin color filter (:py:mod:`bob.ip.skincolorfilt
 is applied to retrieve a mask containing skin pixels.
 
 After having applied the skin color filter, the full algorithm is applied,
-as described in Algorithm 1 in the paper. To get the pulse signal, do
-the following::
+as described in Algorithm 1 in the paper. To get the pulse signals for
+all video in a database, do the following::
 
-  $ ./bin/ssr_pulse.py cohface
+  $ ./bin/ssr_pulse.py config.py -v
 
-The result of this script will be the pulse signal. 
-The output of this step normally goes into a directory named ``pulse``.
+To see the full options, including parameters and protocols, type:: 
+
+  $ ./bin/ssr_pulse.py --help 
+
+As you can see, the script takes a configuration file as argument. This
+configuration file is required to at least specify the database, but can also
+be used to provide various parameters. A full example of configuration is
+given below.
+
+.. code-block:: python
+
+  import os, sys
+  import bob.db.hci_tagging
+  import bob.db.hci_tagging.driver
+
+  if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
+    dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
+
+  if dbdir == '':
+    print("You should provide a directory where the DB is located")
+    sys.exit()
+
+  database = bob.db.hci_tagging.Database()
+  protocol = 'cvpr14'
+
+  basedir = 'ssr-hci-cvpr14/'
+
+  # EXTRACT PULSE 
+  pulsedir = basedir + 'pulse'
+  start = 306
+  end = 2136
+  threshold = 0.1
+  skininit = True
+  stride = 30
+
+  # FREQUENCY ANALYSIS
+  hrdir = basedir + 'hr'
+  nsegments = 8
+  nfft = 4096
+
+  # RESULTS
+  resultdir = basedir + 'results'
 
 .. note::
 
diff --git a/doc/index.rst b/doc/index.rst
index 7138c4a..c027caa 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -19,12 +19,15 @@ This module contains the implementation of different remote photoplesthymography
   * 2SR [wang-tbe-2015]_. 
 
 Also, we provide scripts to infer the heart-rate from the pulse signals, and
-to evaluate global performance on two different databases: Manhob HCI-Tagging 
-(http://mahnob-db.eu/hci-tagging/) and COHFACE (http://www.idiap.ch/dataset/cohface).
+to evaluate global performance on a database.
+
+Note that this package was first meant to be used with the Manhob HCI-Tagging 
+(http://mahnob-db.eu/hci-tagging/) and COHFACE (http://www.idiap.ch/dataset/cohface)
+databases, but could easily be extended to other datasets.
 
 .. warning:: 
   
-   You should download the databases before trying to run anything below!
+   You should download the aforementioned databases before trying to run anything below!
 
 Documentation
 -------------
diff --git a/scripts-article/README.rst b/scripts-article/README.rst
deleted file mode 100644
index 7c0ae97..0000000
--- a/scripts-article/README.rst
+++ /dev/null
@@ -1,35 +0,0 @@
-Scripts for generating article results
---------------------------------------
-
-In this folder, you can find the scripts that have been used to generate the
-results in the article. They assume that the path to the database is either
-'hci' or 'cohface' in the package root folder (this could be a symlink
-though)::
-
-  chrom-cohface-clean-natural.py          --> Table 7 column 2
-  chrom-cohface-clean.py                  --> Table 5, line 2
-  chrom-cohface-complete-face.py          --> Table 8, column 1, line 2
-  chrom-cohface-complete-mask.py          --> Table 8, column 3, line 2
-  chrom-cohface-complete-skin.py          --> Table 8, column 2, line 2
-  chrom-hci-cvpr14.py                     --> Table 2, column 2
-  chrom-hci-protocols.py                  --> Table 4, line 2
-  chrom-xdb-cohface-hci.py                --> Table 6, line 2, column 2
-  chrom-xdb-hci-cohface.py                --> Table 6, line 1, column 2
-  li-cohface-clean-natural.py             --> Table 7, column 1
-  li-cohface-clean.py                     --> Table 5, line 1
-  li-cohface-complete-mask.py             --> Table 8, line 1, column 3
-  li-cohface-complete-skin.py             --> Table 8, line 1, column 2
-  li-cohface-complete-wholeface.py        --> Table 8, line 1, column 1
-  li-hci-cvpr14.py                        --> Table 2, column 1
-  li-hci-protocols.py                     --> Table 4, line 1
-  li-xdb-cohface-hci.py                   --> Table 6, column 1, line 2
-  li-xdb-hci-cohface.py                   --> Table 6, column 1, line 1
-  ssr-cohface-clean-natural.py            --> Table 7, column 3
-  ssr-cohface-clean.py                    --> Table 5, line 3
-  ssr-hci-cvpr14.py                       --> Table 2, column 3
-  ssr-hci-protocols.py                    --> Table 4, line 3
-  ssr-xdb-cohface-hci.py                  --> Table 6, column 3, line 2
-  ssr-xdb-hci-cohface.py                  --> Table 6, column 3, line 1
-  ssr-cohface-complete-face.py            --> Table 8, line 3, column 1
-  ssr-cohface-complete-skin.py            --> Table 8, line 3, column 2
-  ssr-cohface-complete-mask.py            --> Table 8, line 3, column 3
diff --git a/scripts-article/chrom-cohface-clean-natural.py b/scripts-article/chrom-cohface-clean-natural.py
deleted file mode 100644
index de63b1a..0000000
--- a/scripts-article/chrom-cohface-clean-natural.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/chrom-cohface-clean-natural/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-skin_threshold = 0.2
-order = 32
-window = 0
-
-n_segments = 8
-nfft = 1024
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('window = ' + str(window) + '\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'chrom_pulse.py cohface --protocol natural --subset test --dbdir cohface --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --framerate ' + str(framerate) + ' --window ' + str(window) + ' --skininit -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --protocol natural --subset test --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py cohface --protocol natural --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/chrom-cohface-clean.py b/scripts-article/chrom-cohface-clean.py
deleted file mode 100644
index c3d5a97..0000000
--- a/scripts-article/chrom-cohface-clean.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join('experiments/paper/chrom-cohface-clean/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-skin_threshold = 0.2
-order = 32
-window = 0
-
-n_segments = 8
-nfft = 1024
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('window = ' + str(window) + '\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'chrom_pulse.py cohface --protocol clean --dbdir cohface --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --framerate ' + str(framerate) + ' --window ' + str(window) + ' --skininit -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --protocol clean --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py cohface --protocol clean --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py cohface --protocol clean --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/chrom-cohface-complete-face.py b/scripts-article/chrom-cohface-complete-face.py
deleted file mode 100644
index 0529e2c..0000000
--- a/scripts-article/chrom-cohface-complete-face.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join('experiments/paper/chrom-cohface-complete-face/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-skin_threshold = 0.0
-
-# parameters
-order = 128
-window = 0
-
-n_segments = 8
-nfft = 512
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('window = ' + str(window) + '\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'chrom_pulse.py cohface --dbdir cohface --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --framerate ' + str(framerate) + ' --order ' + str(order) + ' --window ' + str(window) + ' -v')
- 
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py cohface --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py cohface --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/chrom-cohface-complete-mask.py b/scripts-article/chrom-cohface-complete-mask.py
deleted file mode 100644
index 41df251..0000000
--- a/scripts-article/chrom-cohface-complete-mask.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/chrom-cohface-complete-mask/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-npoints = 40
-indent = 15
-
-order = 128
-window = 256
-
-n_segments = 8
-nfft = 512
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('npoints = ' + str(npoints) + '\n\n')
-f.write('indent = ' + str(indent) + '\n\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('window = ' + str(window) + '\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'chrom_pulse_from_mask.py cohface --dbdir cohface --pulsedir ' + str(pulse_dir) + ' --framerate ' + str(framerate) + ' --npoints ' + str(npoints) + ' --indent ' + str(indent) + ' --order ' + str(order) + ' --window ' + str(window) + ' -v')
- 
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py cohface --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py cohface --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/chrom-cohface-complete-skin.py b/scripts-article/chrom-cohface-complete-skin.py
deleted file mode 100644
index 1d4bff4..0000000
--- a/scripts-article/chrom-cohface-complete-skin.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join('experiments/paper/chrom-cohface-complete-skin/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-skin_threshold = 0.3
-order = 64
-window = 0
-
-n_segments = 8
-nfft = 512
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('window = ' + str(window) + '\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'chrom_pulse.py cohface --dbdir cohface --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --framerate ' + str(framerate) + ' --order ' + str(order) + ' --window ' + str(window) + ' -v')
- 
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py cohface --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py cohface --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/chrom-hci-cvpr14.py b/scripts-article/chrom-hci-cvpr14.py
deleted file mode 100644
index a3a9aeb..0000000
--- a/scripts-article/chrom-hci-cvpr14.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/chrom-hci-cvpr14/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir = base_expe_dir + 'results'
-
-framerate = 61
-
-# parameters
-skin_threshold = 0.1
-order = 32
-window = 0 
-
-n_segments = 12
-nfft = 2048
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('window = ' + str(window) + '\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'chrom_pulse.py hci --protocol cvpr14 --dbdir hci --bboxdir bounding-boxes --outdir ' + str(pulse_dir) + ' --start 306 --end 2136 --threshold ' + str(skin_threshold) + ' --framerate ' + str(framerate) + ' --window ' + str(window) + ' --skininit -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py hci --protocol cvpr14 --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  hci --protocol cvpr14 --indir ' + hr_dir + ' --outdir ' + results_dir + ' -v')
diff --git a/scripts-article/chrom-hci-protocols.py b/scripts-article/chrom-hci-protocols.py
deleted file mode 100644
index fada777..0000000
--- a/scripts-article/chrom-hci-protocols.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/chrom-hci-protocols/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 61
-
-# parameters
-skin_threshold = 0.3
-order = 32
-window = 32 
-
-n_segments = 8
-nfft = 4096
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('window = ' + str(window) + '\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'chrom_pulse.py hci --dbdir hci --bboxdir bounding-boxes --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --framerate ' + str(framerate) + ' --window ' + str(window) + ' --skininit -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py hci --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  hci --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py  hci --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/chrom-xdb-cohface-hci.py b/scripts-article/chrom-xdb-cohface-hci.py
deleted file mode 100644
index 8e5cdf3..0000000
--- a/scripts-article/chrom-xdb-cohface-hci.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/chrom-xdb-cohface-hci/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 61
-
-# parameters
-skin_threshold = 0.2
-order = 32
-window = 0
-
-n_segments = 8
-nfft = 1024
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('window = ' + str(window) + '\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'chrom_pulse.py hci --subset test --dbdir hci --bboxdir bounding-boxes --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --framerate ' + str(framerate) + ' --window ' + str(window) + ' --skininit -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py hci --subset test --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py hci --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/chrom-xdb-hci-cohface.py b/scripts-article/chrom-xdb-hci-cohface.py
deleted file mode 100644
index 2adc4e6..0000000
--- a/scripts-article/chrom-xdb-hci-cohface.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/chrom-xdb-hci-cohface/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-skin_threshold = 0.3
-order = 32
-window = 32 
-
-n_segments = 8
-nfft = 4096
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('window = ' + str(window) + '\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'chrom_pulse.py cohface --protocol clean --subset test --dbdir cohface --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --framerate ' + str(framerate) + ' --window ' + str(window) + ' --skininit -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --protocol clean --subset test --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  cohface --protocol clean --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/li-cohface-clean-natural.py b/scripts-article/li-cohface-clean-natural.py
deleted file mode 100644
index 093f27b..0000000
--- a/scripts-article/li-cohface-clean-natural.py
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-### WARNING ###
-# be sure to first run li-cohface-clean.py to get the threshold file
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/li-cohface-clean-natural/')
-facedir = base_expe_dir + 'face'
-bgdir = base_expe_dir + 'bg'
-illumination_dir = base_expe_dir + 'illumination'
-motion_dir = base_expe_dir + 'motion'
-filtered_dir = base_expe_dir + 'filtered'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-npoints = 100 
-indent = 10
-
-adaptation = 0.01
-filter_length = 5
-
-segment_length = 40
-cutoff = 0.02
-threshold_file = 'experiments/paper/li-cohface-clean/illumination/threshold.txt'
-
-Lambda = 300
-window = 3
-order = 32
-
-n_segments = 4
-nfft = 4096
-
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('npoints = ' + str(npoints) + '\n')
-f.write('indent [%] = ' + str(indent) + '\n\n')
-f.write('adaptation step = ' + str(adaptation) + '\n')
-f.write('filter length = ' + str(filter_length) + '\n\n')
-f.write('segment length [frames] = ' + str(segment_length) + '\n')
-f.write('cutoff [% / 100] = ' + str(cutoff) + '\n\n')
-f.write('lambda = ' + str(Lambda) + '\n')
-f.write('window = ' + str(window) + '\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# signals extraction
-os.system(bin_folder + 'cvpr14_extract_signals.py cohface --protocol natural --subset test --dbdir cohface --facedir ' + str(facedir) + ' --bgdir ' + str(bgdir) + ' --npoints ' + str(npoints) + ' --indent ' + str(indent) + ' -v')
-
-# illumination correction
-os.system(bin_folder + 'cvpr14_illumination.py cohface --protocol natural --subset test --facedir ' + facedir + ' --bgdir ' + bgdir + ' --outdir ' + illumination_dir + ' --step ' + str(adaptation) + ' --length ' + str(filter_length) + ' -v')
-
-# motion elimination -> remove segments
-os.system(bin_folder + 'cvpr14_motion.py cohface --protocol natural --subset test --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength ' + str(segment_length) + ' --cutoff ' +str(cutoff) + ' --load-threshold ' + threshold_file + ' -v')
-
-# filtering
-os.system(bin_folder + 'cvpr14_filter.py cohface --protocol natural --subset test --indir ' + motion_dir + ' --outdir ' + filtered_dir + ' --lambda ' + str(Lambda) + ' --window ' + str(window) + ' --order ' + str(order) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --protocol natural --subset test --indir ' + filtered_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  cohface --protocol natural --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/li-cohface-clean.py b/scripts-article/li-cohface-clean.py
deleted file mode 100644
index d91e56a..0000000
--- a/scripts-article/li-cohface-clean.py
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/li-cohface-clean/')
-facedir = base_expe_dir + 'face'
-bgdir = base_expe_dir + 'bg'
-illumination_dir = base_expe_dir + 'illumination'
-threshold_file = illumination_dir + '/threshold.txt'
-motion_dir = base_expe_dir + 'motion'
-filtered_dir = base_expe_dir + 'filtered'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-npoints = 100 
-indent = 10
-
-adaptation = 0.01
-filter_length = 5
-
-segment_length = 40
-cutoff = 0.02
-
-Lambda = 300
-window = 3
-order = 32
-
-n_segments = 4
-nfft = 4096
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('npoints = ' + str(npoints) + '\n')
-f.write('indent [%] = ' + str(indent) + '\n\n')
-f.write('adaptation step = ' + str(adaptation) + '\n')
-f.write('filter length = ' + str(filter_length) + '\n\n')
-f.write('segment length [frames] = ' + str(segment_length) + '\n')
-f.write('cutoff [% / 100] = ' + str(cutoff) + '\n\n')
-f.write('lambda = ' + str(Lambda) + '\n')
-f.write('window = ' + str(window) + '\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# signals extraction
-os.system(bin_folder + 'cvpr14_extract_signals.py cohface --protocol clean --dbdir cohface --facedir ' + str(facedir) + ' --bgdir ' + str(bgdir) + ' --npoints ' + str(npoints) + ' --indent ' + str(indent) + ' -v')
-
-# illumination correction
-os.system(bin_folder + 'cvpr14_illumination.py cohface --protocol clean --facedir ' + facedir + ' --bgdir ' + bgdir + ' --outdir ' + illumination_dir + ' --step ' + str(adaptation) + ' --length ' + str(filter_length) + ' -v')
-
-# motion elimination -> determine the threshold
-os.system(bin_folder + 'cvpr14_motion.py cohface --protocol clean --subset train --subset dev --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength ' + str(segment_length) + ' --cutoff ' + str(cutoff) + ' --save-threshold ' + threshold_file + ' -v')
-
-# motion elimination -> remove segments
-os.system(bin_folder + 'cvpr14_motion.py cohface --protocol clean --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength ' + str(segment_length) + ' --cutoff ' +str(cutoff) + ' --load-threshold ' + threshold_file + ' -v')
-
-# filtering
-os.system(bin_folder + 'cvpr14_filter.py cohface --protocol clean --indir ' + motion_dir + ' --outdir ' + filtered_dir + ' --lambda ' + str(Lambda) + ' --window ' + str(window) + ' --order ' + str(order) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --protocol clean --indir ' + filtered_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  cohface --protocol clean --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py  cohface --protocol clean --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/li-cohface-complete-face.py b/scripts-article/li-cohface-complete-face.py
deleted file mode 100644
index 7f4c518..0000000
--- a/scripts-article/li-cohface-complete-face.py
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/li-cohface-complete-wholeface/')
-facedir = base_expe_dir + 'face'
-bgdir = base_expe_dir + 'bg'
-illumination_dir = base_expe_dir + 'illumination'
-threshold_file = illumination_dir + '/threshold.txt'
-motion_dir = base_expe_dir + 'motion'
-filtered_dir = base_expe_dir + 'filtered'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-#parameters
-adaptation = 0.01
-filter_length = 5
-
-segment_length = 40
-cutoff = 0.1
-
-Lambda = 100
-window = 3
-order = 64
-
-n_segments = 4
-nfft = 4096
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('adaptation step = ' + str(adaptation) + '\n')
-f.write('filter length = ' + str(filter_length) + '\n\n')
-f.write('segment length [frames] = ' + str(segment_length) + '\n')
-f.write('cutoff [% / 100] = ' + str(cutoff) + '\n\n')
-f.write('lambda = ' + str(Lambda) + '\n')
-f.write('window = ' + str(window) + '\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# signals extraction
-os.system(bin_folder + 'cvpr14_extract_signals.py cohface --dbdir cohface --facedir ' + str(facedir) + ' --bgdir ' + str(bgdir) + ' --wholeface -v')
-
-# illumination correction
-os.system(bin_folder + 'cvpr14_illumination.py cohface --facedir ' + facedir + ' --bgdir ' + bgdir + ' --outdir ' + illumination_dir + ' --step ' + str(adaptation) + ' --length ' + str(filter_length) + ' -v')
-
-# motion elimination -> determine the threshold
-os.system(bin_folder + 'cvpr14_motion.py cohface --subset train --subset dev --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength ' + str(segment_length) + ' --cutoff ' + str(cutoff) + ' --save-threshold ' + threshold_file + ' -v')
-
-# motion elimination -> remove segments
-os.system(bin_folder + 'cvpr14_motion.py cohface --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength ' + str(segment_length) + ' --cutoff ' +str(cutoff) + ' --load-threshold ' + threshold_file + ' -v')
-
-# filtering
-os.system(bin_folder + 'cvpr14_filter.py cohface --indir ' + motion_dir + ' --outdir ' + filtered_dir + ' --lambda ' + str(Lambda) + ' --window ' + str(window) + ' --order ' + str(order) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --indir ' + filtered_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  cohface --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py  cohface --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/li-cohface-complete-mask.py b/scripts-article/li-cohface-complete-mask.py
deleted file mode 100644
index 28f7093..0000000
--- a/scripts-article/li-cohface-complete-mask.py
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/li-cohface-complete-mask/')
-facedir = base_expe_dir + 'face'
-bgdir = base_expe_dir + 'bg'
-illumination_dir = base_expe_dir + 'illumination'
-threshold_file = illumination_dir + '/threshold.txt'
-motion_dir = base_expe_dir + 'motion'
-filtered_dir = base_expe_dir + 'filtered'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-npoints = 200
-indent = 10
-
-adaptation = 0.01
-filter_length = 5
-
-segment_length = 40
-cutoff = 0.02
-
-Lambda = 300
-window = 3
-order = 32
-
-n_segments = 4
-nfft = 4096
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('npoints = ' + str(npoints) + '\n')
-f.write('indent [%] = ' + str(indent) + '\n\n')
-f.write('adaptation step = ' + str(adaptation) + '\n')
-f.write('filter length = ' + str(filter_length) + '\n\n')
-f.write('segment length [frames] = ' + str(segment_length) + '\n')
-f.write('cutoff [% / 100] = ' + str(cutoff) + '\n\n')
-f.write('lambda = ' + str(Lambda) + '\n')
-f.write('window = ' + str(window) + '\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# signals extraction
-os.system(bin_folder + 'cvpr14_extract_signals.py cohface --subset train --subset dev --dbdir cohface --facedir ' + str(facedir) + ' --bgdir ' + str(bgdir) + ' --npoints ' + str(npoints) + ' --indent ' + str(indent) + ' -v')
-
-# illumination correction
-os.system(bin_folder + 'cvpr14_illumination.py cohface --facedir ' + facedir + ' --bgdir ' + bgdir + ' --outdir ' + illumination_dir + ' --step ' + str(adaptation) + ' --length ' + str(filter_length) + ' -v')
-
-# motion elimination -> determine the threshold
-os.system(bin_folder + 'cvpr14_motion.py cohface --subset train --subset dev --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength ' + str(segment_length) + ' --cutoff ' + str(cutoff) + ' --save-threshold ' + threshold_file + ' -v')
-
-# motion elimination -> remove segments
-os.system(bin_folder + 'cvpr14_motion.py cohface --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength ' + str(segment_length) + ' --cutoff ' +str(cutoff) + ' --load-threshold ' + threshold_file + ' -v')
-
-# filtering
-os.system(bin_folder + 'cvpr14_filter.py cohface --indir ' + motion_dir + ' --outdir ' + filtered_dir + ' --lambda ' + str(Lambda) + ' --window ' + str(window) + ' --order ' + str(order) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --indir ' + filtered_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  cohface --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py  cohface --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/li-cohface-complete-skin.py b/scripts-article/li-cohface-complete-skin.py
deleted file mode 100644
index d271a03..0000000
--- a/scripts-article/li-cohface-complete-skin.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/li-cohface-complete-skin/')
-facedir = base_expe_dir + 'face'
-bgdir = base_expe_dir + 'bg'
-illumination_dir = base_expe_dir + 'illumination'
-threshold_file = illumination_dir + '/threshold.txt'
-motion_dir = base_expe_dir + 'motion'
-filtered_dir = base_expe_dir + 'filtered'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-#parameters
-skin_threshold = 0.8
-
-adaptation = 0.01
-filter_length = 3
-
-segment_length = 40
-cutoff = 0.1
-
-Lambda = 100
-window = 3
-order = 128
-
-n_segments = 8
-nfft = 512
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('adaptation step = ' + str(adaptation) + '\n')
-f.write('filter length = ' + str(filter_length) + '\n\n')
-f.write('segment length [frames] = ' + str(segment_length) + '\n')
-f.write('cutoff [% / 100] = ' + str(cutoff) + '\n\n')
-f.write('lambda = ' + str(Lambda) + '\n')
-f.write('window = ' + str(window) + '\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# signals extraction
-os.system(bin_folder + 'cvpr14_video2skin.py cohface --dbdir cohface --outdir ' + str(facedir) + ' --threshold ' + str(skin_threshold) + ' -v')
-
-# illumination correction
-os.system(bin_folder + 'cvpr14_illumination.py cohface --facedir ' + facedir + ' --bgdir ' + bgdir + ' --outdir ' + illumination_dir + ' --step ' + str(adaptation) + ' --length ' + str(filter_length) + ' -v')
-
-# motion elimination -> determine the threshold
-os.system(bin_folder + 'cvpr14_motion.py cohface --subset train --subset dev --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength ' + str(segment_length) + ' --cutoff ' + str(cutoff) + ' --save-threshold ' + threshold_file + ' -v')
-
-# motion elimination -> remove segments
-os.system(bin_folder + 'cvpr14_motion.py cohface --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength ' + str(segment_length) + ' --cutoff ' +str(cutoff) + ' --load-threshold ' + threshold_file + ' -v')
-
-# filtering
-os.system(bin_folder + 'cvpr14_filter.py cohface --indir ' + motion_dir + ' --outdir ' + filtered_dir + ' --lambda ' + str(Lambda) + ' --window ' + str(window) + ' --order ' + str(order) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --indir ' + filtered_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  cohface --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py  cohface --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/li-hci-cvpr14.py b/scripts-article/li-hci-cvpr14.py
deleted file mode 100644
index 03b2950..0000000
--- a/scripts-article/li-hci-cvpr14.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/li-hci-cvpr14/')
-facedir = base_expe_dir + 'face'
-bgdir = base_expe_dir + 'bg'
-illumination_dir = base_expe_dir + 'illumination'
-threshold_file = illumination_dir + '/threshold.txt'
-motion_dir = base_expe_dir + 'motion'
-filtered_dir = base_expe_dir + 'filtered'
-hr_dir = base_expe_dir + 'hr'
-results_dir = base_expe_dir + 'results'
-
-# fixed parameter
-framerate = 61
-
-# parameters
-npoints = 200
-indent = 10 
-
-adaptation = 0.05
-filter_length = 3
-
-segment_length = 61
-cutoff = 0.05
-
-Lambda = 300
-window = 21
-order = 128
-
-n_segments = 16
-nfft = 8192
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('npoints = ' + str(npoints) + '\n')
-f.write('indent [%] = ' + str(indent) + '\n\n')
-f.write('adaptation step = ' + str(adaptation) + '\n')
-f.write('filter length = ' + str(filter_length) + '\n\n')
-f.write('segment length [frames] = ' + str(segment_length) + '\n')
-f.write('cutoff [% / 100] = ' + str(cutoff) + '\n\n')
-f.write('lambda = ' + str(Lambda) + '\n')
-f.write('window = ' + str(window) + '\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# signals extraction
-os.system(bin_folder + 'cvpr14_extract_signals.py hci --protocol cvpr14 --dbdir hci, --bboxdir bounding-boxes --facedir ' + str(facedir) + ' --bgdir ' + str(bgdir) + ' --npoints ' + str(npoints) + ' --indent ' + str(indent) + ' -v')
-
-# illumination correction
-os.system(bin_folder + 'cvpr14_illumination.py hci --protocol cvpr14 --facedir ' + facedir + ' --bgdir ' + bgdir + ' --outdir ' + illumination_dir + ' --step ' + str(adaptation) + ' --length ' + str(filter_length) + ' --start 306 --end 2136 -v')
-
-# motion elimination -> determine the threshold
-os.system(bin_folder + 'cvpr14_motion.py hci --protocol cvpr14 --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength ' + str(segment_length) + ' --cutoff ' + str(cutoff) + ' --save-threshold ' + threshold_file + ' -v')
-
-# motion elimination -> remove segments
-os.system(bin_folder + 'cvpr14_motion.py hci --protocol cvpr14 --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength 61 --cutoff 0.05 --load-threshold ' + threshold_file + ' -v')
-
-# filter
-os.system(bin_folder + 'cvpr14_filter.py hci --protocol cvpr14 --indir ' + motion_dir + ' --outdir ' + filtered_dir + ' --lambda ' + str(Lambda) + ' --window ' + str(window) + ' --order ' + str(order) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py hci --protocol cvpr14 --indir ' + filtered_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  hci --protocol cvpr14 --indir ' + hr_dir + ' --outdir ' + results_dir + ' -v')
diff --git a/scripts-article/li-hci-protocols.py b/scripts-article/li-hci-protocols.py
deleted file mode 100644
index 053f0c9..0000000
--- a/scripts-article/li-hci-protocols.py
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/li-hci-protocols/')
-facedir = base_expe_dir + 'face'
-bgdir = base_expe_dir + 'bg'
-illumination_dir = base_expe_dir + 'illumination'
-threshold_file = illumination_dir + '/threshold.txt'
-motion_dir = base_expe_dir + 'motion'
-filtered_dir = base_expe_dir + 'filtered'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 61
-
-# parameters
-npoints = 400 
-indent = 10
-
-adaptation = 0.05
-filter_length = 3
-
-segment_length = 30
-cutoff = 0.1
-
-Lambda = 500
-window = 23
-order = 96
-
-n_segments = 12
-nfft = 4096
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('npoints = ' + str(npoints) + '\n')
-f.write('indent [%] = ' + str(indent) + '\n\n')
-f.write('adaptation step = ' + str(adaptation) + '\n')
-f.write('filter length = ' + str(filter_length) + '\n\n')
-f.write('segment length [frames] = ' + str(segment_length) + '\n')
-f.write('cutoff [% / 100] = ' + str(cutoff) + '\n\n')
-f.write('lambda = ' + str(Lambda) + '\n')
-f.write('window = ' + str(window) + '\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# signals extraction
-os.system(bin_folder + 'cvpr14_extract_signals.py hci --dbdir hci, --bboxdir bounding-boxes --facedir ' + str(facedir) + ' --bgdir ' + str(bgdir) + ' --npoints ' + str(npoints) + ' --indent ' + str(indent) + ' -v')
-
-# illumination correction
-os.system(bin_folder + 'cvpr14_illumination.py hci --facedir ' + facedir + ' --bgdir ' + bgdir + ' --outdir ' + illumination_dir + ' --step ' + str(adaptation) + ' --length ' + str(filter_length) + ' -v')
-
-# motion elimination -> determine the threshold
-os.system(bin_folder + 'cvpr14_motion.py hci --subset train --subset dev --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength ' + str(segment_length) + ' --cutoff ' + str(cutoff) + ' --save-threshold ' + threshold_file + ' -v')
-
-# motion elimination -> remove segments
-os.system(bin_folder + 'cvpr14_motion.py hci --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength 61 --cutoff 0.05 --load-threshold ' + threshold_file + ' -v')
-
-# filtering
-os.system(bin_folder + 'cvpr14_filter.py hci --indir ' + motion_dir + ' --outdir ' + filtered_dir + ' --lambda ' + str(Lambda) + ' --window ' + str(window) + ' --order ' + str(order) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py hci --indir ' + filtered_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  hci --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py  hci --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/li-xdb-cohface-hci.py b/scripts-article/li-xdb-cohface-hci.py
deleted file mode 100644
index 6d0f58c..0000000
--- a/scripts-article/li-xdb-cohface-hci.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-### WARNING ###
-# be sure to run li-cohface-clean.py first to get the threshold file
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/li-xdb-cohface-hci/')
-facedir = base_expe_dir + 'face'
-bgdir = base_expe_dir + 'bg'
-illumination_dir = base_expe_dir + 'illumination'
-motion_dir = base_expe_dir + 'motion'
-filtered_dir = base_expe_dir + 'filtered'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 61
-
-# parameters
-npoints = 100 
-indent = 10
-
-adaptation = 0.01
-filter_length = 5
-
-segment_length = 120 # 2 times the framerate, as for COHFACE training set
-cutoff = 0.02
-threshold_file = 'experiments/paper/li-cohface-clean/illumination/threshold.txt'
-
-Lambda = 300
-window = 9
-order = 96
-
-n_segments = 4
-nfft = 4096
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('npoints = ' + str(npoints) + '\n')
-f.write('indent [%] = ' + str(indent) + '\n\n')
-f.write('adaptation step = ' + str(adaptation) + '\n')
-f.write('filter length = ' + str(filter_length) + '\n\n')
-f.write('segment length [frames] = ' + str(segment_length) + '\n')
-f.write('cutoff [% / 100] = ' + str(cutoff) + '\n\n')
-f.write('lambda = ' + str(Lambda) + '\n')
-f.write('window = ' + str(window) + '\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# signals extraction
-os.system(bin_folder + 'cvpr14_extract_signals.py hci --dbdir hci --subset test --bboxdir bounding-boxes --facedir ' + str(facedir) + ' --bgdir ' + str(bgdir) + ' --npoints ' + str(npoints) ' --indent ' + str(indent))
-
-# illumination correction
-os.system(bin_folder + 'cvpr14_illumination.py hci --subset test --facedir ' + facedir + ' --bgdir ' + bgdir + ' --outdir ' + illumination_dir + ' --step ' + str(adaptation) + ' --length ' + str(filter_length) + ' -v')
-
-# motion elimination -> remove segments
-os.system(bin_folder + 'cvpr14_motion.py hci --subset test --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength ' + str(segment_length) + ' --cutoff ' + str(cutoff) + ' --load-threshold ' + threshold_file + ' -v')
-
-# filtering
-os.system(bin_folder + 'cvpr14_filter.py hci --subset test --indir ' + motion_dir + ' --outdir ' + filtered_dir + ' --lambda ' + str(Lambda) + ' --window ' + str(window) + ' --order ' + str(order) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py hci --subset test --indir ' + filtered_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  hci --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/li-xdb-hci-cohface.py b/scripts-article/li-xdb-hci-cohface.py
deleted file mode 100644
index 71a34e1..0000000
--- a/scripts-article/li-xdb-hci-cohface.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-### WARNING ###
-# be sure to first run li-hci-protocols.py to get the required threshold file
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/li-xdb-hci-cohface/')
-facedir = base_expe_dir + 'face'
-bgdir = base_expe_dir + 'bg'
-illumination_dir = base_expe_dir + 'illumination'
-motion_dir = base_expe_dir + 'motion'
-filtered_dir = base_expe_dir + 'filtered'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-npoints = 400 
-indent = 10
-
-adaptation = 0.05
-filter_length = 3
-
-segment_length = 10 # half of the frame rate
-cutoff = 0.1
-threshold_file = 'experiments/paper/li-hci-protocols/illumination/threshold.txt'
-
-Lambda = 500
-window = 23
-order = 96
-
-n_segments = 12
-nfft = 4096
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('npoints = ' + str(npoints) + '\n')
-f.write('indent [%] = ' + str(indent) + '\n\n')
-f.write('adaptation step = ' + str(adaptation) + '\n')
-f.write('filter length = ' + str(filter_length) + '\n\n')
-f.write('segment length [frames] = ' + str(segment_length) + '\n')
-f.write('cutoff [% / 100] = ' + str(cutoff) + '\n\n')
-f.write('lambda = ' + str(Lambda) + '\n')
-f.write('window = ' + str(window) + '\n')
-f.write('order = ' + str(order) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# signals extraction
-os.system(bin_folder + 'cvpr14_extract_signals.py cohface --protocol clean --subset test --dbdir cohface --facedir ' + str(facedir) + ' --bgdir ' + str(bgdir) + ' --npoints ' + str(npoints) + ' --indent ' + str(indent) + ' -v')
-
-# illumination correction
-os.system(bin_folder + 'cvpr14_illumination.py cohface --protocol clean --subset test --facedir ' + facedir + ' --bgdir ' + bgdir + ' --outdir ' + illumination_dir + ' --step ' + str(adaptation) + ' --length ' + str(filter_length) + ' -v')
-
-# motion elimination -> remove segments
-os.system(bin_folder + 'cvpr14_motion.py cohface --protocol clean --subset test  --indir ' + illumination_dir + ' --outdir ' + motion_dir + ' --seglength ' + str(segment_length) + ' --cutoff ' + str(cutoff) + ' --load-threshold ' + threshold_file + ' -v')
-
-# filtering
-os.system(bin_folder + 'cvpr14_filter.py cohface --protocol clean --subset test --indir ' + motion_dir + ' --outdir ' + filtered_dir + ' --lambda ' + str(Lambda) + ' --window ' + str(window) + ' --order ' + str(order) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --protocol clean  --subset test --indir ' + filtered_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py cohface --protocol clean  --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/ssr-cohface-clean-natural.py b/scripts-article/ssr-cohface-clean-natural.py
deleted file mode 100644
index f3c1f4e..0000000
--- a/scripts-article/ssr-cohface-clean-natural.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/ssr-cohface-clean-natural/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-skin_threshold = 0.8
-stride = 80 
-
-n_segments = 8
-nfft = 2048
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('stride = ' + str(stride) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'ssr_pulse.py cohface --protocol natural --subset test --dbdir cohface --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --stride ' + str(stride) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --protocol natural --subset test --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' + str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  cohface --protocol natural --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/ssr-cohface-clean.py b/scripts-article/ssr-cohface-clean.py
deleted file mode 100644
index 3a4802f..0000000
--- a/scripts-article/ssr-cohface-clean.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/ssr-cohface-clean/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-skin_threshold = 0.8
-stride = 80 
-
-n_segments = 8
-nfft = 2048
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('stride = ' + str(stride) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'ssr_pulse.py cohface --protocol clean --dbdir cohface --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --stride ' + str(stride) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --protocol clean --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' + str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  cohface --protocol clean --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py  cohface --protocol clean --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/ssr-cohface-complete-face.py b/scripts-article/ssr-cohface-complete-face.py
deleted file mode 100644
index 560c58a..0000000
--- a/scripts-article/ssr-cohface-complete-face.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join('experiments/paper/ssr-cohface-complete-face/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-skin_threshold = 0.0
-
-# parameters
-stride = 10
-
-n_segments = 16
-nfft = 512
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('stride = ' + str(stride) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'ssr_pulse.py cohface --dbdir cohface --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --stride ' + str(stride) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py cohface --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py cohface --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/ssr-cohface-complete-mask.py b/scripts-article/ssr-cohface-complete-mask.py
deleted file mode 100644
index a283a5b..0000000
--- a/scripts-article/ssr-cohface-complete-mask.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/ssr-cohface-complete-mask/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-npoints = 100
-indent = 10
-
-stride = 10
-
-n_segments = 8
-nfft = 1024 
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('npoints = ' + str(npoints) + '\n\n')
-f.write('indent = ' + str(indent) + '\n\n')
-f.write('stride = ' + str(stride) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'ssr_pulse_from_mask.py cohface --dbdir cohface --pulsedir ' + str(pulse_dir) + ' --npoints ' + str(npoints) + ' --indent ' + str(indent) + ' --stride ' + str(stride) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py cohface --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py cohface --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/ssr-cohface-complete-skin.py b/scripts-article/ssr-cohface-complete-skin.py
deleted file mode 100644
index a3f8244..0000000
--- a/scripts-article/ssr-cohface-complete-skin.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join('experiments/paper/ssr-cohface-complete-skin/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-skin_threshold = 0.6
-stride = 10
-
-n_segments = 8
-nfft = 512
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('threshold = ' + str(skin_threshold) + '\n\n')
-f.write('stride = ' + str(stride) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'ssr_pulse.py cohface --dbdir cohface --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --stride ' + str(stride) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py cohface --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py cohface --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/ssr-hci-cvpr14.py b/scripts-article/ssr-hci-cvpr14.py
deleted file mode 100644
index 694d4a5..0000000
--- a/scripts-article/ssr-hci-cvpr14.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/ssr-hci-cvpr14/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir = base_expe_dir + 'results'
-
-framerate = 61
-
-# parameters
-skin_threshold = 0.1
-stride = 30 
-
-n_segments = 8
-nfft = 4096
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('stride = ' + str(stride) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'ssr_pulse.py hci --protocol cvpr14 --dbdir hci --bboxdir bounding-boxes --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --stride ' + str(stride) + ' --start 306 --end 2136 -v --skininit')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py hci --protocol cvpr14 --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  hci --protocol cvpr14 --indir ' + hr_dir + ' --outdir ' + results_dir + ' -v')
diff --git a/scripts-article/ssr-hci-protocols.py b/scripts-article/ssr-hci-protocols.py
deleted file mode 100644
index 0eff543..0000000
--- a/scripts-article/ssr-hci-protocols.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/ssr-hci-protocols/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 61
-
-# parameters
-skin_threshold = 0.1
-stride = 30 
-
-n_segments = 8
-nfft = 8192
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('stride = ' + str(stride) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'ssr_pulse.py hci --dbdir hci --bboxdir bounding-boxes --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --stride ' + str(stride) + ' -v --skininit')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py hci --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py  hci --subset train --subset dev --indir ' + hr_dir + ' --outdir ' + results_dir_train + ' -v')
-os.system(bin_folder + 'rppg_compute_performance.py  hci --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/ssr-xdb-cohface-hci.py b/scripts-article/ssr-xdb-cohface-hci.py
deleted file mode 100644
index e2fbb0f..0000000
--- a/scripts-article/ssr-xdb-cohface-hci.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/ssr-xdb-cohface-hci/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 61
-
-# parameters
-skin_threshold = 0.8
-stride = 80 
-
-n_segments = 8
-nfft = 2048
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('stride = ' + str(stride) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-# pulse extraction
-os.system(bin_folder + 'ssr_pulse.py hci --subset test --dbdir hci --bboxdir bounding-boxes --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --stride ' + str(stride) + ' -v')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py hci --subset test --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' + str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py hci --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
diff --git a/scripts-article/ssr-xdb-hci-cohface.py b/scripts-article/ssr-xdb-hci-cohface.py
deleted file mode 100644
index 4eb8441..0000000
--- a/scripts-article/ssr-xdb-hci-cohface.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/env python
-# encoding: utf-8
-
-# Copyright (c) 2017 Idiap Research Institute, http://www.idiap.ch/
-# Written by Guillaume Heusch <guillaume.heusch@idiap.ch>,
-# 
-# This file is part of bob.rpgg.base.
-# 
-# bob.rppg.base is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3 as
-# published by the Free Software Foundation.
-# 
-# bob.rppg.base is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# 
-# You should have received a copy of the GNU General Public License
-# along with bob.rppg.base. If not, see <http://www.gnu.org/licenses/>.
-
-import os, sys
-
-# directories and file
-current_folder = os.path.dirname(os.path.abspath(__file__))
-root_folder = os.path.dirname(current_folder)
-bin_folder = os.path.join(root_folder, 'bin/')
-
-base_expe_dir = os.path.join(root_folder, 'experiments/paper/ssr-xdb-hci-cohface/')
-pulse_dir = base_expe_dir + 'pulse'
-hr_dir = base_expe_dir + 'hr'
-results_dir_train = base_expe_dir + 'results-train'
-results_dir_test = base_expe_dir + 'results-test'
-
-framerate = 20
-
-# parameters
-skin_threshold = 0.1
-stride = 30 
-
-n_segments = 8
-nfft = 8192
-
-# write a file with the parameters - useful to keep track sometimes ..
-param_file = base_expe_dir + '/parameters.txt'
-if not os.path.isdir(base_expe_dir):
-  os.makedirs(base_expe_dir)
-
-f = open(param_file, 'w')
-f.write('skin threshold = ' + str(skin_threshold) + '\n\n')
-f.write('stride = ' + str(stride) + '\n\n')
-f.write('Welch segments = ' + str(n_segments) + '\n')
-f.write('npoints FFT = ' + str(nfft) + '\n')
-f.close()
-
-os.system(bin_folder + 'ssr_pulse.py cohface --protocol clean --subset test --dbdir cohface --outdir ' + str(pulse_dir) + ' --threshold ' + str(skin_threshold) + ' --stride ' + str(stride) + ' -v --skininit')
-
-# computing heart-rate
-os.system(bin_folder + 'rppg_get_heart_rate.py cohface --protocol clean --subset test --indir ' + pulse_dir + ' --outdir ' + hr_dir + ' --framerate ' + str(framerate) + ' --nsegments ' +str(n_segments) + ' --nfft ' + str(nfft) + ' -v')
-
-# computing performance
-os.system(bin_folder + 'rppg_compute_performance.py cohface --protocol clean --subset test --indir ' + hr_dir + ' --outdir ' + results_dir_test + ' -v')
-- 
GitLab


From 4713d8d3108ab4807f61717b192ee7d774f224e4 Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Tue, 26 Jun 2018 15:02:23 +0200
Subject: [PATCH 14/22] [doc] added bob.ip.dlib in the doc mapping, improved
 docstring

---
 bob/rppg/cvpr14/extract_utils.py | 7 ++++---
 doc/conf.py                      | 1 -
 doc/extra-intersphinx.txt        | 1 +
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/bob/rppg/cvpr14/extract_utils.py b/bob/rppg/cvpr14/extract_utils.py
index 1deed77..0015fa3 100644
--- a/bob/rppg/cvpr14/extract_utils.py
+++ b/bob/rppg/cvpr14/extract_utils.py
@@ -19,9 +19,9 @@ def kp66_to_mask(image, keypoints, indent=10, plot=False):
   Note also that this function is explicitly made for the
   keypoints set generated by the Matlab software downloaded
   from http://ibug.doc.ic.ac.uk/resources/drmf-matlab-code-cvpr-2013/
-  
-  If you decide to use another keypoint detector, you may need to 
-  rewrite a function to build the mask from your keypoints. 
+
+  Update: this function also works when using 
+  :py:class:`bob.ip.dlib.DlibLandmarkExtraction`
 
   Parameters
   ----------
@@ -104,6 +104,7 @@ def get_mask(image, mask_points):
   
   It turns mask points into a region of interest and returns the
   corresponding boolean array, of the same size as the image.
+  
   Taken from https://github.com/jdoepfert/roipoly.py/blob/master/roipoly.py
 
   Parameters
diff --git a/doc/conf.py b/doc/conf.py
index f0edcfc..a209f39 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -240,7 +240,6 @@ if os.path.exists(sphinx_requirements):
 else:
   intersphinx_mapping = link_documentation()
 
-
 # We want to remove all private (i.e. _. or __.__) members
 # that are not in the list of accepted functions
 accepted_private_functions = ['__array__']
diff --git a/doc/extra-intersphinx.txt b/doc/extra-intersphinx.txt
index de1df19..355bc94 100644
--- a/doc/extra-intersphinx.txt
+++ b/doc/extra-intersphinx.txt
@@ -1 +1,2 @@
 bob.ip.skincolorfilter
+bob.ip.dlib
-- 
GitLab


From bb1123eb658d68b1ea53579ff41237b8c487ae8d Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Tue, 26 Jun 2018 15:26:34 +0200
Subject: [PATCH 15/22] [conda] fixed bug in recipe

---
 conda/meta.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/conda/meta.yaml b/conda/meta.yaml
index 1132395..fa280bd 100644
--- a/conda/meta.yaml
+++ b/conda/meta.yaml
@@ -57,7 +57,7 @@ test:
   imports:
     - {{ name }}
   commands:
-    - cvpr14_extract_signals.py --help
+    - cvpr14_extract_face_and_bg_signals.py --help
     - cvpr14_video2skin.py --help
     - cvpr14_illumination.py --help
     - cvpr14_motion.py --help
-- 
GitLab


From 1993f9354b46293217a9f96eb1decbc84ae059f1 Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Wed, 27 Jun 2018 13:42:02 +0200
Subject: [PATCH 16/22] [base, cvpr14] modified the default value for protocol
 and subset

---
 bob/rppg/base/script/compute_performance.py          |  8 ++++----
 bob/rppg/base/script/frequency_analysis.py           |  8 ++++----
 .../cvpr14/script/extract_face_and_bg_signals.py     | 12 ++++++------
 bob/rppg/cvpr14/script/filter.py                     |  6 +++---
 bob/rppg/cvpr14/script/illumination_rectification.py |  6 +++---
 bob/rppg/cvpr14/script/motion_elimination.py         |  6 +++---
 6 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/bob/rppg/base/script/compute_performance.py b/bob/rppg/base/script/compute_performance.py
index 687f926..b268692 100644
--- a/bob/rppg/base/script/compute_performance.py
+++ b/bob/rppg/base/script/compute_performance.py
@@ -18,7 +18,7 @@ Options:
   -V, --version             Show version
   -v, --verbose             Increases the verbosity (may appear multiple times)
   -P, --plot                Set this flag if you'd like to see some plots. 
-  -p, --protocol=<string>   Protocol.
+  -p, --protocol=<string>   Protocol [default: all].[default: all]
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
   -i, --hrdir=<path>        The path to the saved heart rate values on your disk [default: hr]. 
@@ -48,7 +48,7 @@ logger = setup("bob.rppg.base")
 from docopt import docopt
 
 from bob.extension.config import load
-from bob.rppg.base.utils import get_parameter
+from ..utils import get_parameter
 
 version = pkg_resources.require('bob.rppg.base')[0].version
 
@@ -71,8 +71,8 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
 
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', 'None')
-  subset = get_parameter(args, configuration, 'subset', 'all')
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', None)
   hrdir = get_parameter(args, configuration, 'hrdir', 'hr')
   resultdir = get_parameter(args, configuration, 'resultdir', 'results')
   overwrite = get_parameter(args, configuration, 'overwrite', False)
diff --git a/bob/rppg/base/script/frequency_analysis.py b/bob/rppg/base/script/frequency_analysis.py
index 7a3a619..0b32c28 100644
--- a/bob/rppg/base/script/frequency_analysis.py
+++ b/bob/rppg/base/script/frequency_analysis.py
@@ -20,7 +20,7 @@ Options:
   -V, --version             Show version
   -P, --plot                Set this flag if you'd like to follow-up the algorithm
                             execution graphically. We'll plot some interactions.
-  -p, --protocol=<string>   Protocol.
+  -p, --protocol=<string>   Protocol [default: all].[default: all]
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
   -i, --pulsedir=<path>     The path to the saved filtered signals on your disk
@@ -60,7 +60,7 @@ logger = setup("bob.rppg.base")
 from docopt import docopt
 
 from bob.extension.config import load
-from bob.rppg.base.utils import get_parameter
+from ..utils import get_parameter
 
 version = pkg_resources.require('bob.rppg.base')[0].version
 
@@ -83,8 +83,8 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
 
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', 'None')
-  subset = get_parameter(args, configuration, 'subset', 'all')
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', None)
   pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
   hrdir = get_parameter(args, configuration, 'hrdir', 'hr')
   framerate = get_parameter(args, configuration, 'framerate', 61)
diff --git a/bob/rppg/cvpr14/script/extract_face_and_bg_signals.py b/bob/rppg/cvpr14/script/extract_face_and_bg_signals.py
index 261906c..51f5d18 100644
--- a/bob/rppg/cvpr14/script/extract_face_and_bg_signals.py
+++ b/bob/rppg/cvpr14/script/extract_face_and_bg_signals.py
@@ -17,7 +17,7 @@ Usage:
 Options:
   -h, --help                Show this screen
   -V, --version             Show version
-  -p, --protocol=<string>   Protocol.
+  -p, --protocol=<string>   Protocol [default: all].
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the sets will be loaded.
   -f, --facedir=<path>      The path to the directory where signal extracted 
@@ -63,6 +63,7 @@ logger = setup("bob.rppg.base")
 from docopt import docopt
 
 from bob.extension.config import load
+from ...base.utils import get_parameter
 
 version = pkg_resources.require('bob.rppg.base')[0].version
 
@@ -70,7 +71,6 @@ import numpy
 import bob.io.base
 import bob.ip.facedetect
 
-from ...base.utils import get_parameter
 from ...base.utils import crop_face
 
 from ..extract_utils import kp66_to_mask
@@ -96,10 +96,10 @@ def main(user_input=None):
 
   # load configuration file
   configuration = load([os.path.join(args['<configuration>'])])
-  
+ 
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', 'None')
-  subset = get_parameter(args, configuration, 'subset', '')
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', None)
   facedir = get_parameter(args, configuration, 'facedir', 'face')
   bgdir = get_parameter(args, configuration, 'bgdir', 'bg')
   npoints = get_parameter(args, configuration, 'npoints', 40)
@@ -111,7 +111,7 @@ def main(user_input=None):
   gridcount = get_parameter(args, configuration, 'gridcount', False)
   wholeface = get_parameter(args, configuration, 'wholeface', False)
   verbosity_level = get_parameter(args, configuration, 'verbose', 0)
-  
+
   # if the user wants more verbosity, lowers the logging level
   from bob.core.log import set_verbosity_level
   set_verbosity_level(logger, verbosity_level)
diff --git a/bob/rppg/cvpr14/script/filter.py b/bob/rppg/cvpr14/script/filter.py
index 2bcd7cc..1ff143d 100644
--- a/bob/rppg/cvpr14/script/filter.py
+++ b/bob/rppg/cvpr14/script/filter.py
@@ -20,7 +20,7 @@ Options:
   -V, --version             Show version
   -P, --plot                Set this flag if you'd like to follow-up the algorithm
                             execution graphically. We'll plot some interactions.
-  -p, --protocol=<string>   Protocol.
+  -p, --protocol=<string>   Protocol [default: all].
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
   -i, --motiondir=<path>        The path to the saved signals to be filtered on
@@ -92,8 +92,8 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
   
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', 'None')
-  subset = get_parameter(args, configuration, 'subset', '')
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', None)
   motiondir = get_parameter(args, configuration, 'motiondir', 'motion')
   pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
   Lambda = get_parameter(args, configuration, 'Lambda', 300)
diff --git a/bob/rppg/cvpr14/script/illumination_rectification.py b/bob/rppg/cvpr14/script/illumination_rectification.py
index cecbe41..38049ce 100644
--- a/bob/rppg/cvpr14/script/illumination_rectification.py
+++ b/bob/rppg/cvpr14/script/illumination_rectification.py
@@ -21,7 +21,7 @@ Options:
   -V, --version             Show version
   -P, --plot                Set this flag if you'd like to follow-up the algorithm
                             execution graphically. We'll plot some interactions.
-  -p, --protocol=<string>   Protocol.
+  -p, --protocol=<string>   Protocol [default: all].
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
   -f, --facedir=<path>      The path to the directory containing the average
@@ -88,8 +88,8 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
 
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', 'None')
-  subset = get_parameter(args, configuration, 'subset', 'all')
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', None)
   facedir = get_parameter(args, configuration, 'facedir', 'face')
   bgdir = get_parameter(args, configuration, 'bgdir', 'bg')
   illumdir = get_parameter(args, configuration, 'illumdir', 'illumination')
diff --git a/bob/rppg/cvpr14/script/motion_elimination.py b/bob/rppg/cvpr14/script/motion_elimination.py
index 800af75..5e2f938 100644
--- a/bob/rppg/cvpr14/script/motion_elimination.py
+++ b/bob/rppg/cvpr14/script/motion_elimination.py
@@ -20,7 +20,7 @@ Options:
   -V, --version                 Show version
   -P, --plot                    Set this flag if you'd like to follow-up the algorithm
                                 execution graphically. We'll plot some interactions.
-  -p, --protocol=<string>       Protocol.
+  -p, --protocol=<string>       Protocol [default: all].
   -s, --subset=<string>         Data subset to load. If nothing is provided 
                                 all the data sets will be loaded.
   -i, --illumdir=<path>            The path to the saved illumination corrected signal
@@ -91,8 +91,8 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
 
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', 'None')
-  subset = get_parameter(args, configuration, 'subset', 'all')
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', None)
   illumdir = get_parameter(args, configuration, 'illumdir', 'illumination')
   motiondir = get_parameter(args, configuration, 'motiondir', 'motion')
   seglength = get_parameter(args, configuration, 'seglength', 61)
-- 
GitLab


From 28b19782d2b64dd0f3e0457236f86f8e80e3bb6e Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Wed, 27 Jun 2018 13:42:29 +0200
Subject: [PATCH 17/22] [utils] fixed the function to get parameters

---
 bob/rppg/base/utils.py | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/bob/rppg/base/utils.py b/bob/rppg/base/utils.py
index 32a8e90..9250c42 100644
--- a/bob/rppg/base/utils.py
+++ b/bob/rppg/base/utils.py
@@ -145,10 +145,15 @@ def get_parameter(args, configuration, keyword, default):
   # get the argument in the configuration file 
   if hasattr(configuration, keyword):
     arg_config = getattr(configuration, keyword)
+  else:
+    arg_config = None
 
   # get the argument from the command-line
-  arg_command = _type(args[args_kw])
- 
+  if default is not None:
+    arg_command = _type(args[args_kw])
+  else:
+    arg_command = default 
+
   # if the argument was not specified in the config file
   if not hasattr(configuration, keyword):
     return arg_command
-- 
GitLab


From a49bba874d7977f87c188617b47c598086cfb612 Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Wed, 27 Jun 2018 13:43:08 +0200
Subject: [PATCH 18/22] [cvpr14] configuration file in the video2skin script

---
 bob/rppg/cvpr14/script/video2skin.py | 104 +++++++++++----------------
 1 file changed, 42 insertions(+), 62 deletions(-)

diff --git a/bob/rppg/cvpr14/script/video2skin.py b/bob/rppg/cvpr14/script/video2skin.py
index 6b80375..3a951e0 100644
--- a/bob/rppg/cvpr14/script/video2skin.py
+++ b/bob/rppg/cvpr14/script/video2skin.py
@@ -4,9 +4,9 @@
 """Skin color extraction for database videos (%(version)s)
 
 Usage:
-  %(prog)s (cohface | hci) [--protocol=<string>] [--subset=<string> ...] 
+  %(prog)s <configuration> [--protocol=<string>] [--subset=<string> ...] 
            [--verbose ...] [--plot]
-           [--dbdir=<path>] [--outdir=<path>] 
+           [--skindir=<path>] 
            [--overwrite] [--threshold=<float>] [--skininit]
            [--gridcount] 
 
@@ -23,9 +23,7 @@ Options:
   -p, --protocol=<string>   Protocol [default: all].
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
-  -D, --dbdir=<path>        The path to the database on your disk. If not set,
-                            defaults to Idiap standard locations.
-  -o, --outdir=<path>       Where the skin color will be stored [default: skin].
+  -o, --skindir=<path>       Where the skin color will be stored [default: skin].
                             database (for testing purposes)
   -O, --overwrite           By default, we don't overwrite existing files. The
                             processing will skip those so as to go faster. If you
@@ -38,17 +36,7 @@ Options:
 
 Examples:
 
-  To run the skin color extraction on the hci database
-
-    $ %(prog)s hci -v
-
-  To just run a preliminary benchmark tests on the first 10 videos, do:
-
-    $ %(prog)s cohface -v -l 10
-
-  You can change the output directory using the `-f' r `-b' flags (see help):
-
-    $ %(prog)s hci -v -f /path/to/result/face-directory
+  To run the skin color extraction
 
 
 See '%(prog)s --help' for more information.
@@ -60,7 +48,6 @@ import os
 import sys
 import pkg_resources
 
-from bob.core.log import set_verbosity_level
 from bob.core.log import setup
 logger = setup("bob.rppg.base")
 
@@ -72,6 +59,9 @@ import numpy
 import bob.io.base
 import bob.ip.skincolorfilter
 
+from bob.extension.config import load
+from ...base.utils import get_parameter
+
 from ...base.utils import crop_face
 from ..extract_utils import compute_average_colors_mask
 
@@ -87,44 +77,34 @@ def main(user_input=None):
   completions = dict(prog=prog, version=version,)
   args = docopt(__doc__ % completions, argv=arguments, version='Signal extractor for videos (%s)' % version,)
 
+  # load configuration file
+  configuration = load([os.path.join(args['<configuration>'])])
+ 
+  # get various parameters, either from config file or command-line 
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', None)
+  skindir = get_parameter(args, configuration, 'skindir', 'skin')
+  threshold = get_parameter(args, configuration, 'threshold', 0.5)
+  skininit = get_parameter(args, configuration, 'skininit', False)
+  overwrite = get_parameter(args, configuration, 'overwrite', False)
+  plot = get_parameter(args, configuration, 'plot', False)
+  gridcount = get_parameter(args, configuration, 'gridcount', False)
+  verbosity_level = get_parameter(args, configuration, 'verbose', 0)
+  
+  print(protocol)
+  print(type(protocol))
+  
   # if the user wants more verbosity, lowers the logging level
-  set_verbosity_level(logger, args['--verbose'])
-
-  # chooses the database driver to use
-  if args['cohface']:
-    import bob.db.cohface
-    if os.path.isdir(bob.db.cohface.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.cohface.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir']
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.cohface.Database(dbdir)
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'clean') or (args['--protocol'] == 'natural')):
-      logger.warning("Protocol should be either 'clean', 'natural' or 'all' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
-
-  elif args['hci']:
-    import bob.db.hci_tagging
-    import bob.db.hci_tagging.driver
-    if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
-      logger.debug("Using Idiap default location for the DB")
-      dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
-    elif args['--indir'] is not None:
-      logger.debug("Using provided location for the DB")
-      dbdir = args['--indir'] 
-    else:
-      logger.warn("Could not find the database directory, please provide one")
-      sys.exit()
-    db = bob.db.hci_tagging.Database()
-    if not((args['--protocol'] == 'all') or (args['--protocol'] == 'cvpr14')):
-      logger.warning("Protocol should be either 'all' or 'cvpr14' (and not {0})".format(args['--protocol']))
-      sys.exit()
-    objects = db.objects(args['--protocol'], args['--subset'])
+  from bob.core.log import set_verbosity_level
+  set_verbosity_level(logger, verbosity_level)
+
+  if hasattr(configuration, 'database'):
+    objects = configuration.database.objects(protocol, subset)
+  else:
+    logger.error("Please provide a database in your configuration file !")
+    sys.exit()
+
+  print(objects)
 
   # if we are on a grid environment, just find what I have to process.
   sge = False
@@ -139,7 +119,7 @@ def main(user_input=None):
       raise RuntimeError("Grid request for job {} on a setup with {} jobs".format(pos, len(objects)))
     objects = [objects[pos]]
 
-  if args['--gridcount']:
+  if gridcount:
     print(len(objects))
     sys.exit()
 
@@ -149,15 +129,15 @@ def main(user_input=None):
   for obj in objects:
 
     # expected output face file
-    output = obj.make_path(args['--outdir'], '.hdf5')
+    output = obj.make_path(skindir, '.hdf5')
 
     # if output exists and not overwriting, skip this file
-    if os.path.exists(output) and not args['--overwrite']:
+    if os.path.exists(output) and not overwrite:
       logger.info("Skipping output file `%s': already exists, use --overwrite to force an overwrite", output)
       continue
 
     # load the video sequence into a reader
-    video = obj.load_video(dbdir)
+    video = obj.load_video(configuration.dbdir)
 
     logger.info("Processing input video from `%s'...", video.filename)
     logger.debug("Sequence length = {0}".format(video.number_of_frames))
@@ -180,12 +160,12 @@ def main(user_input=None):
       face = crop_face(frame, bounding_boxes[i], facewidth)
 
       # skin filter
-      if i == 0 or bool(args['--skininit']):
+      if i == 0 or bool(skininit):
         skin_filter.estimate_gaussian_parameters(face)
         logger.debug("Skin color parameters:\nmean\n{0}\ncovariance\n{1}".format(skin_filter.mean, skin_filter.covariance))
-      skin_mask = skin_filter.get_skin_mask(face, float(args['--threshold']))
+      skin_mask = skin_filter.get_skin_mask(face, threshold)
 
-      if bool(args['--plot']) and i == 0:
+      if plot and i == 0:
         from matplotlib import pyplot
         skin_mask_image = numpy.copy(face)
         skin_mask_image[:, skin_mask] = 255
@@ -201,7 +181,7 @@ def main(user_input=None):
         else:
           skin_colors[i] = skin_colors[i-1]
 
-    if bool(args['--plot']):
+    if plot:
       from matplotlib import pyplot
 
       f, axarr = pyplot.subplots(3, sharex=True)
-- 
GitLab


From b865d37ab354c8f24ece15d8293cad9e53b9abc0 Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Wed, 27 Jun 2018 13:51:39 +0200
Subject: [PATCH 19/22] [chrom] changed default values for protocol and subset

---
 bob/rppg/chrom/script/extract_pulse.py           | 6 +++---
 bob/rppg/chrom/script/extract_pulse_from_mask.py | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/bob/rppg/chrom/script/extract_pulse.py b/bob/rppg/chrom/script/extract_pulse.py
index 74d74c3..26e0fcb 100644
--- a/bob/rppg/chrom/script/extract_pulse.py
+++ b/bob/rppg/chrom/script/extract_pulse.py
@@ -20,7 +20,7 @@ Usage:
 Options:
   -h, --help                Show this screen
   -V, --version             Show version
-  -p, --protocol=<string>   Protocol.
+  -p, --protocol=<string>   Protocol [default: all].
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
   -o, --pulsedir=<path>     The path to the directory where signal extracted 
@@ -99,8 +99,8 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
  
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', 'None')
-  subset = get_parameter(args, configuration, 'subset', '')
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', None)
   pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
   start = get_parameter(args, configuration, 'start', 0)
   end = get_parameter(args, configuration, 'end', 0)
diff --git a/bob/rppg/chrom/script/extract_pulse_from_mask.py b/bob/rppg/chrom/script/extract_pulse_from_mask.py
index 6a25c4e..15cfac0 100644
--- a/bob/rppg/chrom/script/extract_pulse_from_mask.py
+++ b/bob/rppg/chrom/script/extract_pulse_from_mask.py
@@ -18,7 +18,7 @@ Usage:
 Options:
   -h, --help                Show this screen
   -V, --version             Show version
-  -p, --protocol=<string>   Protocol.
+  -p, --protocol=<string>   Protocol [default: all].
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
   -o, --pulsedir=<path>     The path to the directory where signal extracted 
@@ -103,8 +103,8 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
  
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', 'None')
-  subset = get_parameter(args, configuration, 'subset', '')
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', None)
   pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
   npoints = get_parameter(args, configuration, 'npoints', 40)
   indent = get_parameter(args, configuration, 'indent', 10)
-- 
GitLab


From 8f8af5751ea4058b8e1e832fa4c9f2ae1597a83c Mon Sep 17 00:00:00 2001
From: Guillaume HEUSCH <guillaume.heusch@idiap.ch>
Date: Wed, 27 Jun 2018 13:53:06 +0200
Subject: [PATCH 20/22] [ssr] changed default values for protocol and subset

---
 bob/rppg/ssr/script/spatial_subspace_rotation.py | 6 +++---
 bob/rppg/ssr/script/ssr_from_mask.py             | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/bob/rppg/ssr/script/spatial_subspace_rotation.py b/bob/rppg/ssr/script/spatial_subspace_rotation.py
index a9010a5..f906bf2 100644
--- a/bob/rppg/ssr/script/spatial_subspace_rotation.py
+++ b/bob/rppg/ssr/script/spatial_subspace_rotation.py
@@ -22,7 +22,7 @@ Options:
   -V, --version             Show version
   -P, --plot                Set this flag if you'd like to follow-up the algorithm
                             execution graphically. We'll plot some interactions.
-  -p, --protocol=<string>   Protocol.
+  -p, --protocol=<string>   Protocol [default: all].
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
   -o, --pulsedir=<path>       The path to the output directory where the resulting
@@ -91,8 +91,8 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
  
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', 'None')
-  subset = get_parameter(args, configuration, 'subset', '')
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', None)
   pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
   start = get_parameter(args, configuration, 'start', 0)
   end = get_parameter(args, configuration, 'end', 0)
diff --git a/bob/rppg/ssr/script/ssr_from_mask.py b/bob/rppg/ssr/script/ssr_from_mask.py
index 4e3eeb5..12fce13 100644
--- a/bob/rppg/ssr/script/ssr_from_mask.py
+++ b/bob/rppg/ssr/script/ssr_from_mask.py
@@ -18,7 +18,7 @@ Usage:
 Options:
   -h, --help                Show this screen
   -V, --version             Show version
-  -p, --protocol=<string>   Protocol.
+  -p, --protocol=<string>   Protocol [default: all].
   -s, --subset=<string>     Data subset to load. If nothing is provided 
                             all the data sets will be loaded.
   -o, --pulsedir=<path>     The path to the directory where signal extracted 
@@ -102,8 +102,8 @@ def main(user_input=None):
   configuration = load([os.path.join(args['<configuration>'])])
  
   # get various parameters, either from config file or command-line 
-  protocol = get_parameter(args, configuration, 'protocol', 'None')
-  subset = get_parameter(args, configuration, 'subset', '')
+  protocol = get_parameter(args, configuration, 'protocol', 'all')
+  subset = get_parameter(args, configuration, 'subset', None)
   pulsedir = get_parameter(args, configuration, 'pulsedir', 'pulse')
   npoints = get_parameter(args, configuration, 'npoints', 40)
   indent = get_parameter(args, configuration, 'indent', 10)
-- 
GitLab


From 6570e6fbd9ea74af93b071dea12b8871002790e6 Mon Sep 17 00:00:00 2001
From: Guillaume Heusch <guillaumeheusch@Guillaumes-MacBook-Pro.local>
Date: Wed, 27 Jun 2018 14:31:45 +0200
Subject: [PATCH 21/22] changed the name of the scripts, adding bob_rppg_ as
 prefix

---
 conda/meta.yaml | 44 ++++++++++++++++++++++----------------------
 setup.py        | 23 +++++++++++------------
 2 files changed, 33 insertions(+), 34 deletions(-)

diff --git a/conda/meta.yaml b/conda/meta.yaml
index fa280bd..6266b6a 100644
--- a/conda/meta.yaml
+++ b/conda/meta.yaml
@@ -7,17 +7,17 @@ package:
 
 build:
   entry_points:
-    - cvpr14_extract_face_and_bg_signals.py = bob.rppg.cvpr14.script.extract_face_and_bg_signals:main
-    - cvpr14_video2skin.py = bob.rppg.cvpr14.script.video2skin:main
-    - cvpr14_illumination.py = bob.rppg.cvpr14.script.illumination_rectification:main
-    - cvpr14_motion.py = bob.rppg.cvpr14.script.motion_elimination:main
-    - cvpr14_filter.py = bob.rppg.cvpr14.script.filter:main
-    - chrom_pulse.py = bob.rppg.chrom.script.extract_pulse:main
-    - chrom_pulse_from_mask.py = bob.rppg.chrom.script.extract_pulse_from_mask:main
-    - ssr_pulse.py = bob.rppg.ssr.script.spatial_subspace_rotation:main
-    - ssr_pulse_from_mask.py = bob.rppg.ssr.script.ssr_from_mask:main
-    - rppg_get_heart_rate.py = bob.rppg.base.script.frequency_analysis:main
-    - rppg_compute_performance.py = bob.rppg.base.script.compute_performance:main
+    - bob_rppg_cvpr14_extract_face_and_bg_signals.py = bob.rppg.cvpr14.script.extract_face_and_bg_signals:main
+    - bob_rppg_cvpr14_video2skin.py = bob.rppg.cvpr14.script.video2skin:main
+    - bob_rppg_cvpr14_illumination.py = bob.rppg.cvpr14.script.illumination_rectification:main
+    - bob_rppg_cvpr14_motion.py = bob.rppg.cvpr14.script.motion_elimination:main
+    - bob_rppg_cvpr14_filter.py = bob.rppg.cvpr14.script.filter:main
+    - bob_rppg_chrom_pulse.py = bob.rppg.chrom.script.extract_pulse:main
+    - bob_rppg_chrom_pulse_from_mask.py = bob.rppg.chrom.script.extract_pulse_from_mask:main
+    - bob_rppg_ssr_pulse.py = bob.rppg.ssr.script.spatial_subspace_rotation:main
+    - bob_rppg_ssr_pulse_from_mask.py = bob.rppg.ssr.script.ssr_from_mask:main
+    - bob_rppg_base_get_heart_rate.py = bob.rppg.base.script.frequency_analysis:main
+    - bob_rppg_base_compute_performance.py = bob.rppg.base.script.compute_performance:main
   number: {{ environ.get('BOB_BUILD_NUMBER', 0) }}
   run_exports:
     - {{ pin_subpackage(name) }}
@@ -57,17 +57,17 @@ test:
   imports:
     - {{ name }}
   commands:
-    - cvpr14_extract_face_and_bg_signals.py --help
-    - cvpr14_video2skin.py --help
-    - cvpr14_illumination.py --help
-    - cvpr14_motion.py --help
-    - cvpr14_filter.py --help
-    - chrom_pulse.py --help
-    - chrom_pulse_from_mask.py --help
-    - ssr_pulse.py --help
-    - ssr_pulse_from_mask.py --help
-    - rppg_get_heart_rate.py --help
-    - rppg_compute_performance.py --help
+    - bob_rppg_cvpr14_extract_face_and_bg_signals.py --help
+    - bob_rppg_cvpr14_video2skin.py --help
+    - bob_rppg_cvpr14_illumination.py --help
+    - bob_rppg_cvpr14_motion.py --help
+    - bob_rppg_cvpr14_filter.py --help
+    - bob_rppg_chrom_pulse.py --help
+    - bob_rppg_chrom_pulse_from_mask.py --help
+    - bob_rppg_ssr_pulse.py --help
+    - bob_rppg_ssr_pulse_from_mask.py --help
+    - bob_rppg_base_get_heart_rate.py --help
+    - bob_rppg_base_compute_performance.py --help
     - nosetests --with-coverage --cover-package={{ name }} -sv {{ name }}
     - sphinx-build -aEW {{ project_dir }}/doc {{ project_dir }}/sphinx
     - sphinx-build -aEb doctest {{ project_dir }}/doc sphinx
diff --git a/setup.py b/setup.py
index f58e61b..ccc68f9 100644
--- a/setup.py
+++ b/setup.py
@@ -32,18 +32,17 @@ setup(
 
   entry_points={
     'console_scripts': [
-      'cvpr14_extract_face_and_bg_signals.py = bob.rppg.cvpr14.script.extract_face_and_bg_signals:main',
-      'cvpr14_video2skin.py = bob.rppg.cvpr14.script.video2skin:main',
-      'cvpr14_illumination.py = bob.rppg.cvpr14.script.illumination_rectification:main',
-      'cvpr14_motion.py = bob.rppg.cvpr14.script.motion_elimination:main',
-      'cvpr14_filter.py = bob.rppg.cvpr14.script.filter:main',
-      'chrom_pulse.py = bob.rppg.chrom.script.extract_pulse:main',
-      'chrom_pulse_from_mask.py = bob.rppg.chrom.script.extract_pulse_from_mask:main',
-      'ssr_pulse.py = bob.rppg.ssr.script.spatial_subspace_rotation:main',
-      'ssr_pulse_from_mask.py = bob.rppg.ssr.script.ssr_from_mask:main',
-      'rppg_get_heart_rate.py = bob.rppg.base.script.frequency_analysis:main',
-      'rppg_compute_performance.py = bob.rppg.base.script.compute_performance:main',
-      'rppg_check_differences.py = bob.rppg.base.script.check_differences:main'
+      'bob_rppg_cvpr14_extract_face_and_bg_signals.py = bob.rppg.cvpr14.script.extract_face_and_bg_signals:main',
+      'bob_rppg_cvpr14_video2skin.py = bob.rppg.cvpr14.script.video2skin:main',
+      'bob_rppg_cvpr14_illumination.py = bob.rppg.cvpr14.script.illumination_rectification:main',
+      'bob_rppg_cvpr14_motion.py = bob.rppg.cvpr14.script.motion_elimination:main',
+      'bob_rppg_cvpr14_filter.py = bob.rppg.cvpr14.script.filter:main',
+      'bob_rppg_chrom_pulse.py = bob.rppg.chrom.script.extract_pulse:main',
+      'bob_rppg_chrom_pulse_from_mask.py = bob.rppg.chrom.script.extract_pulse_from_mask:main',
+      'bob_rppg_ssr_pulse.py = bob.rppg.ssr.script.spatial_subspace_rotation:main',
+      'bob_rppg_ssr_pulse_from_mask.py = bob.rppg.ssr.script.ssr_from_mask:main',
+      'bob_rppg_base_get_heart_rate.py = bob.rppg.base.script.frequency_analysis:main',
+      'bob_rppg_base_compute_performance.py = bob.rppg.base.script.compute_performance:main',
       ],
     },
 
-- 
GitLab


From 198309997cb6d98df1c17e0a222abe49664354f2 Mon Sep 17 00:00:00 2001
From: Guillaume Heusch <guillaumeheusch@Guillaumes-MacBook-Pro.local>
Date: Wed, 27 Jun 2018 14:54:53 +0200
Subject: [PATCH 22/22] [doc] updated the doc with the new scripts name

---
 doc/guide_chrom.rst       |  8 ++++----
 doc/guide_cvpr14.rst      | 16 ++++++++--------
 doc/guide_performance.rst | 39 +++++++++++++++++++++++++++++++--------
 doc/guide_ssr.rst         |  8 ++++----
 4 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/doc/guide_chrom.rst b/doc/guide_chrom.rst
index e616258..8d27144 100644
--- a/doc/guide_chrom.rst
+++ b/doc/guide_chrom.rst
@@ -41,11 +41,11 @@ before the final pulse signal is built.
 
 To extract the pulse signal from video sequences, do the following::
 
-  $ ./bin/chrom_pulse.py config.py -vv
+  $ ./bin/bob_rppg_chrom_pulse.py config.py -vv
 
 To see the full options, including parameters and protocols, type:: 
 
-  $ ./bin/chrom_pulse.py --help 
+  $ ./bin/bob_rppg_chrom_pulse.py --help 
 
 As you can see, the script takes a configuration file as argument. This
 configuration file is required to at least specify the database, but can also
@@ -94,11 +94,11 @@ given below.
    The execution of this script is very slow - mainly due to the face detection. 
    You can speed it up using the gridtk_ (especially, if you're at Idiap). For example::
 
-     $ ./bin/jman sub -t 3490 -- ./bin/chrom_pulse.py cohface
+     $ ./bin/jman sub -t 3490 -- ./bin/bob_rppg_chrom_pulse.py cohface
 
    The number of jobs (i.e. 3490) is given by typing::
      
-     $ ./bin/chrom_pulse.py cohface --gridcount
+     $ ./bin/bob_rppg_chrom_pulse.py cohface --gridcount
 
 
 .. _gridtk: https://pypi.python.org/pypi/gridtk
diff --git a/doc/guide_cvpr14.rst b/doc/guide_cvpr14.rst
index 9a23cd2..5dd152d 100644
--- a/doc/guide_cvpr14.rst
+++ b/doc/guide_cvpr14.rst
@@ -64,11 +64,11 @@ To extract the mean green colors the face region and of
 the background across the video sequences of the defined database 
 in the configuration file, do the following::
 
-  $ ./bin/cvpr14_extract_face_and_bg_signals.py config.py -vv
+  $ ./bin/bob_rppg_cvpr14_extract_face_and_bg_signals.py config.py -vv
 
 To see the full options, including parameters and protocols, type:: 
 
-  $ ./bin/cvpr14_extract_face_and_bg_signals.py --help 
+  $ ./bin/bob_rppg_cvpr14_extract_face_and_bg_signals.py --help 
 
 Note that you can either pass parameters through command-line, or 
 by specififing them in the configuration file. Be aware that
@@ -80,11 +80,11 @@ the command-line overrides the configuration file though.
    You can speed it up using the gridtk_ toolbox (especially, if you're at Idiap). 
    For example::
 
-     $ ./bin/jman sub -t 3490 -- ./bin/cvpr14_extract_face_and_bg_signals. config.py
+     $ ./bin/jman sub -t 3490 -- ./bin/bob_rppg_cvpr14_extract_face_and_bg_signals. config.py
 
    The number of jobs (i.e. 3490) is given by typing::
      
-     $ ./bin/cvpr14_extract_signals.py cohface --gridcount
+     $ ./bin/bob_rppg_cvpr14_extract_face_and_bg_signals.py cohface --gridcount
 
 
 Step 2: Illumination Rectification
@@ -96,7 +96,7 @@ Normalized Linear Mean Square and is then removed from the face signal. To get
 the rectified green signal of the face area, you should execute the following
 script::
 
-  $ ./bin/cvpr14_illumination.py config.py -v
+  $ ./bin/bob_rppg_cvpr14_illumination.py config.py -v
 
 Again, parameters can be passed either through the configuration file or
 the command-line
@@ -113,8 +113,8 @@ channel on all the segment of all sequences. By default, the threshold is set su
 of all the segments will be retained. To get the signals where large motion has
 been eliminated, execute the following commands::
 
-  $ ./bin/cvpr14_motion.py cohface --save-threshold threshold.txt -vv
-  $ ./bin/cvpr14_motion.py cohface --load-threshold threshold.txt -vv
+  $ ./bin/bob_rppg_cvpr14_motion.py cohface --save-threshold threshold.txt -vv
+  $ ./bin/bob_rppg_cvpr14_motion.py cohface --load-threshold threshold.txt -vv
 
 
 Step 4: Filtering
@@ -129,7 +129,7 @@ window. Finally, a bandpass filter is applied to restrict the
 frequencies to the range corresponding to a plausible heart-rate. To filter the
 signal, you should execute the following command::
 
-  $ ./bin/cvpr14_filter.py cohface -vv
+  $ ./bin/bob_rppg_cvpr14_filter.py cohface -vv
 
 A Full Configuration File Example
 ---------------------------------
diff --git a/doc/guide_performance.rst b/doc/guide_performance.rst
index b8984e6..8713371 100644
--- a/doc/guide_performance.rst
+++ b/doc/guide_performance.rst
@@ -13,12 +13,7 @@ signal. The Welch's algorithm is applied to find the power spectrum of the
 signal, and the heart rate is found using peak detection in the frequency range
 of interest.  To obtain the heart-rate, you should do the following::
 
-  $ ./bin/rppg_frequency_analysis.py hci -vv
-
-This script normally takes data from a directory called ``pulse``
-and outputs data to a directory called ``heart-rate``. This output represents
-the end of the processing chain and contains the estimated heart-rate for every
-video sequence in the dataset.
+  $ ./bin/bob_rppg_base_get_heart_rate.py config.py -v
 
 
 Generating performance measures
@@ -27,7 +22,35 @@ Generating performance measures
 In order to get some insights on how good the computed heart-rates match the
 ground truth, you should execute the following script::
 
-  $ ./bin/rppg_compute_performance.py hci --indir heart-rate -v -P 
+  $ ./bin/bob_rppg_base_compute_performance.py config.py -v 
 
 This will output and save various statistics (Root Mean Square Error, 
-Pearson correlation) as well as figures (error distribution, scatter plot)
+Pearson correlation) as well as figures (error distribution, scatter plot).
+
+
+Again, these scripts rely on the use of configuration 
+files. An minimal example is given below:
+
+.. code-block:: python
+
+  import os, sys
+
+  import bob.db.hci_tagging
+  import bob.db.hci_tagging.driver
+
+  # DATABASE
+  if os.path.isdir(bob.db.hci_tagging.driver.DATABASE_LOCATION):
+    dbdir = bob.db.hci_tagging.driver.DATABASE_LOCATION
+  if dbdir == '':
+    print("You should provide a directory where the DB is located")
+    sys.exit()
+  database = bob.db.hci_tagging.Database()
+  protocol = 'cvpr14'
+
+  basedir = 'li-hci-cvpr14/'
+
+  # FREQUENCY ANALYSIS
+  hrdir = basedir + 'hr'
+  nsegments = 16
+  nfft = 8192
+
diff --git a/doc/guide_ssr.rst b/doc/guide_ssr.rst
index b993a26..d4237ab 100644
--- a/doc/guide_ssr.rst
+++ b/doc/guide_ssr.rst
@@ -36,11 +36,11 @@ After having applied the skin color filter, the full algorithm is applied,
 as described in Algorithm 1 in the paper. To get the pulse signals for
 all video in a database, do the following::
 
-  $ ./bin/ssr_pulse.py config.py -v
+  $ ./bin/bob_rppg_ssr_pulse.py config.py -v
 
 To see the full options, including parameters and protocols, type:: 
 
-  $ ./bin/ssr_pulse.py --help 
+  $ ./bin/bob_rppg_ssr_pulse.py --help 
 
 As you can see, the script takes a configuration file as argument. This
 configuration file is required to at least specify the database, but can also
@@ -86,11 +86,11 @@ given below.
    The execution of this script is very slow - mainly due to the face detection. 
    You can speed it up using the gridtk_ (especially, if you're at Idiap). For example::
 
-     $ ./bin/jman sub -t 3490 -- ./bin/ssr_pulse.py cohface
+     $ ./bin/jman sub -t 3490 -- ./bin/bob_rppg_ssr_pulse.py cohface
 
    The number of jobs (i.e. 3490) is given by typing::
      
-     $ ./bin/ssr_pulse.py cohface --gridcount
+     $ ./bin/bob_rppg_ssr_pulse.py cohface --gridcount
 
 
 .. _gridtk: https://pypi.python.org/pypi/gridtk
-- 
GitLab