From db78cba9d9e2148eba5df52e7236a13d9ca439b1 Mon Sep 17 00:00:00 2001
From: Olegs NIKISINS <onikisins@italix03.idiap.ch>
Date: Thu, 13 Jul 2017 09:09:17 +0200
Subject: [PATCH] Added unit tests for remaining preprocessors: VideoFaceCrop,
 FrameDifference

---
 bob/pad/face/test/test.py | 156 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 155 insertions(+), 1 deletion(-)

diff --git a/bob/pad/face/test/test.py b/bob/pad/face/test/test.py
index 7ec3460f..4ed747bf 100644
--- a/bob/pad/face/test/test.py
+++ b/bob/pad/face/test/test.py
@@ -13,12 +13,18 @@ from bob.io.base import load
 
 import bob.io.image  # for image loading functionality
 
+import bob.bio.video
+
 from bob.ip.color import rgb_to_gray
 
 from ..extractor import LBPHistogram
 
 from ..preprocessor import ImageFaceCrop
 
+from ..preprocessor import VideoFaceCrop
+
+from ..preprocessor import FrameDifference
+
 #==============================================================================
 def test_lbp_histogram():
     lbp = LBPHistogram()
@@ -48,4 +54,152 @@ def test_image_face_crop():
     face = preprocessor(image, annotations)
 
     assert face.shape == (3, 64, 64)
-    assert np.sum(face) == 1215525
\ No newline at end of file
+    assert np.sum(face) == 1215525
+
+
+#==============================================================================
+def convert_image_to_video_data(image, annotations, n_frames):
+    """
+    Convert input image to video and image annotations to frame annotations.
+
+    **Parameters:**
+
+    ``image`` : 2D or 3D :py:class:`numpy.ndarray`
+        Input image (RGB or gray-scale).
+
+    ``annotations`` : :py:class:`dict`
+        A dictionary containing annotations of the face bounding box.
+        Dictionary must be as follows ``{'topleft': (row, col), 'bottomright': (row, col)}``
+
+    ``n_frames`` : :py:class:`int`
+        Number of frames in the output video
+
+    **Returns:**
+
+    ``frame_container`` : FrameContainer
+        Video data stored in the FrameContainer, see ``bob.bio.video.utils.FrameContainer``
+        for further details.
+
+    ``video_annotations`` : :py:class:`dict`
+        A dictionary containing the annotations for each frame in the video.
+        Dictionary structure: ``annotations = {'1': frame1_dict, '2': frame1_dict, ...}``.
+        Where ``frameN_dict = {'topleft': (row, col), 'bottomright': (row, col)}``
+        is the dictionary defining the coordinates of the face bounding box in frame N.
+    """
+
+    frame_container = bob.bio.video.FrameContainer() # initialize the FrameContainer
+
+    video_annotations = {}
+
+    for idx, fn in enumerate( range(0, n_frames) ):
+
+        frame_container.add(idx, image) # add current frame to FrameContainer
+
+        video_annotations[str(idx)] = annotations
+
+    return frame_container, video_annotations
+
+
+#==============================================================================
+def test_video_face_crop():
+    """
+    Test VideoFaceCrop preprocessor, which is designed to crop faces in the video.
+    """
+
+    image = load(datafile('test_image.png', 'bob.pad.face.test'))
+    annotations = {'topleft': (95, 155), 'bottomright': (215, 265)}
+
+    CROPPED_IMAGE_SIZE = (64, 64) # The size of the resulting face
+    CROPPED_POSITIONS = {'topleft' : (0,0) , 'bottomright' : CROPPED_IMAGE_SIZE}
+    FIXED_POSITIONS = None
+    MASK_SIGMA = None             # The sigma for random values areas outside image
+    MASK_NEIGHBORS = 5            # The number of neighbors to consider while extrapolating
+    MASK_SEED = None              # The seed for generating random values during extrapolation
+    CHECK_FACE_SIZE_FLAG = True   # Check the size of the face
+    MIN_FACE_SIZE = 50            # Minimal possible size of the face
+    USE_LOCAL_CROPPER_FLAG = True # Use the local face cropping class (identical to Ivana's paper)
+    COLOR_CHANNEL = 'gray'        # Convert image to gray-scale format
+
+    preprocessor = VideoFaceCrop(cropped_image_size = CROPPED_IMAGE_SIZE,
+                                 cropped_positions = CROPPED_POSITIONS,
+                                 fixed_positions = FIXED_POSITIONS,
+                                 mask_sigma = MASK_SIGMA,
+                                 mask_neighbors = MASK_NEIGHBORS,
+                                 mask_seed = MASK_SEED,
+                                 check_face_size_flag = CHECK_FACE_SIZE_FLAG,
+                                 min_face_size = MIN_FACE_SIZE,
+                                 use_local_cropper_flag = USE_LOCAL_CROPPER_FLAG,
+                                 color_channel = COLOR_CHANNEL)
+
+    video, annotations = convert_image_to_video_data(image, annotations, 20)
+
+    faces = preprocessor(frames = video, annotations = annotations)
+
+    assert len(faces) == 20
+    assert faces[0][1].shape == (64, 64)
+    assert faces[-1][1].shape == (64, 64)
+    assert np.sum(faces[0][1]) == 429158
+    assert np.sum(faces[-1][1]) == 429158
+
+
+#==============================================================================
+def test_frame_difference():
+    """
+    Test FrameDifference preprocessor computing frame differences for both
+    facial and non-facial/background regions.
+    """
+
+    image = load(datafile('test_image.png', 'bob.pad.face.test'))
+    annotations = {'topleft': (95, 155), 'bottomright': (215, 265)}
+
+    n_frames = 20
+
+    video, annotations = convert_image_to_video_data(image, annotations, n_frames)
+
+    NUMBER_OF_FRAMES = None # process all frames
+    CHECK_FACE_SIZE_FLAG = True # Check size of the face
+    MIN_FACE_SIZE = 50 # Minimal size of the face to consider
+
+    preprocessor = FrameDifference(number_of_frames = NUMBER_OF_FRAMES,
+                                   check_face_size_flag = CHECK_FACE_SIZE_FLAG,
+                                   min_face_size = MIN_FACE_SIZE)
+
+    diff = preprocessor(frames = video, annotations = annotations)
+
+    assert diff.shape == (n_frames-1, 2)
+    assert (diff==0).all()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-- 
GitLab