| // Copyright 2016 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package vision |
| |
| import ( |
| "log" |
| |
| "github.com/golang/geo/r3" |
| pb "google.golang.org/genproto/googleapis/cloud/vision/v1" |
| ) |
| |
| // FaceLandmarks contains the positions of facial features detected by the service. |
| // TODO(jba): write doc for all |
| type FaceLandmarks struct { |
| Eyebrows Eyebrows |
| Eyes Eyes |
| Ears Ears |
| Nose Nose |
| Mouth Mouth |
| Chin Chin |
| Forehead *r3.Vector |
| } |
| |
| type Eyebrows struct { |
| Left, Right Eyebrow |
| } |
| |
| type Eyebrow struct { |
| Top, Left, Right *r3.Vector |
| } |
| |
| type Eyes struct { |
| Left, Right Eye |
| } |
| |
| type Eye struct { |
| Left, Right, Top, Bottom, Center, Pupil *r3.Vector |
| } |
| |
| type Ears struct { |
| Left, Right *r3.Vector |
| } |
| |
| type Nose struct { |
| Left, Right, Top, Bottom, Tip *r3.Vector |
| } |
| |
| type Mouth struct { |
| Left, Center, Right, UpperLip, LowerLip *r3.Vector |
| } |
| |
| type Chin struct { |
| Left, Center, Right *r3.Vector |
| } |
| |
| // FaceLikelihoods expresses the likelihood of various aspects of a face. |
| type FaceLikelihoods struct { |
| // Joy is the likelihood that the face expresses joy. |
| Joy Likelihood |
| |
| // Sorrow is the likelihood that the face expresses sorrow. |
| Sorrow Likelihood |
| |
| // Anger is the likelihood that the face expresses anger. |
| Anger Likelihood |
| |
| // Surprise is the likelihood that the face expresses surprise. |
| Surprise Likelihood |
| |
| // UnderExposed is the likelihood that the face is under-exposed. |
| UnderExposed Likelihood |
| |
| // Blurred is the likelihood that the face is blurred. |
| Blurred Likelihood |
| |
| // Headwear is the likelihood that the face has headwear. |
| Headwear Likelihood |
| } |
| |
| func populateFaceLandmarks(landmarks []*pb.FaceAnnotation_Landmark, face *FaceLandmarks) { |
| for _, lm := range landmarks { |
| pos := &r3.Vector{ |
| X: float64(lm.Position.X), |
| Y: float64(lm.Position.Y), |
| Z: float64(lm.Position.Z), |
| } |
| switch lm.Type { |
| case pb.FaceAnnotation_Landmark_LEFT_OF_LEFT_EYEBROW: |
| face.Eyebrows.Left.Left = pos |
| case pb.FaceAnnotation_Landmark_RIGHT_OF_LEFT_EYEBROW: |
| face.Eyebrows.Left.Right = pos |
| case pb.FaceAnnotation_Landmark_LEFT_OF_RIGHT_EYEBROW: |
| face.Eyebrows.Right.Left = pos |
| case pb.FaceAnnotation_Landmark_RIGHT_OF_RIGHT_EYEBROW: |
| face.Eyebrows.Right.Right = pos |
| case pb.FaceAnnotation_Landmark_LEFT_EYEBROW_UPPER_MIDPOINT: |
| face.Eyebrows.Left.Top = pos |
| case pb.FaceAnnotation_Landmark_RIGHT_EYEBROW_UPPER_MIDPOINT: |
| face.Eyebrows.Right.Top = pos |
| case pb.FaceAnnotation_Landmark_MIDPOINT_BETWEEN_EYES: |
| face.Nose.Top = pos |
| case pb.FaceAnnotation_Landmark_NOSE_TIP: |
| face.Nose.Tip = pos |
| case pb.FaceAnnotation_Landmark_UPPER_LIP: |
| face.Mouth.UpperLip = pos |
| case pb.FaceAnnotation_Landmark_LOWER_LIP: |
| face.Mouth.LowerLip = pos |
| case pb.FaceAnnotation_Landmark_MOUTH_LEFT: |
| face.Mouth.Left = pos |
| case pb.FaceAnnotation_Landmark_MOUTH_RIGHT: |
| face.Mouth.Right = pos |
| case pb.FaceAnnotation_Landmark_MOUTH_CENTER: |
| face.Mouth.Center = pos |
| case pb.FaceAnnotation_Landmark_NOSE_BOTTOM_RIGHT: |
| face.Nose.Right = pos |
| case pb.FaceAnnotation_Landmark_NOSE_BOTTOM_LEFT: |
| face.Nose.Left = pos |
| case pb.FaceAnnotation_Landmark_NOSE_BOTTOM_CENTER: |
| face.Nose.Bottom = pos |
| case pb.FaceAnnotation_Landmark_LEFT_EYE: |
| face.Eyes.Left.Center = pos |
| case pb.FaceAnnotation_Landmark_RIGHT_EYE: |
| face.Eyes.Right.Center = pos |
| case pb.FaceAnnotation_Landmark_LEFT_EYE_TOP_BOUNDARY: |
| face.Eyes.Left.Top = pos |
| case pb.FaceAnnotation_Landmark_LEFT_EYE_RIGHT_CORNER: |
| face.Eyes.Left.Right = pos |
| case pb.FaceAnnotation_Landmark_LEFT_EYE_BOTTOM_BOUNDARY: |
| face.Eyes.Left.Bottom = pos |
| case pb.FaceAnnotation_Landmark_LEFT_EYE_LEFT_CORNER: |
| face.Eyes.Left.Left = pos |
| case pb.FaceAnnotation_Landmark_RIGHT_EYE_TOP_BOUNDARY: |
| face.Eyes.Right.Top = pos |
| case pb.FaceAnnotation_Landmark_RIGHT_EYE_RIGHT_CORNER: |
| face.Eyes.Right.Right = pos |
| case pb.FaceAnnotation_Landmark_RIGHT_EYE_BOTTOM_BOUNDARY: |
| face.Eyes.Right.Bottom = pos |
| case pb.FaceAnnotation_Landmark_RIGHT_EYE_LEFT_CORNER: |
| face.Eyes.Right.Left = pos |
| case pb.FaceAnnotation_Landmark_LEFT_EYE_PUPIL: |
| face.Eyes.Left.Pupil = pos |
| case pb.FaceAnnotation_Landmark_RIGHT_EYE_PUPIL: |
| face.Eyes.Right.Pupil = pos |
| case pb.FaceAnnotation_Landmark_LEFT_EAR_TRAGION: |
| face.Ears.Left = pos |
| case pb.FaceAnnotation_Landmark_RIGHT_EAR_TRAGION: |
| face.Ears.Right = pos |
| case pb.FaceAnnotation_Landmark_FOREHEAD_GLABELLA: |
| face.Forehead = pos |
| case pb.FaceAnnotation_Landmark_CHIN_GNATHION: |
| face.Chin.Center = pos |
| case pb.FaceAnnotation_Landmark_CHIN_LEFT_GONION: |
| face.Chin.Left = pos |
| case pb.FaceAnnotation_Landmark_CHIN_RIGHT_GONION: |
| face.Chin.Right = pos |
| default: |
| log.Printf("vision: ignoring unknown face annotation landmark %s", lm.Type) |
| } |
| } |
| } |