from collections import OrderedDict
import numpy as np
from ..base import (
validate_input, connectivity_from_array, pcloud_and_lgroup_from_ranges,
connectivity_from_range, labeller_func)
[docs]@labeller_func(group_label='face_ibug_68')
def face_ibug_68_to_face_ibug_68(pcloud):
r"""
Apply the IBUG 68-point semantic labels.
The semantic labels are as follows:
- jaw
- left_eyebrow
- right_eyebrow
- nose
- left_eye
- right_eye
- mouth
References
----------
.. [1] http://www.multipie.org/
.. [2] http://ibug.doc.ic.ac.uk/resources/300-W/
"""
from menpo.shape import LabelledPointUndirectedGraph
n_expected_points = 68
validate_input(pcloud, n_expected_points)
jaw_indices = np.arange(0, 17)
lbrow_indices = np.arange(17, 22)
rbrow_indices = np.arange(22, 27)
upper_nose_indices = np.arange(27, 31)
lower_nose_indices = np.arange(31, 36)
leye_indices = np.arange(36, 42)
reye_indices = np.arange(42, 48)
outer_mouth_indices = np.arange(48, 60)
inner_mouth_indices = np.arange(60, 68)
jaw_connectivity = connectivity_from_array(jaw_indices)
lbrow_connectivity = connectivity_from_array(lbrow_indices)
rbrow_connectivity = connectivity_from_array(rbrow_indices)
nose_connectivity = np.vstack([
connectivity_from_array(upper_nose_indices),
connectivity_from_array(lower_nose_indices)])
leye_connectivity = connectivity_from_array(leye_indices, close_loop=True)
reye_connectivity = connectivity_from_array(reye_indices, close_loop=True)
mouth_connectivity = np.vstack([
connectivity_from_array(outer_mouth_indices, close_loop=True),
connectivity_from_array(inner_mouth_indices, close_loop=True)])
all_connectivity = np.vstack([
jaw_connectivity, lbrow_connectivity, rbrow_connectivity,
nose_connectivity, leye_connectivity, reye_connectivity,
mouth_connectivity
])
mapping = OrderedDict()
mapping['jaw'] = jaw_indices
mapping['left_eyebrow'] = lbrow_indices
mapping['right_eyebrow'] = rbrow_indices
mapping['nose'] = np.hstack((upper_nose_indices, lower_nose_indices))
mapping['left_eye'] = leye_indices
mapping['right_eye'] = reye_indices
mapping['mouth'] = np.hstack((outer_mouth_indices, inner_mouth_indices))
new_pcloud = LabelledPointUndirectedGraph.init_from_indices_mapping(
pcloud.points, all_connectivity, mapping)
return new_pcloud, mapping
[docs]@labeller_func(group_label='face_ibug_68')
def face_ibug_68_mirrored_to_face_ibug_68(pcloud):
r"""
Apply the IBUG 68-point semantic labels, on a pointcloud that has been
mirrored around the vertical axis (flipped around the Y-axis). Thus, on
the flipped image the jaw etc would be the wrong way around. This
rectifies that and returns a new PointCloud whereby all the points
are oriented correctly.
The semantic labels applied are as follows:
- jaw
- left_eyebrow
- right_eyebrow
- nose
- left_eye
- right_eye
- mouth
References
----------
.. [1] http://www.multipie.org/
.. [2] http://ibug.doc.ic.ac.uk/resources/300-W/
"""
new_pcloud, old_map = face_ibug_68_to_face_ibug_68(pcloud,
return_mapping=True)
lms_map = np.hstack([old_map['jaw'][::-1],
old_map['right_eyebrow'][::-1],
old_map['left_eyebrow'][::-1],
old_map['nose'][:4],
old_map['nose'][4:][::-1],
np.roll(old_map['right_eye'][::-1], 4),
np.roll(old_map['left_eye'][::-1], 4),
np.roll(old_map['mouth'][:12][::-1], 7),
np.roll(old_map['mouth'][12:][::-1], 5)])
return new_pcloud.from_vector(pcloud.points[lms_map]), old_map
[docs]@labeller_func(group_label='face_ibug_66')
def face_ibug_68_to_face_ibug_66(pcloud):
r"""
Apply the IBUG 66-point semantic labels, but ignoring the 2 points
describing the inner mouth corners).
The semantic labels applied are as follows:
- jaw
- left_eyebrow
- right_eyebrow
- nose
- left_eye
- right_eye
- mouth
References
----------
.. [1] http://www.multipie.org/
.. [2] http://ibug.doc.ic.ac.uk/resources/300-W/
"""
from menpo.shape import LabelledPointUndirectedGraph
n_expected_points = 68
validate_input(pcloud, n_expected_points)
jaw_indices = np.arange(0, 17)
lbrow_indices = np.arange(17, 22)
rbrow_indices = np.arange(22, 27)
upper_nose_indices = np.arange(27, 31)
lower_nose_indices = np.arange(31, 36)
leye_indices = np.arange(36, 42)
reye_indices = np.arange(42, 48)
outer_mouth_indices = np.arange(48, 60)
inner_mouth_indices = np.hstack((48, np.arange(60, 63),
54, np.arange(63, 66)))
jaw_connectivity = connectivity_from_array(jaw_indices)
lbrow_connectivity = connectivity_from_array(lbrow_indices)
rbrow_connectivity = connectivity_from_array(rbrow_indices)
nose_connectivity = np.vstack([
connectivity_from_array(upper_nose_indices),
connectivity_from_array(lower_nose_indices)])
leye_connectivity = connectivity_from_array(leye_indices, close_loop=True)
reye_connectivity = connectivity_from_array(reye_indices, close_loop=True)
mouth_connectivity = np.vstack([
connectivity_from_array(outer_mouth_indices, close_loop=True),
connectivity_from_array(inner_mouth_indices, close_loop=True)])
all_connectivity = np.vstack([
jaw_connectivity, lbrow_connectivity, rbrow_connectivity,
nose_connectivity, leye_connectivity, reye_connectivity,
mouth_connectivity])
mapping = OrderedDict()
mapping['jaw'] = jaw_indices
mapping['left_eyebrow'] = lbrow_indices
mapping['right_eyebrow'] = rbrow_indices
mapping['nose'] = np.hstack([upper_nose_indices, lower_nose_indices])
mapping['left_eye'] = leye_indices
mapping['right_eye'] = reye_indices
mapping['mouth'] = np.hstack([outer_mouth_indices, inner_mouth_indices])
# Ignore the two inner mouth points
ind = np.hstack((np.arange(60), np.arange(61, 64), np.arange(65, 68)))
new_pcloud = LabelledPointUndirectedGraph.init_from_indices_mapping(
pcloud.points[ind], all_connectivity, mapping)
return new_pcloud, mapping
[docs]@labeller_func(group_label='face_ibug_51')
def face_ibug_68_to_face_ibug_51(pcloud):
r"""
Apply the IBUG 51-point semantic labels, but removing the annotations
corresponding to the jaw region.
The semantic labels applied are as follows:
- left_eyebrow
- right_eyebrow
- nose
- left_eye
- right_eye
- mouth
References
----------
.. [1] http://www.multipie.org/
.. [2] http://ibug.doc.ic.ac.uk/resources/300-W/
"""
from menpo.shape import LabelledPointUndirectedGraph
n_expected_points = 68
validate_input(pcloud, n_expected_points)
lbrow_indices = np.arange(0, 5)
rbrow_indices = np.arange(5, 10)
upper_nose_indices = np.arange(10, 14)
lower_nose_indices = np.arange(14, 19)
leye_indices = np.arange(19, 25)
reye_indices = np.arange(25, 31)
outer_mouth_indices = np.arange(31, 43)
inner_mouth_indices = np.arange(43, 51)
lbrow_connectivity = connectivity_from_array(lbrow_indices)
rbrow_connectivity = connectivity_from_array(rbrow_indices)
nose_connectivity = np.vstack([
connectivity_from_array(upper_nose_indices),
connectivity_from_array(lower_nose_indices)])
leye_connectivity = connectivity_from_array(leye_indices, close_loop=True)
reye_connectivity = connectivity_from_array(reye_indices, close_loop=True)
mouth_connectivity = np.vstack([
connectivity_from_array(outer_mouth_indices, close_loop=True),
connectivity_from_array(inner_mouth_indices, close_loop=True)])
all_connectivity = np.vstack([
lbrow_connectivity, rbrow_connectivity, nose_connectivity,
leye_connectivity, reye_connectivity, mouth_connectivity])
mapping = OrderedDict()
mapping['left_eyebrow'] = lbrow_indices
mapping['right_eyebrow'] = rbrow_indices
mapping['nose'] = np.hstack([upper_nose_indices, lower_nose_indices])
mapping['left_eye'] = leye_indices
mapping['right_eye'] = reye_indices
mapping['mouth'] = np.hstack([outer_mouth_indices, inner_mouth_indices])
# Ignore the two inner mouth points
ind = np.arange(17, 68)
new_pcloud = LabelledPointUndirectedGraph.init_from_indices_mapping(
pcloud.points[ind], all_connectivity, mapping)
return new_pcloud, mapping
[docs]@labeller_func(group_label='face_ibug_49')
def face_ibug_49_to_face_ibug_49(pcloud):
r"""
Apply the IBUG 49-point semantic labels.
The semantic labels applied are as follows:
- left_eyebrow
- right_eyebrow
- nose
- left_eye
- right_eye
- mouth
References
----------
.. [1] http://www.multipie.org/
.. [2] http://ibug.doc.ic.ac.uk/resources/300-W/
"""
from menpo.shape import LabelledPointUndirectedGraph
n_expected_points = 49
validate_input(pcloud, n_expected_points)
lbrow_indices = np.arange(0, 5)
rbrow_indices = np.arange(5, 10)
upper_nose_indices = np.arange(10, 14)
lower_nose_indices = np.arange(14, 19)
leye_indices = np.arange(19, 25)
reye_indices = np.arange(25, 31)
outer_mouth_indices = np.arange(31, 43)
inner_mouth_indices = np.hstack((31, np.arange(43, 46),
37, np.arange(46, 49)))
lbrow_connectivity = connectivity_from_array(lbrow_indices)
rbrow_connectivity = connectivity_from_array(rbrow_indices)
nose_connectivity = np.vstack([
connectivity_from_array(upper_nose_indices),
connectivity_from_array(lower_nose_indices)])
leye_connectivity = connectivity_from_array(leye_indices, close_loop=True)
reye_connectivity = connectivity_from_array(reye_indices, close_loop=True)
mouth_connectivity = np.vstack([
connectivity_from_array(outer_mouth_indices, close_loop=True),
connectivity_from_array(inner_mouth_indices, close_loop=True)])
all_connectivity = np.vstack([
lbrow_connectivity, rbrow_connectivity, nose_connectivity,
leye_connectivity, reye_connectivity, mouth_connectivity])
mapping = OrderedDict()
mapping['left_eyebrow'] = lbrow_indices
mapping['right_eyebrow'] = rbrow_indices
mapping['nose'] = np.hstack([upper_nose_indices, lower_nose_indices])
mapping['left_eye'] = leye_indices
mapping['right_eye'] = reye_indices
mapping['mouth'] = np.hstack([outer_mouth_indices, inner_mouth_indices])
# Ignore the two inner mouth points
new_pcloud = LabelledPointUndirectedGraph.init_from_indices_mapping(
pcloud.points, all_connectivity, mapping)
return new_pcloud, mapping
[docs]@labeller_func(group_label='face_ibug_49')
def face_ibug_68_to_face_ibug_49(pcloud):
r"""
Apply the IBUG 49-point semantic labels, but removing the annotations
corresponding to the jaw region and the 2 describing the inner mouth
corners.
The semantic labels applied are as follows:
- left_eyebrow
- right_eyebrow
- nose
- left_eye
- right_eye
- mouth
References
----------
.. [1] http://www.multipie.org/
.. [2] http://ibug.doc.ic.ac.uk/resources/300-W/
"""
from menpo.shape import LabelledPointUndirectedGraph
n_expected_points = 68
validate_input(pcloud, n_expected_points)
lbrow_indices = np.arange(0, 5)
rbrow_indices = np.arange(5, 10)
upper_nose_indices = np.arange(10, 14)
lower_nose_indices = np.arange(14, 19)
leye_indices = np.arange(19, 25)
reye_indices = np.arange(25, 31)
outer_mouth_indices = np.arange(31, 43)
inner_mouth_indices = np.hstack((31, np.arange(43, 46),
37, np.arange(46, 49)))
lbrow_connectivity = connectivity_from_array(lbrow_indices)
rbrow_connectivity = connectivity_from_array(rbrow_indices)
nose_connectivity = np.vstack([
connectivity_from_array(upper_nose_indices),
connectivity_from_array(lower_nose_indices)])
leye_connectivity = connectivity_from_array(leye_indices, close_loop=True)
reye_connectivity = connectivity_from_array(reye_indices, close_loop=True)
mouth_connectivity = np.vstack([
connectivity_from_array(outer_mouth_indices, close_loop=True),
connectivity_from_array(inner_mouth_indices, close_loop=True)])
all_connectivity = np.vstack([
lbrow_connectivity, rbrow_connectivity, nose_connectivity,
leye_connectivity, reye_connectivity, mouth_connectivity])
mapping = OrderedDict()
mapping['left_eyebrow'] = lbrow_indices
mapping['right_eyebrow'] = rbrow_indices
mapping['nose'] = np.hstack([upper_nose_indices, lower_nose_indices])
mapping['left_eye'] = leye_indices
mapping['right_eye'] = reye_indices
mapping['mouth'] = np.hstack([outer_mouth_indices, inner_mouth_indices])
# Ignore the two inner mouth points
ind = np.hstack((np.arange(17, 60), np.arange(61, 64), np.arange(65, 68)))
new_pcloud = LabelledPointUndirectedGraph.init_from_indices_mapping(
pcloud.points[ind], all_connectivity, mapping)
return new_pcloud, mapping
[docs]@labeller_func(group_label='face_ibug_68_trimesh')
def face_ibug_68_to_face_ibug_68_trimesh(pcloud):
r"""
Apply the IBUG 68-point semantic labels, with trimesh connectivity.
The semantic labels applied are as follows:
- tri
References
----------
.. [1] http://www.multipie.org/
.. [2] http://ibug.doc.ic.ac.uk/resources/300-W/
"""
from menpo.shape import TriMesh
n_expected_points = 68
validate_input(pcloud, n_expected_points)
tri_list = np.array([[47, 29, 28], [44, 43, 23], [38, 20, 21],
[47, 28, 42], [49, 61, 60], [40, 41, 37],
[37, 19, 20], [28, 40, 39], [38, 21, 39],
[36, 1, 0], [48, 59, 4], [49, 60, 48],
[67, 59, 60], [13, 53, 14], [61, 51, 62],
[57, 8, 7], [52, 51, 33], [61, 67, 60],
[52, 63, 51], [66, 56, 57], [35, 30, 29],
[53, 52, 35], [37, 36, 17], [18, 37, 17],
[37, 38, 40], [38, 37, 20], [19, 37, 18],
[38, 39, 40], [28, 29, 40], [41, 36, 37],
[27, 39, 21], [41, 31, 1], [30, 32, 31],
[33, 51, 50], [33, 30, 34], [31, 40, 29],
[36, 0, 17], [31, 2, 1], [31, 41, 40],
[ 1, 36, 41], [31, 49, 2], [ 2, 49, 3],
[60, 59, 48], [ 3, 49, 48], [31, 32, 50],
[48, 4, 3], [59, 5, 4], [58, 67, 66],
[ 5, 59, 58], [58, 59, 67], [ 7, 6, 58],
[66, 57, 58], [13, 54, 53], [ 7, 58, 57],
[ 6, 5, 58], [50, 61, 49], [62, 67, 61],
[31, 50, 49], [32, 33, 50], [30, 33, 32],
[34, 52, 33], [35, 52, 34], [53, 63, 52],
[62, 63, 65], [62, 51, 63], [66, 65, 56],
[63, 53, 64], [62, 66, 67], [62, 65, 66],
[57, 56, 9], [65, 63, 64], [ 8, 57, 9],
[ 9, 56, 10], [10, 56, 11], [11, 56, 55],
[11, 55, 12], [56, 65, 55], [55, 64, 54],
[55, 65, 64], [55, 54, 12], [64, 53, 54],
[12, 54, 13], [45, 46, 44], [35, 34, 30],
[14, 53, 35], [15, 46, 45], [27, 28, 39],
[27, 42, 28], [35, 29, 47], [30, 31, 29],
[15, 35, 46], [15, 14, 35], [43, 22, 23],
[27, 21, 22], [24, 44, 23], [44, 47, 43],
[43, 47, 42], [46, 35, 47], [26, 45, 44],
[46, 47, 44], [25, 44, 24], [25, 26, 44],
[16, 15, 45], [16, 45, 26], [22, 42, 43],
[50, 51, 61], [27, 22, 42]])
new_pcloud = TriMesh(pcloud.points, trilist=tri_list)
mapping = OrderedDict()
mapping['tri'] = np.arange(new_pcloud.n_points)
return new_pcloud, mapping
[docs]@labeller_func(group_label='face_ibug_66_trimesh')
def face_ibug_68_to_face_ibug_66_trimesh(pcloud):
r"""
Apply the IBUG 66-point semantic labels, with trimesh connectivity.
The semantic labels applied are as follows:
- tri
References
----------
.. [1] http://www.multipie.org/
.. [2] http://ibug.doc.ic.ac.uk/resources/300-W/
"""
from menpo.shape import TriMesh
# Apply face_ibug_68_to_face_ibug_66
new_pcloud = face_ibug_68_to_face_ibug_66(pcloud)
# This is in terms of the 66 points
tri_list = np.array([[47, 29, 28], [44, 43, 23], [38, 20, 21],
[47, 28, 42], [40, 41, 37], [51, 62, 61],
[37, 19, 20], [28, 40, 39], [38, 21, 39],
[36, 1, 0], [48, 59, 4], [49, 60, 48],
[13, 53, 14], [60, 51, 61], [51, 51, 62],
[52, 51, 33], [49, 50, 60], [57, 7, 8],
[64, 56, 57], [35, 30, 29], [52, 62, 53],
[53, 52, 35], [37, 36, 17], [18, 37, 17],
[37, 38, 40], [38, 37, 20], [19, 37, 18],
[38, 39, 40], [28, 29, 40], [41, 36, 37],
[27, 39, 21], [41, 31, 1], [30, 32, 31],
[33, 51, 50], [33, 30, 34], [31, 40, 29],
[36, 0, 17], [31, 2, 1], [31, 41, 40],
[ 1, 36, 41], [31, 49, 2], [ 2, 49, 3],
[ 3, 49, 48], [31, 32, 50], [62, 53, 54],
[48, 4, 3], [59, 5, 4], [58, 65, 64],
[ 5, 59, 58], [58, 59, 65], [ 7, 6, 58],
[64, 57, 58], [13, 54, 53], [ 7, 58, 57],
[ 6, 5, 58], [63, 55, 54], [65, 59, 48],
[31, 50, 49], [32, 33, 50], [30, 33, 32],
[34, 52, 33], [35, 52, 34], [48, 60, 65],
[64, 63, 56], [60, 65, 61], [65, 64, 61],
[57, 56, 9], [ 8, 57, 9], [64, 63, 61],
[ 9, 56, 10], [10, 56, 11], [11, 56, 55],
[11, 55, 12], [56, 63, 55], [51, 52, 62],
[55, 54, 12], [63, 54, 62], [61, 62, 63],
[12, 54, 13], [45, 46, 44], [35, 34, 30],
[14, 53, 35], [15, 46, 45], [27, 28, 39],
[27, 42, 28], [35, 29, 47], [30, 31, 29],
[15, 35, 46], [15, 14, 35], [43, 22, 23],
[27, 21, 22], [24, 44, 23], [44, 47, 43],
[43, 47, 42], [46, 35, 47], [26, 45, 44],
[46, 47, 44], [25, 44, 24], [25, 26, 44],
[16, 15, 45], [16, 45, 26], [22, 42, 43],
[50, 60, 51], [27, 22, 42]])
new_pcloud = TriMesh(new_pcloud.points, trilist=tri_list, copy=False)
mapping = OrderedDict()
mapping['tri'] = np.arange(new_pcloud.n_points)
return new_pcloud, mapping
[docs]@labeller_func(group_label='face_ibug_51_trimesh')
def face_ibug_68_to_face_ibug_51_trimesh(pcloud):
r"""
Apply the IBUG 51-point semantic labels, with trimesh connectivity..
The semantic labels applied are as follows:
- tri
References
----------
.. [1] http://www.multipie.org/
.. [2] http://ibug.doc.ic.ac.uk/resources/300-W/
"""
from menpo.shape import TriMesh
# Apply face_ibug_68_to_face_ibug_51
new_pcloud = face_ibug_68_to_face_ibug_51(pcloud)
# This is in terms of the 51 points
tri_list = np.array([[30, 12, 11], [27, 26, 6], [21, 3, 4],
[30, 11, 25], [32, 44, 43], [23, 24, 20],
[20, 2, 3], [11, 23, 22], [21, 4, 22],
[32, 43, 31], [50, 42, 43], [44, 34, 45],
[35, 34, 16], [44, 50, 43], [35, 46, 34],
[49, 39, 40], [18, 13, 12], [36, 35, 18],
[20, 19, 0], [ 1, 20, 0], [20, 21, 23],
[21, 20, 3], [ 2, 20, 1], [21, 22, 23],
[11, 12, 23], [24, 19, 20], [10, 22, 4],
[13, 15, 14], [16, 34, 33], [16, 13, 17],
[14, 23, 12], [14, 24, 23], [43, 42, 31],
[14, 15, 33], [41, 50, 49], [41, 42, 50],
[49, 40, 41], [33, 44, 32], [45, 50, 44],
[14, 33, 32], [15, 16, 33], [13, 16, 15],
[17, 35, 16], [18, 35, 17], [36, 46, 35],
[45, 46, 48], [45, 34, 46], [49, 48, 39],
[46, 36, 47], [45, 49, 50], [45, 48, 49],
[48, 46, 47], [39, 48, 38], [38, 47, 37],
[38, 48, 47], [47, 36, 37], [28, 29, 27],
[18, 17, 13], [10, 11, 22], [10, 25, 11],
[18, 12, 30], [13, 14, 12], [26, 5, 6],
[10, 4, 5], [ 7, 27, 6], [27, 30, 26],
[26, 30, 25], [29, 18, 30], [ 9, 28, 27],
[29, 30, 27], [ 8, 27, 7], [ 8, 9, 27],
[ 5, 25, 26], [33, 34, 44], [10, 5, 25]])
new_pcloud = TriMesh(new_pcloud.points, trilist=tri_list, copy=False)
mapping = OrderedDict()
mapping['tri'] = np.arange(new_pcloud.n_points)
return new_pcloud, mapping
[docs]@labeller_func(group_label='face_ibug_49_trimesh')
def face_ibug_68_to_face_ibug_49_trimesh(pcloud):
r"""
Apply the IBUG 49-point semantic labels, with trimesh connectivity.
The semantic labels applied are as follows:
- tri
References
----------
.. [1] http://www.multipie.org/
.. [2] http://ibug.doc.ic.ac.uk/resources/300-W/
"""
from menpo.shape import TriMesh
# Apply face_ibug_68_to_face_ibug_49
new_pcloud = face_ibug_68_to_face_ibug_49(pcloud)
# This is in terms of the 49 points
tri_list = np.array([[47, 29, 28], [44, 43, 23], [38, 20, 21],
[47, 28, 42], [40, 41, 37], [51, 62, 61],
[37, 19, 20], [28, 40, 39], [38, 21, 39],
[36, 1, 0], [48, 59, 4], [49, 60, 48],
[13, 53, 14], [60, 51, 61], [51, 51, 62],
[52, 51, 33], [49, 50, 60], [57, 7, 8],
[64, 56, 57], [35, 30, 29], [52, 62, 53],
[53, 52, 35], [37, 36, 17], [18, 37, 17],
[37, 38, 40], [38, 37, 20], [19, 37, 18],
[38, 39, 40], [28, 29, 40], [41, 36, 37],
[27, 39, 21], [41, 31, 1], [30, 32, 31],
[33, 51, 50], [33, 30, 34], [31, 40, 29],
[36, 0, 17], [31, 2, 1], [31, 41, 40],
[ 1, 36, 41], [31, 49, 2], [ 2, 49, 3],
[ 3, 49, 48], [31, 32, 50], [62, 53, 54],
[48, 4, 3], [59, 5, 4], [58, 65, 64],
[ 5, 59, 58], [58, 59, 65], [ 7, 6, 58],
[64, 57, 58], [13, 54, 53], [ 7, 58, 57],
[ 6, 5, 58], [63, 55, 54], [65, 59, 48],
[31, 50, 49], [32, 33, 50], [30, 33, 32],
[34, 52, 33], [35, 52, 34], [48, 60, 65],
[64, 63, 56], [60, 65, 61], [65, 64, 61],
[57, 56, 9], [ 8, 57, 9], [64, 63, 61],
[ 9, 56, 10], [10, 56, 11], [11, 56, 55],
[11, 55, 12], [56, 63, 55], [51, 52, 62],
[55, 54, 12], [63, 54, 62], [61, 62, 63],
[12, 54, 13], [45, 46, 44], [35, 34, 30],
[14, 53, 35], [15, 46, 45], [27, 28, 39],
[27, 42, 28], [35, 29, 47], [30, 31, 29],
[15, 35, 46], [15, 14, 35], [43, 22, 23],
[27, 21, 22], [24, 44, 23], [44, 47, 43],
[43, 47, 42], [46, 35, 47], [26, 45, 44],
[46, 47, 44], [25, 44, 24], [25, 26, 44],
[16, 15, 45], [16, 45, 26], [22, 42, 43],
[50, 60, 51], [27, 22, 42]])
new_pcloud = TriMesh(new_pcloud.points, trilist=tri_list, copy=False)
mapping = OrderedDict()
mapping['tri'] = np.arange(new_pcloud.n_points)
return new_pcloud, mapping
[docs]@labeller_func(group_label='face_ibug_65')
def face_ibug_68_to_face_ibug_65(pcloud):
r"""
Apply the IBUG 68 point semantic labels, but ignore the 3 points that are
coincident for a closed mouth (bottom of the inner mouth).
The semantic labels applied are as follows:
- jaw
- left_eyebrow
- right_eyebrow
- nose
- left_eye
- right_eye
- mouth
References
----------
.. [1] http://www.multipie.org/
.. [2] http://ibug.doc.ic.ac.uk/resources/300-W/
"""
from menpo.shape import LabelledPointUndirectedGraph
# Apply face_ibug_68_to_face_ibug_68
new_pcloud, mapping = face_ibug_68_to_face_ibug_68(pcloud,
return_mapping=True)
# The coincident points are considered the final 3 landmarks (bottom of
# the inner mouth points). We remove all the edges for the inner mouth
# which are the last 8.
edges = new_pcloud.edges[:-8]
# Re-add the inner mouth without the bottom 3 points
edges = np.vstack([edges,
connectivity_from_range((60, 65), close_loop=True)])
# Luckily, OrderedDict maintains the original ordering despite updates
outer_mouth_indices = np.arange(48, 60)
inner_mouth_indices = np.arange(60, 65)
mapping['mouth'] = np.hstack([outer_mouth_indices, inner_mouth_indices])
new_pcloud = LabelledPointUndirectedGraph.init_from_indices_mapping(
new_pcloud.points[:-3], edges, mapping)
return new_pcloud, mapping
[docs]@labeller_func(group_label='face_imm_58')
def face_imm_58_to_face_imm_58(pcloud):
r"""
Apply the 58-point semantic labels from the IMM dataset.
The semantic labels applied are as follows:
- jaw
- left_eye
- right_eye
- left_eyebrow
- right_eyebrow
- mouth
- nose
References
----------
.. [1] http://www2.imm.dtu.dk/~aam/
"""
n_expected_points = 58
validate_input(pcloud, n_expected_points)
labels = OrderedDict([
('jaw', (0, 13, False)),
('left_eye', (13, 21, True)),
('right_eye', (21, 29, True)),
('left _eyebrow', (29, 34, False)),
('right_eyebrow', (34, 39, False)),
('mouth', (39, 47, True)),
('nose', (47, 58, False))
])
return pcloud_and_lgroup_from_ranges(pcloud, labels)
[docs]@labeller_func(group_label='face_lfpw_29')
def face_lfpw_29_to_face_lfpw_29(pcloud):
r"""
Apply the 29-point semantic labels from the original LFPW dataset.
The semantic labels applied are as follows:
- chin
- left_eye
- right_eye
- left_eyebrow
- right_eyebrow
- mouth
- nose
References
----------
.. [1] http://homes.cs.washington.edu/~neeraj/databases/lfpw/
"""
from menpo.shape import LabelledPointUndirectedGraph
n_expected_points = 29
validate_input(pcloud, n_expected_points)
chin_indices = np.array([28])
outer_leye_indices = np.array([8, 12, 10, 13])
pupil_leye_indices = np.array([16])
outer_reye_indices = np.array([11, 14, 9, 15])
pupil_reye_indices = np.array([17])
lbrow_indices = np.array([0, 4, 2, 5])
rbrow_indices = np.array([3, 6, 1, 7])
outer_mouth_indices = np.array([22, 24, 23, 27])
inner_mouth_indices = np.array([22, 25, 23, 26])
nose_indices = np.array([18, 20, 19, 21])
chin_connectivity = connectivity_from_array(chin_indices, close_loop=True)
leye_connectivity = connectivity_from_array(outer_leye_indices,
close_loop=True)
reye_connectivity = connectivity_from_array(outer_reye_indices,
close_loop=True)
lbrow_connectivity = connectivity_from_array(lbrow_indices,
close_loop=True)
rbrow_connectivity = connectivity_from_array(rbrow_indices,
close_loop=True)
mouth_connectivity = np.vstack([
connectivity_from_array(outer_mouth_indices, close_loop=True),
connectivity_from_array(inner_mouth_indices, close_loop=True)])
nose_connectivity = connectivity_from_array(nose_indices, close_loop=True)
all_connectivity = np.vstack([
chin_connectivity, leye_connectivity, reye_connectivity,
lbrow_connectivity, rbrow_connectivity, mouth_connectivity,
nose_connectivity])
mapping = OrderedDict()
mapping['chin'] = chin_indices
mapping['left_eye'] = np.hstack((outer_leye_indices, pupil_leye_indices))
mapping['right_eye'] = np.hstack((outer_reye_indices, pupil_reye_indices))
mapping['left_eyebrow'] = lbrow_indices
mapping['right_eyebrow'] = rbrow_indices
mapping['mouth'] = np.hstack((outer_mouth_indices, inner_mouth_indices))
mapping['nose'] = nose_indices
new_pcloud = LabelledPointUndirectedGraph.init_from_indices_mapping(
pcloud.points, all_connectivity, mapping)
return new_pcloud, mapping
def _build_upper_eyelid():
top_indices = np.arange(0, 7)
middle_indices = np.arange(12, 17)
upper_eyelid_indices = np.hstack((top_indices, middle_indices))
upper_eyelid_connectivity = list(zip(top_indices, top_indices[1:]))
upper_eyelid_connectivity += [(0, 12)]
upper_eyelid_connectivity += list(zip(middle_indices, middle_indices[1:]))
upper_eyelid_connectivity += [(16, 6)]
return upper_eyelid_indices, upper_eyelid_connectivity
[docs]@labeller_func(group_label='eye_ibug_open_38')
def eye_ibug_open_38_to_eye_ibug_open_38(pcloud):
r"""
Apply the IBUG 38-point open eye semantic labels.
The semantic labels applied are as follows:
- upper_eyelid
- lower_eyelid
- iris
- pupil
- sclera
"""
from menpo.shape import LabelledPointUndirectedGraph
n_expected_points = 38
validate_input(pcloud, n_expected_points)
upper_el_indices, upper_el_connectivity = _build_upper_eyelid()
iris_range = (22, 30)
pupil_range = (30, 38)
sclera_top = np.arange(12, 17)
sclera_bottom = np.arange(17, 22)
sclera_indices = np.hstack((0, sclera_top, 6, sclera_bottom))
lower_el_top = np.arange(17, 22)
lower_el_bottom = np.arange(7, 12)
lower_el_indices = np.hstack((6, lower_el_top, 0, lower_el_bottom))
iris_connectivity = connectivity_from_range(iris_range, close_loop=True)
pupil_connectivity = connectivity_from_range(pupil_range, close_loop=True)
sclera_connectivity = list(zip(sclera_top, sclera_top[1:]))
sclera_connectivity += [(0, 21)]
sclera_connectivity += list(zip(sclera_bottom, sclera_bottom[1:]))
sclera_connectivity += [(6, 17)]
lower_el_connectivity = list(zip(lower_el_top, lower_el_top[1:]))
lower_el_connectivity += [(6, 7)]
lower_el_connectivity += list(zip(lower_el_bottom, lower_el_bottom[1:]))
lower_el_connectivity += [(11, 0)]
all_connectivity = np.asarray(upper_el_connectivity +
lower_el_connectivity +
iris_connectivity.tolist() +
pupil_connectivity.tolist() +
sclera_connectivity)
mapping = OrderedDict()
mapping['upper_eyelid'] = upper_el_indices
mapping['lower_eyelid'] = lower_el_indices
mapping['pupil'] = np.arange(*pupil_range)
mapping['iris'] = np.arange(*iris_range)
mapping['sclera'] = sclera_indices
new_pcloud = LabelledPointUndirectedGraph.init_from_indices_mapping(
pcloud.points, all_connectivity, mapping)
return new_pcloud, mapping
[docs]@labeller_func(group_label='eye_ibug_close_17')
def eye_ibug_close_17_to_eye_ibug_close_17(pcloud):
r"""
Apply the IBUG 17-point close eye semantic labels.
The semantic labels applied are as follows:
- upper_eyelid
- lower_eyelid
"""
from menpo.shape import LabelledPointUndirectedGraph
n_expected_points = 17
validate_input(pcloud, n_expected_points)
upper_indices, upper_connectivity = _build_upper_eyelid()
middle_indices = np.arange(12, 17)
bottom_indices = np.arange(6, 12)
lower_indices = np.hstack((bottom_indices, 0, middle_indices))
lower_connectivity = list(zip(bottom_indices, bottom_indices[1:]))
lower_connectivity += [(0, 12)]
lower_connectivity += list(zip(middle_indices, middle_indices[1:]))
lower_connectivity += [(11, 0)]
all_connectivity = np.asarray(upper_connectivity + lower_connectivity)
mapping = OrderedDict()
mapping['upper_eyelid'] = upper_indices
mapping['lower_eyelid'] = lower_indices
new_pcloud = LabelledPointUndirectedGraph.init_from_indices_mapping(
pcloud.points, all_connectivity, mapping)
return new_pcloud, mapping
[docs]@labeller_func(group_label='eye_ibug_open_38_trimesh')
def eye_ibug_open_38_to_eye_ibug_open_38_trimesh(pcloud):
r"""
Apply the IBUG 38-point open eye semantic labels, with trimesh connectivity.
The semantic labels applied are as follows:
- tri
"""
from menpo.shape import TriMesh
n_expected_points = 38
validate_input(pcloud, n_expected_points)
tri_list = np.array([[29, 36, 28], [22, 13, 23], [12, 1, 2],
[29, 30, 37], [13, 3, 14], [13, 12, 2],
[19, 8, 9], [25, 33, 24], [36, 37, 33],
[24, 32, 31], [33, 37, 31], [35, 34, 27],
[35, 36, 33], [ 3, 13, 2], [14, 24, 23],
[33, 32, 24], [15, 25, 14], [25, 26, 34],
[22, 30, 29], [31, 37, 30], [24, 31, 23],
[32, 33, 31], [22, 12, 13], [ 0, 1, 12],
[14, 23, 13], [31, 30, 23], [28, 19, 20],
[21, 11, 0], [12, 21, 0], [20, 11, 21],
[20, 10, 11], [21, 29, 20], [21, 12, 22],
[30, 22, 23], [29, 21, 22], [27, 19, 28],
[29, 37, 36], [29, 28, 20], [36, 35, 28],
[20, 19, 10], [10, 19, 9], [28, 35, 27],
[19, 19, 8], [17, 16, 6], [18, 7, 8],
[25, 34, 33], [18, 27, 17], [18, 19, 27],
[18, 17, 7], [27, 26, 17], [17, 6, 7],
[14, 25, 24], [34, 35, 33], [17, 26, 16],
[27, 34, 26], [ 3, 15, 14], [15, 26, 25],
[ 4, 15, 3], [16, 26, 15], [16, 4, 5],
[16, 15, 4], [16, 5, 6], [8, 18, 19]])
new_pcloud = TriMesh(pcloud.points, trilist=tri_list, copy=False)
mapping = OrderedDict()
mapping['tri'] = np.arange(new_pcloud.n_points)
return new_pcloud, mapping
[docs]@labeller_func(group_label='eye_ibug_close_17_trimesh')
def eye_ibug_close_17_to_eye_ibug_close_17_trimesh(pcloud):
r"""
Apply the IBUG 17-point close eye semantic labels, with trimesh
connectivity.
The semantic labels applied are as follows:
- tri
"""
from menpo.shape import TriMesh
n_expected_points = 17
validate_input(pcloud, n_expected_points)
tri_list = np.array([[10, 11, 13], [ 3, 13, 2], [ 4, 14, 3],
[15, 5, 16], [12, 11, 0], [13, 14, 10],
[13, 12, 2], [14, 13, 3], [ 0, 1, 12],
[ 2, 12, 1], [13, 11, 12], [ 9, 10, 14],
[15, 9, 14], [ 7, 8, 15], [ 5, 6, 16],
[15, 14, 4], [ 7, 15, 16], [ 8, 9, 15],
[15, 4, 5], [16, 6, 7]])
new_pcloud = TriMesh(pcloud.points, trilist=tri_list, copy=False)
mapping = OrderedDict()
mapping['tri'] = np.arange(new_pcloud.n_points)
return new_pcloud, mapping
[docs]@labeller_func(group_label='tongue_ibug_19')
def tongue_ibug_19_to_tongue_ibug_19(pcloud):
r"""
Apply the IBUG 19-point tongue semantic labels.
The semantic labels applied are as follows:
- outline
- bisector
"""
n_expected_points = 19
validate_input(pcloud, n_expected_points)
labels = OrderedDict([
('outline', (0, 13, False)),
('bisector', (13, 19, False))
])
return pcloud_and_lgroup_from_ranges(pcloud, labels)