From ed7e9eb7972620b9d185b9ca815905ade1f379f9 Mon Sep 17 00:00:00 2001
From: Olegs NIKISINS <onikisins@italix03.idiap.ch>
Date: Tue, 16 May 2017 15:17:20 +0200
Subject: [PATCH] Added VideoLBPHistogram extractor and corresponding configs
 and entry points

---
 bob/pad/face/config/extractor/__init__.py     |   0
 .../config/extractor/video_lbp_histogram.py   |  22 +++
 bob/pad/face/extractor/LBPHistogram.py        |   2 +-
 bob/pad/face/extractor/VideoLBPHistogram.py   | 151 ++++++++++++++++++
 bob/pad/face/extractor/__init__.py            |   2 +
 bob/pad/face/preprocessor/VideoFaceCrop.py    |   6 +-
 setup.py                                      |   5 +
 7 files changed, 184 insertions(+), 4 deletions(-)
 create mode 100644 bob/pad/face/config/extractor/__init__.py
 create mode 100644 bob/pad/face/config/extractor/video_lbp_histogram.py
 create mode 100644 bob/pad/face/extractor/VideoLBPHistogram.py

diff --git a/bob/pad/face/config/extractor/__init__.py b/bob/pad/face/config/extractor/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/bob/pad/face/config/extractor/video_lbp_histogram.py b/bob/pad/face/config/extractor/video_lbp_histogram.py
new file mode 100644
index 00000000..dbc51bbf
--- /dev/null
+++ b/bob/pad/face/config/extractor/video_lbp_histogram.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+from bob.pad.face.extractor import VideoLBPHistogram
+
+
+#=======================================================================================
+# Define instances here:
+
+lbptype='regular'
+elbptype='regular'
+rad=3
+neighbors=8
+circ=False
+dtype=None
+
+video_lbp_histogram_extractor_n8r3 = VideoLBPHistogram(lbptype=lbptype,
+                                                       elbptype=elbptype,
+                                                       rad=rad,
+                                                       neighbors=neighbors,
+                                                       circ=circ,
+                                                       dtype=dtype)
+
diff --git a/bob/pad/face/extractor/LBPHistogram.py b/bob/pad/face/extractor/LBPHistogram.py
index c66d7b46..ee0a583b 100644
--- a/bob/pad/face/extractor/LBPHistogram.py
+++ b/bob/pad/face/extractor/LBPHistogram.py
@@ -87,7 +87,7 @@ class LBPHistogram(Extractor):
                     elbp_type=elbps[elbptype])
             else:  # we assume neighbors==8 in this case
                 lbp = bob.ip.base.LBP(
-                    neighbors=16, circular=circ, radius=rad, to_average=mct,
+                    neighbors=8, circular=circ, radius=rad, to_average=mct,
                     elbp_type=elbps[elbptype])
 
         self.dtype = dtype
