1// Copyright 2016 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package vision
16
17import (
18	"testing"
19
20	"cloud.google.com/go/internal/testutil"
21	pb "google.golang.org/genproto/googleapis/cloud/vision/v1"
22)
23
24func TestFaceFromLandmarks(t *testing.T) {
25	landmarks := []*pb.FaceAnnotation_Landmark{
26		{
27			Type:     pb.FaceAnnotation_Landmark_LEFT_EYE,
28			Position: &pb.Position{X: 1192, Y: 575, Z: 0},
29		},
30		{
31			Type:     pb.FaceAnnotation_Landmark_RIGHT_EYE,
32			Position: &pb.Position{X: 1479, Y: 571, Z: -9},
33		},
34		{
35			Type:     pb.FaceAnnotation_Landmark_LEFT_OF_LEFT_EYEBROW,
36			Position: &pb.Position{X: 1097, Y: 522, Z: 27},
37		},
38		{
39			Type:     pb.FaceAnnotation_Landmark_RIGHT_OF_LEFT_EYEBROW,
40			Position: &pb.Position{X: 1266, Y: 521, Z: -61},
41		},
42		{
43			Type:     pb.FaceAnnotation_Landmark_LEFT_OF_RIGHT_EYEBROW,
44			Position: &pb.Position{X: 1402, Y: 520, Z: -66},
45		},
46		{
47			Type:     pb.FaceAnnotation_Landmark_RIGHT_OF_RIGHT_EYEBROW,
48			Position: &pb.Position{X: 1571, Y: 519, Z: 10},
49		},
50		{
51			Type:     pb.FaceAnnotation_Landmark_MIDPOINT_BETWEEN_EYES,
52			Position: &pb.Position{X: 1331, Y: 566, Z: -66},
53		},
54		{
55			Type:     pb.FaceAnnotation_Landmark_NOSE_TIP,
56			Position: &pb.Position{X: 1329, Y: 743, Z: -137},
57		},
58		{
59			Type:     pb.FaceAnnotation_Landmark_UPPER_LIP,
60			Position: &pb.Position{X: 1330, Y: 836, Z: -66},
61		},
62		{
63			Type:     pb.FaceAnnotation_Landmark_LOWER_LIP,
64			Position: &pb.Position{X: 1334, Y: 954, Z: -36},
65		},
66		{
67			Type:     pb.FaceAnnotation_Landmark_MOUTH_LEFT,
68			Position: &pb.Position{X: 1186, Y: 867, Z: 27},
69		},
70		{
71			Type:     pb.FaceAnnotation_Landmark_MOUTH_RIGHT,
72			Position: &pb.Position{X: 1484, Y: 857, Z: 19},
73		},
74		{
75			Type:     pb.FaceAnnotation_Landmark_MOUTH_CENTER,
76			Position: &pb.Position{X: 1332, Y: 894, Z: -41},
77		},
78		{
79			Type:     pb.FaceAnnotation_Landmark_NOSE_BOTTOM_RIGHT,
80			Position: &pb.Position{X: 1432, Y: 750, Z: -26},
81		},
82		{
83			Type:     pb.FaceAnnotation_Landmark_NOSE_BOTTOM_LEFT,
84			Position: &pb.Position{X: 1236, Y: 755, Z: -20},
85		},
86		{
87			Type:     pb.FaceAnnotation_Landmark_NOSE_BOTTOM_CENTER,
88			Position: &pb.Position{X: 1332, Y: 783, Z: -70},
89		},
90		{
91			Type:     pb.FaceAnnotation_Landmark_LEFT_EYE_TOP_BOUNDARY,
92			Position: &pb.Position{X: 1193, Y: 561, Z: -20},
93		},
94		{
95			Type:     pb.FaceAnnotation_Landmark_LEFT_EYE_RIGHT_CORNER,
96			Position: &pb.Position{X: 1252, Y: 581, Z: -1},
97		},
98		{
99			Type:     pb.FaceAnnotation_Landmark_LEFT_EYE_BOTTOM_BOUNDARY,
100			Position: &pb.Position{X: 1190, Y: 593, Z: -1},
101		},
102		{
103			Type:     pb.FaceAnnotation_Landmark_LEFT_EYE_LEFT_CORNER,
104			Position: &pb.Position{X: 1133, Y: 584, Z: 28},
105		},
106		{
107			Type:     pb.FaceAnnotation_Landmark_LEFT_EYE_PUPIL,
108			Position: &pb.Position{X: 1189, Y: 580, Z: -8},
109		},
110		{
111			Type:     pb.FaceAnnotation_Landmark_RIGHT_EYE_TOP_BOUNDARY,
112			Position: &pb.Position{X: 1474, Y: 561, Z: -30},
113		},
114		{
115			Type:     pb.FaceAnnotation_Landmark_RIGHT_EYE_RIGHT_CORNER,
116			Position: &pb.Position{X: 1536, Y: 581, Z: 15},
117		},
118		{
119			Type:     pb.FaceAnnotation_Landmark_RIGHT_EYE_BOTTOM_BOUNDARY,
120			Position: &pb.Position{X: 1481, Y: 590, Z: -11},
121		},
122		{
123			Type:     pb.FaceAnnotation_Landmark_RIGHT_EYE_LEFT_CORNER,
124			Position: &pb.Position{X: 1424, Y: 579, Z: -6},
125		},
126		{
127			Type:     pb.FaceAnnotation_Landmark_RIGHT_EYE_PUPIL,
128			Position: &pb.Position{X: 1478, Y: 580, Z: -18},
129		},
130		{
131			Type:     pb.FaceAnnotation_Landmark_LEFT_EYEBROW_UPPER_MIDPOINT,
132			Position: &pb.Position{X: 1181, Y: 482, Z: -40},
133		},
134		{
135			Type:     pb.FaceAnnotation_Landmark_RIGHT_EYEBROW_UPPER_MIDPOINT,
136			Position: &pb.Position{X: 1485, Y: 482, Z: -50},
137		},
138		{
139			Type:     pb.FaceAnnotation_Landmark_LEFT_EAR_TRAGION,
140			Position: &pb.Position{X: 1027, Y: 696, Z: 361},
141		},
142		{
143			Type:     pb.FaceAnnotation_Landmark_RIGHT_EAR_TRAGION,
144			Position: &pb.Position{X: 1666, Y: 695, Z: 339},
145		},
146		{
147			Type:     pb.FaceAnnotation_Landmark_FOREHEAD_GLABELLA,
148			Position: &pb.Position{X: 1332, Y: 514, Z: -75},
149		},
150		{
151			Type:     pb.FaceAnnotation_Landmark_CHIN_GNATHION,
152			Position: &pb.Position{X: 1335, Y: 1058, Z: 6},
153		},
154		{
155			Type:     pb.FaceAnnotation_Landmark_CHIN_LEFT_GONION,
156			Position: &pb.Position{X: 1055, Y: 882, Z: 257},
157		},
158		{
159			Type:     pb.FaceAnnotation_Landmark_CHIN_RIGHT_GONION,
160			Position: &pb.Position{X: 1631, Y: 881, Z: 238},
161		},
162	}
163	want := &FaceLandmarks{
164		Eyebrows: Eyebrows{
165			Left: Eyebrow{
166				Top:   &pb.Position{X: 1181, Y: 482, Z: -40},
167				Left:  &pb.Position{X: 1097, Y: 522, Z: 27},
168				Right: &pb.Position{X: 1266, Y: 521, Z: -61},
169			},
170			Right: Eyebrow{
171				Top:   &pb.Position{X: 1485, Y: 482, Z: -50},
172				Left:  &pb.Position{X: 1402, Y: 520, Z: -66},
173				Right: &pb.Position{X: 1571, Y: 519, Z: 10},
174			},
175		},
176		Eyes: Eyes{
177			Left: Eye{
178				Left:   &pb.Position{X: 1133, Y: 584, Z: 28},
179				Right:  &pb.Position{X: 1252, Y: 581, Z: -1},
180				Top:    &pb.Position{X: 1193, Y: 561, Z: -20},
181				Bottom: &pb.Position{X: 1190, Y: 593, Z: -1},
182				Center: &pb.Position{X: 1192, Y: 575, Z: 0},
183				Pupil:  &pb.Position{X: 1189, Y: 580, Z: -8},
184			},
185			Right: Eye{
186				Left:   &pb.Position{X: 1424, Y: 579, Z: -6},
187				Right:  &pb.Position{X: 1536, Y: 581, Z: 15},
188				Top:    &pb.Position{X: 1474, Y: 561, Z: -30},
189				Bottom: &pb.Position{X: 1481, Y: 590, Z: -11},
190				Center: &pb.Position{X: 1479, Y: 571, Z: -9},
191				Pupil:  &pb.Position{X: 1478, Y: 580, Z: -18},
192			},
193		},
194		Ears: Ears{
195			Left:  &pb.Position{X: 1027, Y: 696, Z: 361},
196			Right: &pb.Position{X: 1666, Y: 695, Z: 339},
197		},
198		Nose: Nose{
199			Left:   &pb.Position{X: 1236, Y: 755, Z: -20},
200			Right:  &pb.Position{X: 1432, Y: 750, Z: -26},
201			Top:    &pb.Position{X: 1331, Y: 566, Z: -66},
202			Bottom: &pb.Position{X: 1332, Y: 783, Z: -70},
203			Tip:    &pb.Position{X: 1329, Y: 743, Z: -137},
204		},
205		Mouth: Mouth{
206			Left:     &pb.Position{X: 1186, Y: 867, Z: 27},
207			Center:   &pb.Position{X: 1332, Y: 894, Z: -41},
208			Right:    &pb.Position{X: 1484, Y: 857, Z: 19},
209			UpperLip: &pb.Position{X: 1330, Y: 836, Z: -66},
210			LowerLip: &pb.Position{X: 1334, Y: 954, Z: -36},
211		},
212		Chin: Chin{
213			Left:   &pb.Position{X: 1055, Y: 882, Z: 257},
214			Center: &pb.Position{X: 1335, Y: 1058, Z: 6},
215			Right:  &pb.Position{X: 1631, Y: 881, Z: 238},
216		},
217		Forehead: &pb.Position{X: 1332, Y: 514, Z: -75},
218	}
219
220	got := FaceFromLandmarks(landmarks)
221	if diff := testutil.Diff(got, want); diff != "" {
222		t.Error(diff)
223	}
224}
225