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