From d85be042e7566613d82831d196ab36d25139d5d6 Mon Sep 17 00:00:00 2001 From: Amir MOHAMMADI <amir.mohammadi@idiap.ch> Date: Tue, 1 Jun 2021 14:05:35 +0200 Subject: [PATCH] merge the two helpers and rename to utils --- bob/bio/face/__init__.py | 1 + .../config/baseline/arcface_insightface.py | 2 +- bob/bio/face/config/baseline/dummy.py | 2 +- .../config/baseline/facenet_sanderberg.py | 2 +- bob/bio/face/config/baseline/gabor_graph.py | 2 +- .../inception_resnetv1_casiawebface.py | 2 +- .../baseline/inception_resnetv1_msceleb.py | 2 +- .../inception_resnetv2_casiawebface.py | 2 +- .../baseline/inception_resnetv2_msceleb.py | 2 +- bob/bio/face/config/baseline/lda.py | 2 +- bob/bio/face/config/baseline/lgbphs.py | 2 +- .../mobilenetv2_msceleb_arcface_2021.py | 2 +- .../baseline/resnet50_msceleb_arcface_2021.py | 2 +- .../baseline/resnet50_vgg2_arcface_2021.py | 2 +- bob/bio/face/config/baseline/templates.py | 2 +- .../config/baseline/tf2_inception_resnet.py | 2 +- bob/bio/face/helpers.py | 72 ---------------- .../{config/baseline/helpers.py => utils.py} | 83 +++++++++++++++++-- doc/faq.rst | 5 +- doc/plot/default_crops.py | 2 +- 20 files changed, 97 insertions(+), 96 deletions(-) delete mode 100644 bob/bio/face/helpers.py rename bob/bio/face/{config/baseline/helpers.py => utils.py} (78%) diff --git a/bob/bio/face/__init__.py b/bob/bio/face/__init__.py index 4f3858c5..9bda18df 100644 --- a/bob/bio/face/__init__.py +++ b/bob/bio/face/__init__.py @@ -4,6 +4,7 @@ from . import algorithm from . import script from . import database from . import annotator +from . import utils from . import test diff --git a/bob/bio/face/config/baseline/arcface_insightface.py b/bob/bio/face/config/baseline/arcface_insightface.py index dfe1d043..3e018121 100644 --- a/bob/bio/face/config/baseline/arcface_insightface.py +++ b/bob/bio/face/config/baseline/arcface_insightface.py @@ -1,5 +1,5 @@ from bob.bio.face.embeddings.mxnet_models import ArcFaceInsightFace -from bob.bio.face.config.baseline.helpers import lookup_config_from_database +from bob.bio.face.utils import lookup_config_from_database from bob.bio.face.config.baseline.templates import arcface_baseline annotation_type, fixed_positions, memory_demanding = lookup_config_from_database( diff --git a/bob/bio/face/config/baseline/dummy.py b/bob/bio/face/config/baseline/dummy.py index eaa993d3..9c407c8e 100644 --- a/bob/bio/face/config/baseline/dummy.py +++ b/bob/bio/face/config/baseline/dummy.py @@ -5,7 +5,7 @@ from bob.bio.base.pipelines.vanilla_biometrics import ( VanillaBiometricsPipeline, ) from bob.pipelines.transformers import SampleLinearize -from bob.bio.face.config.baseline.helpers import lookup_config_from_database +from bob.bio.face.utils import lookup_config_from_database annotation_type, fixed_positions, memory_demanding = lookup_config_from_database() diff --git a/bob/bio/face/config/baseline/facenet_sanderberg.py b/bob/bio/face/config/baseline/facenet_sanderberg.py index 73c3d687..510d9287 100644 --- a/bob/bio/face/config/baseline/facenet_sanderberg.py +++ b/bob/bio/face/config/baseline/facenet_sanderberg.py @@ -1,7 +1,7 @@ from bob.bio.face.embeddings.tf2_inception_resnet import ( FaceNetSanderberg_20170512_110547, ) -from bob.bio.face.config.baseline.helpers import lookup_config_from_database +from bob.bio.face.utils import lookup_config_from_database from bob.bio.face.config.baseline.templates import facenet_baseline annotation_type, fixed_positions, memory_demanding = lookup_config_from_database( diff --git a/bob/bio/face/config/baseline/gabor_graph.py b/bob/bio/face/config/baseline/gabor_graph.py index 2a6925a2..b21d10ae 100644 --- a/bob/bio/face/config/baseline/gabor_graph.py +++ b/bob/bio/face/config/baseline/gabor_graph.py @@ -3,7 +3,7 @@ from bob.bio.base.pipelines.vanilla_biometrics import ( VanillaBiometricsPipeline, BioAlgorithmLegacy, ) -from bob.bio.face.config.baseline.helpers import ( +from bob.bio.face.utils import ( lookup_config_from_database, legacy_default_cropping, make_cropper, diff --git a/bob/bio/face/config/baseline/inception_resnetv1_casiawebface.py b/bob/bio/face/config/baseline/inception_resnetv1_casiawebface.py index b3301dcd..149c0742 100644 --- a/bob/bio/face/config/baseline/inception_resnetv1_casiawebface.py +++ b/bob/bio/face/config/baseline/inception_resnetv1_casiawebface.py @@ -1,7 +1,7 @@ from bob.bio.face.embeddings.tf2_inception_resnet import ( InceptionResnetv1_Casia_CenterLoss_2018, ) -from bob.bio.face.config.baseline.helpers import lookup_config_from_database +from bob.bio.face.utils import lookup_config_from_database from bob.bio.face.config.baseline.templates import facenet_baseline annotation_type, fixed_positions, memory_demanding = lookup_config_from_database( diff --git a/bob/bio/face/config/baseline/inception_resnetv1_msceleb.py b/bob/bio/face/config/baseline/inception_resnetv1_msceleb.py index 745b7bbd..f7ce09f7 100644 --- a/bob/bio/face/config/baseline/inception_resnetv1_msceleb.py +++ b/bob/bio/face/config/baseline/inception_resnetv1_msceleb.py @@ -1,7 +1,7 @@ from bob.bio.face.embeddings.tf2_inception_resnet import ( InceptionResnetv1_MsCeleb_CenterLoss_2018, ) -from bob.bio.face.config.baseline.helpers import lookup_config_from_database +from bob.bio.face.utils import lookup_config_from_database from bob.bio.face.config.baseline.templates import facenet_baseline diff --git a/bob/bio/face/config/baseline/inception_resnetv2_casiawebface.py b/bob/bio/face/config/baseline/inception_resnetv2_casiawebface.py index b1b066ac..eadd9154 100644 --- a/bob/bio/face/config/baseline/inception_resnetv2_casiawebface.py +++ b/bob/bio/face/config/baseline/inception_resnetv2_casiawebface.py @@ -1,7 +1,7 @@ from bob.bio.face.embeddings.tf2_inception_resnet import ( InceptionResnetv2_Casia_CenterLoss_2018, ) -from bob.bio.face.config.baseline.helpers import lookup_config_from_database +from bob.bio.face.utils import lookup_config_from_database from bob.bio.face.config.baseline.templates import facenet_baseline diff --git a/bob/bio/face/config/baseline/inception_resnetv2_msceleb.py b/bob/bio/face/config/baseline/inception_resnetv2_msceleb.py index f3e083b7..0be122d3 100644 --- a/bob/bio/face/config/baseline/inception_resnetv2_msceleb.py +++ b/bob/bio/face/config/baseline/inception_resnetv2_msceleb.py @@ -1,7 +1,7 @@ from bob.bio.face.embeddings.tf2_inception_resnet import ( InceptionResnetv2_MsCeleb_CenterLoss_2018, ) -from bob.bio.face.config.baseline.helpers import lookup_config_from_database +from bob.bio.face.utils import lookup_config_from_database from bob.bio.face.config.baseline.templates import facenet_baseline annotation_type, fixed_positions, memory_demanding = lookup_config_from_database( diff --git a/bob/bio/face/config/baseline/lda.py b/bob/bio/face/config/baseline/lda.py index e78eb76b..de1935cb 100644 --- a/bob/bio/face/config/baseline/lda.py +++ b/bob/bio/face/config/baseline/lda.py @@ -3,7 +3,7 @@ from bob.bio.base.pipelines.vanilla_biometrics import ( VanillaBiometricsPipeline, BioAlgorithmLegacy, ) -from bob.bio.face.config.baseline.helpers import ( +from bob.bio.face.utils import ( lookup_config_from_database, legacy_default_cropping, make_cropper, diff --git a/bob/bio/face/config/baseline/lgbphs.py b/bob/bio/face/config/baseline/lgbphs.py index 7b484a7f..b70b638a 100644 --- a/bob/bio/face/config/baseline/lgbphs.py +++ b/bob/bio/face/config/baseline/lgbphs.py @@ -3,7 +3,7 @@ from bob.bio.base.pipelines.vanilla_biometrics import ( VanillaBiometricsPipeline, BioAlgorithmLegacy, ) -from bob.bio.face.config.baseline.helpers import ( +from bob.bio.face.utils import ( lookup_config_from_database, legacy_default_cropping, make_cropper, diff --git a/bob/bio/face/config/baseline/mobilenetv2_msceleb_arcface_2021.py b/bob/bio/face/config/baseline/mobilenetv2_msceleb_arcface_2021.py index 04148407..23554948 100644 --- a/bob/bio/face/config/baseline/mobilenetv2_msceleb_arcface_2021.py +++ b/bob/bio/face/config/baseline/mobilenetv2_msceleb_arcface_2021.py @@ -1,5 +1,5 @@ from bob.bio.face.embeddings.mobilenet_v2 import MobileNetv2_MsCeleb_ArcFace_2021 -from bob.bio.face.config.baseline.helpers import lookup_config_from_database +from bob.bio.face.utils import lookup_config_from_database from bob.bio.face.config.baseline.templates import arcface_baseline diff --git a/bob/bio/face/config/baseline/resnet50_msceleb_arcface_2021.py b/bob/bio/face/config/baseline/resnet50_msceleb_arcface_2021.py index b67e65e5..0560a97a 100644 --- a/bob/bio/face/config/baseline/resnet50_msceleb_arcface_2021.py +++ b/bob/bio/face/config/baseline/resnet50_msceleb_arcface_2021.py @@ -1,5 +1,5 @@ from bob.bio.face.embeddings.resnet50 import Resnet50_MsCeleb_ArcFace_2021 -from bob.bio.face.config.baseline.helpers import lookup_config_from_database +from bob.bio.face.utils import lookup_config_from_database from bob.bio.face.config.baseline.templates import arcface_baseline diff --git a/bob/bio/face/config/baseline/resnet50_vgg2_arcface_2021.py b/bob/bio/face/config/baseline/resnet50_vgg2_arcface_2021.py index 1237cfef..64d6ec4c 100644 --- a/bob/bio/face/config/baseline/resnet50_vgg2_arcface_2021.py +++ b/bob/bio/face/config/baseline/resnet50_vgg2_arcface_2021.py @@ -1,5 +1,5 @@ from bob.bio.face.embeddings.resnet50 import Resnet50_VGG2_ArcFace_2021 -from bob.bio.face.config.baseline.helpers import lookup_config_from_database +from bob.bio.face.utils import lookup_config_from_database from bob.bio.face.config.baseline.templates import arcface_baseline diff --git a/bob/bio/face/config/baseline/templates.py b/bob/bio/face/config/baseline/templates.py index ed8b10e3..415ecd28 100644 --- a/bob/bio/face/config/baseline/templates.py +++ b/bob/bio/face/config/baseline/templates.py @@ -1,4 +1,4 @@ -from bob.bio.face.config.baseline.helpers import ( +from bob.bio.face.utils import ( dnn_default_cropping, embedding_transformer, ) diff --git a/bob/bio/face/config/baseline/tf2_inception_resnet.py b/bob/bio/face/config/baseline/tf2_inception_resnet.py index 54b408bb..38d78c53 100644 --- a/bob/bio/face/config/baseline/tf2_inception_resnet.py +++ b/bob/bio/face/config/baseline/tf2_inception_resnet.py @@ -1,6 +1,6 @@ from bob.extension import rc from bob.bio.face.embeddings.tf2_inception_resnet import InceptionResnetv2 -from bob.bio.face.config.baseline.helpers import lookup_config_from_database +from bob.bio.face.utils import lookup_config_from_database from bob.bio.face.config.baseline.templates import facenet_baseline annotation_type, fixed_positions, memory_demanding = lookup_config_from_database( diff --git a/bob/bio/face/helpers.py b/bob/bio/face/helpers.py deleted file mode 100644 index 9a3a2c97..00000000 --- a/bob/bio/face/helpers.py +++ /dev/null @@ -1,72 +0,0 @@ -from bob.bio.face.preprocessor import FaceCrop, MultiFaceCrop, Scale -import bob.bio.face.config.baseline.helpers as helpers - -def face_crop_solver( - cropped_image_size, - cropped_positions=None, - color_channel="rgb", - fixed_positions=None, - annotator=None, - dtype="uint8", -): - """ - Decide which face cropper to use. - """ - # If there's not cropped positions, just resize - if cropped_positions is None: - return Scale(cropped_image_size) - else: - # Detects the face and crops it without eye detection - if isinstance(cropped_positions, list): - return MultiFaceCrop( - cropped_image_size=cropped_image_size, - cropped_positions_list=cropped_positions, - fixed_positions_list=fixed_positions, - color_channel=color_channel, - dtype=dtype, - annotator=annotator, - ) - else: - return FaceCrop( - cropped_image_size=cropped_image_size, - cropped_positions=cropped_positions, - color_channel=color_channel, - fixed_positions=fixed_positions, - dtype=dtype, - annotator=annotator, - ) - - -def get_default_cropped_positions(mode, cropped_image_size, annotation_type): - """ - Computes the default cropped positions for the FaceCropper, - proportionally to the target image size - - - Parameters - ---------- - mode: str - Which default cropping to use. Available modes are : `legacy` (legacy baselines), `facenet`, `arcface`, - and `pad`. - - cropped_image_size : tuple - A tuple (HEIGHT, WIDTH) describing the target size of the cropped image. - - annotation_type: str - Type of annotations. Possible values are: `bounding-box`, `eyes-center` and None, or a combination of those as a list - - Returns - ------- - - cropped_positions: - The dictionary of cropped positions that will be feeded to the FaceCropper, or a list of such dictionaries if - ``annotation_type`` is a list - """ - if mode == "legacy": - return helpers.legacy_default_cropping(cropped_image_size, annotation_type) - elif mode in ["dnn", "facenet", "arcface"]: - return helpers.dnn_default_cropping(cropped_image_size, annotation_type) - elif mode == "pad": - return helpers.pad_default_cropping(cropped_image_size, annotation_type) - else: - raise ValueError("Unknown default cropping mode `{}`".format(mode)) diff --git a/bob/bio/face/config/baseline/helpers.py b/bob/bio/face/utils.py similarity index 78% rename from bob/bio/face/config/baseline/helpers.py rename to bob/bio/face/utils.py index 5a8cc944..988314f0 100644 --- a/bob/bio/face/config/baseline/helpers.py +++ b/bob/bio/face/utils.py @@ -1,9 +1,11 @@ -from sklearn.pipeline import make_pipeline -from bob.pipelines import wrap -from bob.bio.face import helpers -import numpy as np import logging +from .preprocessor import FaceCrop +from .preprocessor import MultiFaceCrop +from .preprocessor import Scale +from bob.pipelines import wrap +from sklearn.pipeline import make_pipeline + logger = logging.getLogger(__name__) @@ -237,7 +239,7 @@ def make_cropper( transform_extra_arguments for wrapping the cropper with a SampleWrapper. """ - face_cropper = helpers.face_crop_solver( + face_cropper = face_crop_solver( cropped_image_size=cropped_image_size, cropped_positions=cropped_positions, fixed_positions=fixed_positions, @@ -289,3 +291,74 @@ def embedding_transformer( ) return transformer + + +def face_crop_solver( + cropped_image_size, + cropped_positions=None, + color_channel="rgb", + fixed_positions=None, + annotator=None, + dtype="uint8", +): + """ + Decide which face cropper to use. + """ + # If there's not cropped positions, just resize + if cropped_positions is None: + return Scale(cropped_image_size) + else: + # Detects the face and crops it without eye detection + if isinstance(cropped_positions, list): + return MultiFaceCrop( + cropped_image_size=cropped_image_size, + cropped_positions_list=cropped_positions, + fixed_positions_list=fixed_positions, + color_channel=color_channel, + dtype=dtype, + annotator=annotator, + ) + else: + return FaceCrop( + cropped_image_size=cropped_image_size, + cropped_positions=cropped_positions, + color_channel=color_channel, + fixed_positions=fixed_positions, + dtype=dtype, + annotator=annotator, + ) + + +def get_default_cropped_positions(mode, cropped_image_size, annotation_type): + """ + Computes the default cropped positions for the FaceCropper, + proportionally to the target image size + + + Parameters + ---------- + mode: str + Which default cropping to use. Available modes are : `legacy` (legacy baselines), `facenet`, `arcface`, + and `pad`. + + cropped_image_size : tuple + A tuple (HEIGHT, WIDTH) describing the target size of the cropped image. + + annotation_type: str + Type of annotations. Possible values are: `bounding-box`, `eyes-center` and None, or a combination of those as a list + + Returns + ------- + + cropped_positions: + The dictionary of cropped positions that will be feeded to the FaceCropper, or a list of such dictionaries if + ``annotation_type`` is a list + """ + if mode == "legacy": + return legacy_default_cropping(cropped_image_size, annotation_type) + elif mode in ["dnn", "facenet", "arcface"]: + return dnn_default_cropping(cropped_image_size, annotation_type) + elif mode == "pad": + return pad_default_cropping(cropped_image_size, annotation_type) + else: + raise ValueError("Unknown default cropping mode `{}`".format(mode)) diff --git a/doc/faq.rst b/doc/faq.rst index cf281bd6..e52795bf 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -22,7 +22,7 @@ Some face embedding extractors work well on loosely cropped faces, while others We provide a few reasonable defaults that are used in our implemented baselines. They are accessible through a function as follows : :: - from bob.bio.face.helpers import get_default_cropped_positions + from bob.bio.face.utils import get_default_cropped_positions mode = 'legacy' cropped_image_size=(160, 160) annotation_type='eyes-center' @@ -31,7 +31,7 @@ We provide a few reasonable defaults that are used in our implemented baselines. There are currently three available modes : -* :code:`legacy` Tight crop, used in non neural-net baselines such as :code:`gabor-graph`, :code:`lgbphs` or :code:`lda`. +* :code:`legacy` Tight crop, used in non neural-net baselines such as :code:`gabor-graph`, :code:`lgbphs` or :code:`lda`. It is typically use with a 5:4 aspect ratio for the :code:`cropped_image_size` * :code:`dnn` Loose crop, used for neural-net baselines such as the ArcFace or FaceNet models. * :code:`pad` Tight crop used in some PAD baselines @@ -40,4 +40,3 @@ We present hereafter a visual example of those crops for the `eyes-center` annot .. plot:: plot/default_crops.py :include-source: True - \ No newline at end of file diff --git a/doc/plot/default_crops.py b/doc/plot/default_crops.py index 2507cd4f..c1b9ac6b 100644 --- a/doc/plot/default_crops.py +++ b/doc/plot/default_crops.py @@ -1,5 +1,5 @@ import bob.io.image -from bob.bio.face.helpers import get_default_cropped_positions +from bob.bio.face.utils import get_default_cropped_positions from bob.bio.face.preprocessor import FaceCrop import matplotlib.pyplot as plt -- GitLab