Coverage for src/bob/bio/face/preprocessor/INormLBP.py: 87%
23 statements
« prev ^ index » next coverage.py v7.6.0, created at 2024-07-13 00:04 +0200
« prev ^ index » next coverage.py v7.6.0, created at 2024-07-13 00:04 +0200
1#!/usr/bin/env python
2# vim: set fileencoding=utf-8 :
3# @author: Manuel Guenther <Manuel.Guenther@idiap.ch>
4# @author: Tiago de Freitas Pereira <tiago.pereira@idiap.ch>
6import skimage
8from .Base import Base
9from .utils import load_cropper
12class INormLBP(Base):
13 """
14 Performs I-Norm LBP on the given image.
16 The supported LBP methods are the ones available on.
17 https://scikit-image.org/docs/dev/api/skimage.feature.html#skimage.feature.local_binary_pattern
21 Parameters
22 ----------
24 face_cropper : str or :py:class:`bob.bio.face.preprocessor.FaceCrop` or :py:class:`bob.bio.face.preprocessor.FaceDetect` or ``None``
25 The face image cropper that should be applied to the image.
26 It might be specified as a registered resource, a configuration file, or an instance of a preprocessor.
28 .. note:: The given class needs to contain a ``crop_face`` method.
30 neighbors : int
31 Number of circularly symmetric neighbor set points (quantization of the angular space)
33 radius : int
34 The radius of the LBP features to extract
36 method : str
37 The type of LBP to use. https://scikit-image.org/docs/dev/api/skimage.feature.html#skimage.feature.local_binary_pattern
40 """
42 def __init__(
43 self,
44 face_cropper,
45 neighbors=8,
46 radius=2, # Radius of the LBP
47 method="default", # Type of LBP
48 **kwargs,
49 ):
50 # call base class constructors
51 Base.__init__(self, **kwargs)
53 self.face_cropper = face_cropper
54 self.radius = radius
55 self.neighbors = neighbors
56 self.method = method
57 self.cropper = load_cropper(face_cropper)
59 def transform(self, X, annotations=None):
60 """__call__(image, annotations = None) -> face
62 Aligns the given image according to the given annotations.
64 First, the desired color channel is extracted from the given image.
65 Afterward, the face is eventually cropped using the ``face_cropper`` specified in the constructor.
66 Then, the image is photometrically enhanced by extracting LBP features [HRM06]_.
67 Finally, the resulting face is converted to the desired data type.
69 **Parameters:**
71 image : 2D or 3D :py:class:`numpy.ndarray`
72 The face image to be processed.
74 annotations : dict or ``None``
75 The annotations that fit to the given image.
76 Might be ``None``, when the ``face_cropper`` is ``None`` or of type :py:class:`FaceDetect`.
78 **Returns:**
80 face : 2D :py:class:`numpy.ndarray`
81 The cropped and photometrically enhanced face.
82 """
84 def _crop_one_sample(image, annotations=None):
85 if self.cropper is not None:
86 # TODO: USE THE TAG `ALLOW_ANNOTATIONS`
87 image = (
88 self.cropper.transform([image])
89 if annotations is None
90 else self.cropper.transform([image], [annotations])
91 )
92 # LBP's doesn't work with batches, so we have to work this out
93 # Also, we change the color channel *after* cropping : some croppers use MTCNN internally, that works on multichannel images
94 image = self.change_color_channel(image[0])
95 image = skimage.feature.local_binary_pattern(
96 image, P=self.neighbors, R=self.radius, method=self.method
97 )
98 else:
99 # Handle with the cropper is None
100 image = self.change_color_channel(image)
101 # image = self.lbp_extractor(image)
102 image = skimage.feature.local_binary_pattern(
103 image, P=self.neighbors, R=self.radius, method=self.method
104 )
106 return self.data_type(image)
108 if annotations is None:
109 return [_crop_one_sample(data) for data in X]
110 else:
111 return [
112 _crop_one_sample(data, annot)
113 for data, annot in zip(X, annotations)
114 ]