diff --git a/bob/pad/face/extractor/VideoLBPHistogram.py b/bob/pad/face/extractor/VideoLBPHistogram.py
new file mode 100644
index 00000000..a1e1f8c9
--- /dev/null
+++ b/bob/pad/face/extractor/VideoLBPHistogram.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python2
+# -*- coding: utf-8 -*-
+"""
+Created on Tue May 16 13:48:43 2017
+
+@author: Olegs Nikisins
+"""
+
+#==============================================================================
+# Import what is needed here:
+
+from bob.bio.base.extractor import Extractor
+
+from bob.pad.face.extractor import LBPHistogram
+
+import bob.bio.video
+
+
+#==============================================================================
+# Main body:
+
+class VideoLBPHistogram(Extractor, object):
+    """
+    This class is designed to extract LBP histograms for each frame in the input
+    video sequence/container.
+
+    **Parameters:**
+
+    ``lbptype`` : :py:class:`str`
+        The type of the LBP operator ("regular", "uniform" or "riu2").
+        Default: uniform.
+
+    ``elbptype`` : :py:class:`str`
+        The type of extended version of LBP (regular if not extended version
+        is used, otherwise transitional, direction_coded or modified).
+        Default: regular.
+
+    ``rad`` : :py:class:`float`
+        The radius of the circle on which the points are taken (for circular
+        LBP). Default: 1
+
+    ``neighbors`` : :py:class:`int`
+        The number of points around the central point on which LBP is
+        computed. Possible options: (4, 8, 16). Default: 8.
+
+    ``circ`` : :py:class:`bool`
+        Set to True if circular LBP is needed. Default: False.
+
+    ``dtype`` : numpy.dtype
+        If specified in the constructor, the resulting features will have
+        that type of data. Default: None.
+    """
+
+    #==========================================================================
+    def __init__(self,
+                 lbptype='uniform',
+                 elbptype='regular',
+                 rad=1,
+                 neighbors=8,
+                 circ=False,
+                 dtype=None):
+
+
+        super(VideoLBPHistogram, self).__init__(lbptype = lbptype,
+                                                elbptype = elbptype,
+                                                rad = rad,
+                                                neighbors = neighbors,
+                                                circ = circ,
+                                                dtype = dtype)
+
+        self.lbptype = lbptype
+        self.elbptype = elbptype
+        self.rad = rad
+        self.neighbors = neighbors
+        self.circ = circ
+        self.dtype = dtype
+
+        # extractor to process a single image/frame:
+        extractor = LBPHistogram(lbptype=lbptype,
+                                 elbptype=elbptype,
+                                 rad=rad,
+                                 neighbors=neighbors,
+                                 circ=circ,
+                                 dtype=dtype)
+
+        # a wrapper allowing to apply above extractor to the whole video:
+        self.video_extractor = bob.bio.video.extractor.Wrapper(extractor)
+
+
+    #==========================================================================
+    def __call__(self, frames):
+        """
+        Extracts LBP histogram for each frame in the input video sequence/container.s
+
+        **Parameters:**
+
+        ``image`` : FrameContainer
+            Video data stored in the FrameContainer, see ``bob.bio.video.utils.FrameContainer``
+            for further details.
+
+        **Returns:**
+
+        ``lbp_histograms`` : FrameContainer
+            LBP histograms for each frame stored in the FrameContainer.
+        """
+
+        lbp_histograms = self.video_extractor(frames = frames)
+
+        return lbp_histograms
+
+
+    #==========================================================================
+    def write_feature(self, frames, file_name):
+        """
+        Writes the given data (that has been generated using the __call__ function of this class) to file.
+        This method overwrites the write_data() method of the Extractor class.
+
+        **Parameters:**
+
+        ``frames`` :
+            Data returned by the __call__ method of the class.
+
+        ``file_name`` : :py:class:`str`
+            Name of the file.
+        """
+
+        self.video_extractor.write_feature(frames, file_name)
+
+
+    #==========================================================================
+    def read_feature(self, file_name):
+        """
+        Reads the preprocessed data from file.
+        This method overwrites the read_data() method of the Extractor class.
+
+        **Parameters:**
+
+        ``file_name`` : :py:class:`str`
+            Name of the file.
+
+        **Returns:**
+
+        ``frames`` : :py:class:`bob.bio.video.FrameContainer`
+            Frames stored in the frame container.
+        """
+
+        frames = self.video_extractor.read_feature(file_name)
+
+        return frames
+
+
diff --git a/bob/pad/face/extractor/__init__.py b/bob/pad/face/extractor/__init__.py
index 4a9104db..1066793c 100644
--- a/bob/pad/face/extractor/__init__.py
+++ b/bob/pad/face/extractor/__init__.py
@@ -1,4 +1,5 @@
 from .LBPHistogram import LBPHistogram
+from .VideoLBPHistogram import VideoLBPHistogram
 
 
 def __appropriate__(*args):
@@ -21,5 +22,6 @@ def __appropriate__(*args):
 
 __appropriate__(
     LBPHistogram,
+    VideoLBPHistogram,
 )
 __all__ = [_ for _ in dir() if not _.startswith('_')]
diff --git a/bob/pad/face/preprocessor/VideoFaceCrop.py b/bob/pad/face/preprocessor/VideoFaceCrop.py
index 421b6dde..2ef76572 100644
--- a/bob/pad/face/preprocessor/VideoFaceCrop.py
+++ b/bob/pad/face/preprocessor/VideoFaceCrop.py
@@ -3,7 +3,7 @@
 """
 Created on Fri May 12 14:14:23 2017
 
-@author: onikisins
+@author: Olegs Nikisins
 """
 #==============================================================================
 # Import what is needed here:
@@ -106,7 +106,7 @@ class VideoFaceCrop(Preprocessor, object):
 
         **Parameters:**
 
-        ``image`` : FrameContainer
+        ``frames`` : FrameContainer
             Video data stored in the FrameContainer, see ``bob.bio.video.utils.FrameContainer``
             for further details.
 
@@ -149,7 +149,7 @@ class VideoFaceCrop(Preprocessor, object):
     def read_data( self, file_name ):
         """
         Reads the preprocessed data from file.
-        his method overwrites the read_data() method of the Preprocessor class.
+        This method overwrites the read_data() method of the Preprocessor class.
 
         **Parameters:**
 
diff --git a/setup.py b/setup.py
index 7b46b14a..a9f9101c 100644
--- a/setup.py
+++ b/setup.py
@@ -103,6 +103,11 @@ setup(
             'video-face-crop-preproc-100 = bob.pad.face.config.preprocessor.video_face_crop:video_face_crop_preproc_100_100',
             ],
 
+        # registered preprocessors:
+        'bob.pad.extractor': [
+            'video-lbp-histogram-extractor-n8r3 = bob.pad.face.config.extractor.video_lbp_histogram:video_lbp_histogram_extractor_n8r3',
+            ],
+
         # registered grid configurations:
         'bob.pad.grid': [
             'idiap = bob.pad.face.config.grid:idiap',
-- 
GitLab