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 "log" 19 20 pb "google.golang.org/genproto/googleapis/cloud/vision/v1" 21) 22 23// FaceLandmarks contains the positions of facial features detected by the service. 24type FaceLandmarks struct { 25 Eyebrows Eyebrows 26 Eyes Eyes 27 Ears Ears 28 Nose Nose 29 Mouth Mouth 30 Chin Chin 31 Forehead *pb.Position 32} 33 34// Eyebrows represents a face's eyebrows. 35type Eyebrows struct { 36 Left, Right Eyebrow 37} 38 39// Eyebrow represents a face's eyebrow. 40type Eyebrow struct { 41 Top, Left, Right *pb.Position 42} 43 44// Eyes represents a face's eyes. 45type Eyes struct { 46 Left, Right Eye 47} 48 49// Eye represents a face's eye. 50type Eye struct { 51 Left, Right, Top, Bottom, Center, Pupil *pb.Position 52} 53 54// Ears represents a face's ears. 55type Ears struct { 56 Left, Right *pb.Position 57} 58 59// Nose represents a face's nose. 60type Nose struct { 61 Left, Right, Top, Bottom, Tip *pb.Position 62} 63 64// Mouth represents a face's mouth. 65type Mouth struct { 66 Left, Center, Right, UpperLip, LowerLip *pb.Position 67} 68 69// Chin represents a face's chin. 70type Chin struct { 71 Left, Center, Right *pb.Position 72} 73 74// FaceFromLandmarks converts the list of face landmarks returned by the service 75// to a FaceLandmarks struct. 76func FaceFromLandmarks(landmarks []*pb.FaceAnnotation_Landmark) *FaceLandmarks { 77 face := &FaceLandmarks{} 78 for _, lm := range landmarks { 79 switch lm.Type { 80 case pb.FaceAnnotation_Landmark_LEFT_OF_LEFT_EYEBROW: 81 face.Eyebrows.Left.Left = lm.Position 82 case pb.FaceAnnotation_Landmark_RIGHT_OF_LEFT_EYEBROW: 83 face.Eyebrows.Left.Right = lm.Position 84 case pb.FaceAnnotation_Landmark_LEFT_OF_RIGHT_EYEBROW: 85 face.Eyebrows.Right.Left = lm.Position 86 case pb.FaceAnnotation_Landmark_RIGHT_OF_RIGHT_EYEBROW: 87 face.Eyebrows.Right.Right = lm.Position 88 case pb.FaceAnnotation_Landmark_LEFT_EYEBROW_UPPER_MIDPOINT: 89 face.Eyebrows.Left.Top = lm.Position 90 case pb.FaceAnnotation_Landmark_RIGHT_EYEBROW_UPPER_MIDPOINT: 91 face.Eyebrows.Right.Top = lm.Position 92 case pb.FaceAnnotation_Landmark_MIDPOINT_BETWEEN_EYES: 93 face.Nose.Top = lm.Position 94 case pb.FaceAnnotation_Landmark_NOSE_TIP: 95 face.Nose.Tip = lm.Position 96 case pb.FaceAnnotation_Landmark_UPPER_LIP: 97 face.Mouth.UpperLip = lm.Position 98 case pb.FaceAnnotation_Landmark_LOWER_LIP: 99 face.Mouth.LowerLip = lm.Position 100 case pb.FaceAnnotation_Landmark_MOUTH_LEFT: 101 face.Mouth.Left = lm.Position 102 case pb.FaceAnnotation_Landmark_MOUTH_RIGHT: 103 face.Mouth.Right = lm.Position 104 case pb.FaceAnnotation_Landmark_MOUTH_CENTER: 105 face.Mouth.Center = lm.Position 106 case pb.FaceAnnotation_Landmark_NOSE_BOTTOM_RIGHT: 107 face.Nose.Right = lm.Position 108 case pb.FaceAnnotation_Landmark_NOSE_BOTTOM_LEFT: 109 face.Nose.Left = lm.Position 110 case pb.FaceAnnotation_Landmark_NOSE_BOTTOM_CENTER: 111 face.Nose.Bottom = lm.Position 112 case pb.FaceAnnotation_Landmark_LEFT_EYE: 113 face.Eyes.Left.Center = lm.Position 114 case pb.FaceAnnotation_Landmark_RIGHT_EYE: 115 face.Eyes.Right.Center = lm.Position 116 case pb.FaceAnnotation_Landmark_LEFT_EYE_TOP_BOUNDARY: 117 face.Eyes.Left.Top = lm.Position 118 case pb.FaceAnnotation_Landmark_LEFT_EYE_RIGHT_CORNER: 119 face.Eyes.Left.Right = lm.Position 120 case pb.FaceAnnotation_Landmark_LEFT_EYE_BOTTOM_BOUNDARY: 121 face.Eyes.Left.Bottom = lm.Position 122 case pb.FaceAnnotation_Landmark_LEFT_EYE_LEFT_CORNER: 123 face.Eyes.Left.Left = lm.Position 124 case pb.FaceAnnotation_Landmark_RIGHT_EYE_TOP_BOUNDARY: 125 face.Eyes.Right.Top = lm.Position 126 case pb.FaceAnnotation_Landmark_RIGHT_EYE_RIGHT_CORNER: 127 face.Eyes.Right.Right = lm.Position 128 case pb.FaceAnnotation_Landmark_RIGHT_EYE_BOTTOM_BOUNDARY: 129 face.Eyes.Right.Bottom = lm.Position 130 case pb.FaceAnnotation_Landmark_RIGHT_EYE_LEFT_CORNER: 131 face.Eyes.Right.Left = lm.Position 132 case pb.FaceAnnotation_Landmark_LEFT_EYE_PUPIL: 133 face.Eyes.Left.Pupil = lm.Position 134 case pb.FaceAnnotation_Landmark_RIGHT_EYE_PUPIL: 135 face.Eyes.Right.Pupil = lm.Position 136 case pb.FaceAnnotation_Landmark_LEFT_EAR_TRAGION: 137 face.Ears.Left = lm.Position 138 case pb.FaceAnnotation_Landmark_RIGHT_EAR_TRAGION: 139 face.Ears.Right = lm.Position 140 case pb.FaceAnnotation_Landmark_FOREHEAD_GLABELLA: 141 face.Forehead = lm.Position 142 case pb.FaceAnnotation_Landmark_CHIN_GNATHION: 143 face.Chin.Center = lm.Position 144 case pb.FaceAnnotation_Landmark_CHIN_LEFT_GONION: 145 face.Chin.Left = lm.Position 146 case pb.FaceAnnotation_Landmark_CHIN_RIGHT_GONION: 147 face.Chin.Right = lm.Position 148 default: 149 log.Printf("vision: ignoring unknown face annotation landmark %s", lm.Type) 150 } 151 } 152 return face 153} 154