From 6771bcd83cad3e756876f739486b7d0f314ee74c Mon Sep 17 00:00:00 2001 From: Laurent COLBOIS <lcolbois@.idiap.ch> Date: Mon, 21 Dec 2020 11:28:14 +0100 Subject: [PATCH] Added a test and description of the MultiFaceCrop --- bob/bio/face/preprocessor/FaceCrop.py | 51 +++++++++++++++++----- bob/bio/face/preprocessor/__init__.py | 2 +- bob/bio/face/test/data/cropped_bbox.hdf5 | Bin 0 -> 43008 bytes bob/bio/face/test/data/testimage_bbox.pos | 2 + bob/bio/face/test/test_preprocessors.py | 50 +++++++++++++++++++++ 5 files changed, 94 insertions(+), 11 deletions(-) create mode 100644 bob/bio/face/test/data/cropped_bbox.hdf5 create mode 100644 bob/bio/face/test/data/testimage_bbox.pos diff --git a/bob/bio/face/preprocessor/FaceCrop.py b/bob/bio/face/preprocessor/FaceCrop.py index 9b04b9de..23cfc249 100644 --- a/bob/bio/face/preprocessor/FaceCrop.py +++ b/bob/bio/face/preprocessor/FaceCrop.py @@ -373,12 +373,26 @@ class FaceCrop(Base): self._init_non_pickables() -class MultiFaceCrop(TransformerMixin, BaseEstimator): +class MultiFaceCrop(Base): + """ Wraps around FaceCrop to enable a dynamical cropper that can handle several annotation types. + Initialization and usage is similar to the FaceCrop, but the main difference here is that one specifies + a *list* of cropped_positions, and optionally a *list* of associated fixed positions. + + For each set of cropped_positions in the list, a new FaceCrop will be instanciated that handles this + exact set of annotations. + When calling the *transform* method, the MultiFaceCrop matches each sample to its associated cropper + based on the received annotation, then performs the cropping of each subset, and finally gathers the results. + + In case of ambiguity (when no cropper is a match for the received annotations, or when several croppers + match the received annotations), raises a ValueError. + + """ + def __init__( self, cropped_image_size, cropped_positions_list, - fixed_positions=None, + fixed_positions_list=None, mask_sigma=None, mask_neighbors=5, mask_seed=None, @@ -388,9 +402,14 @@ class MultiFaceCrop(TransformerMixin, BaseEstimator): ): assert isinstance(cropped_positions_list, list) + if fixed_positions_list is None: + fixed_positions_list = [None] * len(cropped_positions_list) + assert isinstance(fixed_positions_list, list) self.croppers = {} - for cropped_positions in cropped_positions_list: + for cropped_positions, fixed_positions in zip( + cropped_positions_list, fixed_positions_list + ): assert len(cropped_positions) == 2 self.croppers[tuple(cropped_positions)] = FaceCrop( cropped_image_size, @@ -408,26 +427,38 @@ class MultiFaceCrop(TransformerMixin, BaseEstimator): subsets = {k: {"X": [], "annotations": []} for k in self.croppers.keys()} def assign(X_elem, annotations_elem): + # Assign a single sample to its matching cropper + + # Compare the received annotations keys to the cropped_positions keys of each cropper valid_keys = [ k for k in self.croppers.keys() if set(k).issubset(set(annotations_elem.keys())) ] - assert ( - len(valid_keys) == 1 - ), "Cropper selection from the annotations is ambiguous ({} valid croppers)".format( - len(valid_keys) - ) - subsets[valid_keys[0]]["X"].append(X_elem) - subsets[valid_keys[0]]["annotations"].append(annotations_elem) + # Ensure exactly one cropper is a match + if len(valid_keys) != 1: + raise ValueError( + "Cropper selection from the annotations is ambiguous ({} valid croppers)".format( + len(valid_keys) + ) + ) + else: + # Assign the sample to this particuler cropper + cropper_key = valid_keys[0] + subsets[cropper_key]["X"].append(X_elem) + subsets[cropper_key]["annotations"].append(annotations_elem) + + # Assign each sample to its matching cropper for X_elem, annotations_elem in zip(X, annotations): assign(X_elem, annotations_elem) + # Call each FaceCrop on its sample subset transformed_subsets = { k: self.croppers[k].transform(**subsets[k]) for k in subsets.keys() } + # Gather the results return [item for sublist in transformed_subsets.values() for item in sublist] def fit(self, X, y=None): diff --git a/bob/bio/face/preprocessor/__init__.py b/bob/bio/face/preprocessor/__init__.py index 61ac1346..1a0c9b64 100644 --- a/bob/bio/face/preprocessor/__init__.py +++ b/bob/bio/face/preprocessor/__init__.py @@ -1,5 +1,5 @@ from .Base import Base -from .FaceCrop import FaceCrop +from .FaceCrop import FaceCrop, MultiFaceCrop from .TanTriggs import TanTriggs from .INormLBP import INormLBP diff --git a/bob/bio/face/test/data/cropped_bbox.hdf5 b/bob/bio/face/test/data/cropped_bbox.hdf5 new file mode 100644 index 0000000000000000000000000000000000000000..a0048061a5901e7af7d5278cd0430f79294254bd GIT binary patch literal 43008 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 literal 0 HcmV?d00001 diff --git a/bob/bio/face/test/data/testimage_bbox.pos b/bob/bio/face/test/data/testimage_bbox.pos new file mode 100644 index 00000000..933a7652 --- /dev/null +++ b/bob/bio/face/test/data/testimage_bbox.pos @@ -0,0 +1,2 @@ +topleft 85 130 +bottomright 270 330 diff --git a/bob/bio/face/test/test_preprocessors.py b/bob/bio/face/test/test_preprocessors.py index 4b02fc8c..51e6675f 100644 --- a/bob/bio/face/test/test_preprocessors.py +++ b/bob/bio/face/test/test_preprocessors.py @@ -151,6 +151,56 @@ def test_face_crop(): # reset the configuration, so that later tests don't get screwed. cropper.color_channel = "gray" +def test_multi_face_crop(): + # read input + image = _image() + eye_annotation, bbox_annotation = [ + bob.db.base.read_annotation_file( + pkg_resources.resource_filename("bob.bio.face.test", "data/" + filename + ".pos"), + "named" + ) + for filename in ["testimage", "testimage_bbox"] + ] + + # define the preprocessor + cropper = bob.bio.face.preprocessor.MultiFaceCrop( + cropped_image_size=(CROPPED_IMAGE_HEIGHT, CROPPED_IMAGE_WIDTH), + cropped_positions_list=[ + {'leye': LEFT_EYE_POS, 'reye': RIGHT_EYE_POS}, + {'topleft': (0, 0), 'bottomright': (CROPPED_IMAGE_HEIGHT, CROPPED_IMAGE_WIDTH)} + ] + ) + + # execute face cropper + eye_reference, bbox_reference = [ + pkg_resources.resource_filename( + "bob.bio.face.test", "data/" + filename + ".hdf5" + ) + for filename in ["cropped", "cropped_bbox"] + ] + + eye_cropped, bbox_cropped = cropper.transform([image, image], [eye_annotation, bbox_annotation]) + + # Compare the cropped results to the reference + _compare(eye_cropped, eye_reference) + _compare(bbox_cropped, bbox_reference) + + # test a ValueError is raised if the annotations don't match any cropper + try: + annot = dict(landmark_A=(60, 60), landmark_B=(120, 120)) + cropper.transform([image], [annot]) + assert 0, "MultiFaceCrop did not raise a ValueError for annotations matching no cropper" + except ValueError: + pass + + # test a ValueError is raised if the annotations match several croppers + try: + annot = {**eye_annotation, **bbox_annotation} + cropper.transform([image], [annot]) + assert 0, "MultiFaceCrop did not raise a ValueError for annotations matching several croppers" + except ValueError: + pass + def test_tan_triggs(): # read input -- GitLab