Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
bob.pad.face
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
bob
bob.pad.face
Commits
e1a7c88e
"README.md" did not exist on "c4455b5a1612935a12ec07a06f219bc654975e9a"
Commit
e1a7c88e
authored
6 years ago
by
Anjith GEORGE
Browse files
Options
Downloads
Patches
Plain Diff
Alignment for LightCNN
parent
91cc9f64
No related branches found
No related tags found
1 merge request
!75
Alignment for LightCNN
Pipeline
#23477
passed
6 years ago
Stage: build
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
bob/pad/face/preprocessor/FaceCropAlign.py
+129
-11
129 additions, 11 deletions
bob/pad/face/preprocessor/FaceCropAlign.py
with
129 additions
and
11 deletions
bob/pad/face/preprocessor/FaceCropAlign.py
+
129
−
11
View file @
e1a7c88e
...
@@ -19,6 +19,9 @@ import bob.ip.base
...
@@ -19,6 +19,9 @@ import bob.ip.base
import
importlib
import
importlib
import
bob.bio.face
# ==============================================================================
# ==============================================================================
def
auto_norm_image
(
data
,
annotations
,
n_sigma
=
3.0
,
norm_method
=
'
MAD
'
):
def
auto_norm_image
(
data
,
annotations
,
n_sigma
=
3.0
,
norm_method
=
'
MAD
'
):
...
@@ -76,6 +79,31 @@ def auto_norm_image(data, annotations, n_sigma=3.0, norm_method='MAD'):
...
@@ -76,6 +79,31 @@ def auto_norm_image(data, annotations, n_sigma=3.0, norm_method='MAD'):
return
data_n
return
data_n
def
get_mouth_center
(
lm
):
"""
This function returns the location of mouth center
**Parameters:**
``lm`` : :py:class:`numpy.ndarray`
A numpy array containing the coordinates of facial landmarks, (68X2)
**Returns:**
``mouth_center``
A tuple containing the location of mouth center
"""
# Mean position of eye corners as eye centers , casted to int()
mouth_center_t
=
(
lm
[
48
,
:]
+
lm
[
54
,
:])
/
2.0
mouth_center
=
(
int
(
mouth_center_t
[
1
]),
int
(
mouth_center_t
[
0
]))
return
mouth_center
# ==============================================================================
# ==============================================================================
def
get_eye_pos
(
lm
):
def
get_eye_pos
(
lm
):
...
@@ -108,6 +136,32 @@ def get_eye_pos(lm):
...
@@ -108,6 +136,32 @@ def get_eye_pos(lm):
return
right_eye
,
left_eye
return
right_eye
,
left_eye
def
get_eye_center
(
lm
):
"""
This function returns the location of eye_center, midpoint of left and right eye
**Parameters:**
``lm`` : :py:class:`numpy.ndarray`
A numpy array containing the coordinates of facial landmarks, (68X2)
**Returns:**
``eye_center``
A tuple containing the location of eye_center
"""
# Mean position of eye corners as eye centers , casted to int()
left_eye_t
=
(
lm
[
36
,
:]
+
lm
[
39
,
:])
/
2.0
right_eye_t
=
(
lm
[
42
,
:]
+
lm
[
45
,
:])
/
2.0
eye_center
=
(
int
((
left_eye_t
[
1
]
+
right_eye_t
[
1
])
/
2.0
),
int
((
left_eye_t
[
0
]
+
right_eye_t
[
0
])
/
2.0
))
return
eye_center
# ==============================================================================
# ==============================================================================
def
detect_face_landmarks_in_image
(
image
,
method
=
"
dlib
"
):
def
detect_face_landmarks_in_image
(
image
,
method
=
"
dlib
"
):
"""
"""
...
@@ -213,7 +267,7 @@ def detect_face_landmarks_in_image(image, method="dlib"):
...
@@ -213,7 +267,7 @@ def detect_face_landmarks_in_image(image, method="dlib"):
# ==========================================================================
# ==========================================================================
def
normalize_image_size_in_grayscale
(
image
,
annotations
,
def
normalize_image_size_in_grayscale
(
image
,
annotations
,
face_size
,
use_face_alignment
):
face_size
,
use_face_alignment
,
alignment_type
=
'
default
'
):
"""
"""
This function crops the face in the input Gray-scale image given annotations
This function crops the face in the input Gray-scale image given annotations
defining the face bounding box, and eye positions.
defining the face bounding box, and eye positions.
...
@@ -250,16 +304,56 @@ def normalize_image_size_in_grayscale(image, annotations,
...
@@ -250,16 +304,56 @@ def normalize_image_size_in_grayscale(image, annotations,
if
use_face_alignment
:
if
use_face_alignment
:
face_eyes_norm
=
bob
.
ip
.
base
.
FaceEyesNorm
(
eyes_distance
=
((
face_size
+
1
)
/
2.
),
crop_size
=
(
face_size
,
face_size
),
eyes_center
=
(
face_size
/
4.
,
(
face_size
-
0.5
)
/
2.
))
right_eye
,
left_eye
=
annotations
[
'
reye
'
],
annotations
[
'
leye
'
]
if
alignment_type
==
'
default
'
:
face_eyes_norm
=
bob
.
ip
.
base
.
FaceEyesNorm
(
eyes_distance
=
((
face_size
+
1
)
/
2.
),
crop_size
=
(
face_size
,
face_size
),
eyes_center
=
(
face_size
/
4.
,
(
face_size
-
0.5
)
/
2.
))
right_eye
,
left_eye
=
annotations
[
'
reye
'
],
annotations
[
'
leye
'
]
normalized_image
=
face_eyes_norm
(
image
,
right_eye
=
right_eye
,
left_eye
=
left_eye
)
normbbx
=
normalized_image
.
astype
(
'
uint8
'
)
elif
alignment_type
==
'
lightcnn
'
:
# This option overrides the facesize argument
# This is the size of the image that this model expects
CROPPED_IMAGE_HEIGHT
=
128
CROPPED_IMAGE_WIDTH
=
128
# eye positions for frontal images
RIGHT_EYE_POS
=
(
32
,
44
)
LEFT_EYE_POS
=
(
32
,
84
)
EYE_CENTER_POS
=
(
40
,
64
)
MOUTH_CENTER_POS
=
(
88
,
64
)
normalized_image
=
face_eyes_norm
(
image
,
right_eye
=
right_eye
,
left_eye
=
left_eye
)
lm
=
np
.
array
(
annotations
[
'
landmarks
'
]
)
normbbx
=
normalized_image
.
astype
(
'
uint8
'
)
mouth_center
=
get_mouth_center
(
lm
)
eye_center
=
get_eye_center
(
lm
)
annotations
[
'
eye_center
'
]
=
eye_center
annotations
[
'
mouth_center
'
]
=
mouth_center
light_cnn_face_cropper
=
bob
.
bio
.
face
.
preprocessor
.
FaceCrop
(
cropped_image_size
=
(
CROPPED_IMAGE_HEIGHT
,
CROPPED_IMAGE_WIDTH
),
cropped_positions
=
{
'
eye_center
'
:
EYE_CENTER_POS
,
'
mouth_center
'
:
MOUTH_CENTER_POS
})
normalized_image
=
light_cnn_face_cropper
(
image
,
annotations
=
annotations
)
normbbx
=
normalized_image
.
astype
(
'
uint8
'
)
else
:
print
(
'
The specified alignment method {} is not implemented!
'
.
format
(
alignment_type
))
else
:
else
:
...
@@ -278,7 +372,7 @@ def normalize_image_size_in_grayscale(image, annotations,
...
@@ -278,7 +372,7 @@ def normalize_image_size_in_grayscale(image, annotations,
# ==========================================================================
# ==========================================================================
def
normalize_image_size
(
image
,
annotations
,
face_size
,
def
normalize_image_size
(
image
,
annotations
,
face_size
,
rgb_output_flag
,
use_face_alignment
):
rgb_output_flag
,
use_face_alignment
,
alignment_type
=
'
default
'
):
"""
"""
This function crops the face in the input image given annotations defining
This function crops the face in the input image given annotations defining
the face bounding box. The size of the face is also normalized to the
the face bounding box. The size of the face is also normalized to the
...
@@ -334,7 +428,7 @@ def normalize_image_size(image, annotations, face_size,
...
@@ -334,7 +428,7 @@ def normalize_image_size(image, annotations, face_size,
for
image_channel
in
image
:
# for all color channels in the input image
for
image_channel
in
image
:
# for all color channels in the input image
cropped_face
=
normalize_image_size_in_grayscale
(
cropped_face
=
normalize_image_size_in_grayscale
(
image_channel
,
annotations
,
face_size
,
use_face_alignment
)
image_channel
,
annotations
,
face_size
,
use_face_alignment
,
alignment_type
=
alignment_type
)
result
.
append
(
cropped_face
)
result
.
append
(
cropped_face
)
...
@@ -388,6 +482,15 @@ class FaceCropAlign(Preprocessor):
...
@@ -388,6 +482,15 @@ class FaceCropAlign(Preprocessor):
using the facial landmarks detected locally.
using the facial landmarks detected locally.
Works only when ``face_detection_method is not None``.
Works only when ``face_detection_method is not None``.
``alignment_type`` : :py:class:`str`
Specifies the alignment type to use if ``use_face_alignment`` is set to ``True``
Two methods are currently implemented:
``default`` which would do alignment by making eyes
horizontally
``lightcnn`` which aligns the face such that eye center are mouth centers are aligned to
predefined positions. This option overrides the face size option as the output required
is always 128x128. This is suitable for use with LightCNN model.
``max_image_size`` : :py:class:`int`
``max_image_size`` : :py:class:`int`
The maximum size of the image to be processed.
The maximum size of the image to be processed.
``max_image_size`` is only supported when
``max_image_size`` is only supported when
...
@@ -420,6 +523,7 @@ class FaceCropAlign(Preprocessor):
...
@@ -420,6 +523,7 @@ class FaceCropAlign(Preprocessor):
def
__init__
(
self
,
face_size
,
def
__init__
(
self
,
face_size
,
rgb_output_flag
,
rgb_output_flag
,
use_face_alignment
,
use_face_alignment
,
alignment_type
=
'
default
'
,
max_image_size
=
None
,
max_image_size
=
None
,
face_detection_method
=
None
,
face_detection_method
=
None
,
min_face_size
=
None
,
min_face_size
=
None
,
...
@@ -429,6 +533,7 @@ class FaceCropAlign(Preprocessor):
...
@@ -429,6 +533,7 @@ class FaceCropAlign(Preprocessor):
Preprocessor
.
__init__
(
self
,
face_size
=
face_size
,
Preprocessor
.
__init__
(
self
,
face_size
=
face_size
,
rgb_output_flag
=
rgb_output_flag
,
rgb_output_flag
=
rgb_output_flag
,
use_face_alignment
=
use_face_alignment
,
use_face_alignment
=
use_face_alignment
,
alignment_type
=
alignment_type
,
max_image_size
=
max_image_size
,
max_image_size
=
max_image_size
,
face_detection_method
=
face_detection_method
,
face_detection_method
=
face_detection_method
,
min_face_size
=
min_face_size
,
min_face_size
=
min_face_size
,
...
@@ -438,6 +543,7 @@ class FaceCropAlign(Preprocessor):
...
@@ -438,6 +543,7 @@ class FaceCropAlign(Preprocessor):
self
.
face_size
=
face_size
self
.
face_size
=
face_size
self
.
rgb_output_flag
=
rgb_output_flag
self
.
rgb_output_flag
=
rgb_output_flag
self
.
use_face_alignment
=
use_face_alignment
self
.
use_face_alignment
=
use_face_alignment
self
.
alignment_type
=
alignment_type
self
.
max_image_size
=
max_image_size
self
.
max_image_size
=
max_image_size
self
.
face_detection_method
=
face_detection_method
self
.
face_detection_method
=
face_detection_method
...
@@ -447,6 +553,17 @@ class FaceCropAlign(Preprocessor):
...
@@ -447,6 +553,17 @@ class FaceCropAlign(Preprocessor):
self
.
supported_face_detection_method
=
[
"
dlib
"
,
"
mtcnn
"
]
self
.
supported_face_detection_method
=
[
"
dlib
"
,
"
mtcnn
"
]
self
.
supported_alignment_method
=
[
"
default
"
,
"
lightcnn
"
]
if
use_face_alignment
:
if
self
.
alignment_type
not
in
self
.
supported_alignment_method
:
raise
ValueError
(
'
The alignment type {} is not supported
'
.
format
(
self
.
alignment_type
))
if
self
.
face_detection_method
is
not
None
:
if
self
.
face_detection_method
is
not
None
:
if
self
.
face_detection_method
not
in
self
.
supported_face_detection_method
:
if
self
.
face_detection_method
not
in
self
.
supported_face_detection_method
:
...
@@ -546,6 +663,7 @@ class FaceCropAlign(Preprocessor):
...
@@ -546,6 +663,7 @@ class FaceCropAlign(Preprocessor):
annotations
=
annotations
,
annotations
=
annotations
,
face_size
=
self
.
face_size
,
face_size
=
self
.
face_size
,
rgb_output_flag
=
self
.
rgb_output_flag
,
rgb_output_flag
=
self
.
rgb_output_flag
,
use_face_alignment
=
self
.
use_face_alignment
)
use_face_alignment
=
self
.
use_face_alignment
,
alignment_type
=
self
.
alignment_type
)
return
norm_face_image
return
norm_face_image
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment