FaceDetails CreateFaceDetails(Person person) { FaceDetails face = new FaceDetails(); face.questUID = person.ParentQuest.UID; face.targetPerson = person.Symbol; face.targetRace = person.Race; face.gender = person.Gender; face.isChild = person.FactionData.id == (int)FactionFile.FactionIDs.Children; face.faceIndex = person.FaceIndex; face.factionFaceIndex = -1; // Read faction face index for fixed NPCs if (person.IsIndividualNPC) { FactionFile.FactionData fd; if (GameManager.Instance.PlayerEntity.FactionData.GetFactionData(person.FactionIndex, out fd)) { face.factionFaceIndex = fd.face; } } // Determine child faction portrait - there are only 2 variants of each gender indexed 0-3 if (face.isChild) { UnityEngine.Random.InitState(Time.frameCount); int variantOffset = (UnityEngine.Random.Range(0, 2) == 0) ? 0 : 2; face.faceIndex = variantOffset + (int)face.gender; } return(face); }
FaceDetails CreateFaceDetails(Person person) { // TODO: Support child portrait selection FaceDetails face = new FaceDetails(); face.questUID = person.ParentQuest.UID; face.targetPerson = person.Symbol; face.targetRace = person.Race; face.gender = person.Gender; face.faceIndex = person.FaceIndex; face.factionFaceIndex = -1; // Read faction face index for fixed NPCs if (person.IsIndividualNPC) { FactionFile.FactionData fd; if (GameManager.Instance.PlayerEntity.FactionData.GetFactionData(person.FactionIndex, out fd)) { face.factionFaceIndex = fd.face; } } return(face); }
private static FaceDetails MapToDomain(this Microsoft.ProjectOxford.Face.Contract.Face face) { var emotion = GetEmotionValueFromScores(face.FaceAttributes.Emotion); var domainEntity = new FaceDetails() { FaceId = face.FaceId.ToString(), Age = face.FaceAttributes.Age, Emotion = emotion.emotionValue, EmotionScore = emotion.emotionScore, HasBeard = face.FaceAttributes.FacialHair.Beard > FacialHairThreshold, BeardScore = face.FaceAttributes.FacialHair.Beard, HasMoustache = face.FaceAttributes.FacialHair.Moustache > FacialHairThreshold, MoustacheScore = face.FaceAttributes.FacialHair.Moustache, HasSideburns = face.FaceAttributes.FacialHair.Sideburns > FacialHairThreshold, SideburnsScore = face.FaceAttributes.FacialHair.Sideburns, Gender = face.FaceAttributes.Gender == "male" ? Gender.Male : Gender.Female, HasGlasses = face.FaceAttributes.Glasses != Microsoft.ProjectOxford.Face.Contract.Glasses.NoGlasses, GlassesType = (GlassesType)face.FaceAttributes.Glasses, HeadPose = new HeadPose() { Pitch = face.FaceAttributes.HeadPose.Pitch, Roll = face.FaceAttributes.HeadPose.Roll, Yaw = face.FaceAttributes.HeadPose.Yaw }, SmileScore = face.FaceAttributes.Smile, BoundingBox = new Rectangle { X = face.FaceRectangle.Left, Y = face.FaceRectangle.Top, Width = face.FaceRectangle.Width, Height = face.FaceRectangle.Height }, }; return(domainEntity); }
FaceDetails CreateFaceDetails(Person person) { FaceDetails face = new FaceDetails(); face.questUID = person.ParentQuest.UID; face.targetPerson = person.Symbol; face.targetRace = person.HUDRace; face.gender = person.Gender; face.faceIndex = person.FaceIndex; return(face); }
public static bool ReflectedEquals(FaceDetails a, FaceDetails b) { return((a.topLeft == b.topRight) && (a.top == b.top) && (a.topRight == b.topLeft) && (a.left == b.right) && (a.center == b.center) && (a.right == b.left) && (a.bottomLeft == b.bottomRight) && (a.bottom == b.bottom) && (a.bottomRight == b.bottomLeft)); }
private void TargetImage_SizeChanged(object sender, SizeChangedEventArgs e) { Faces.Children.Clear(); if (CurrentPhoto.DetectedFaces != null && CurrentPhoto.DetectedFaces.Any()) { foreach (var face in CurrentPhoto.DetectedFaces) { var rect = new FaceDetails(face, TargetImage.RenderSize, photoFile.PixelWidth, photoFile.PixelHeight); Faces.Children.Add(rect); } } }
FaceDetails CreateFaceDetails(Foe foe) { UnityEngine.Random.InitState(Time.frameCount); FaceDetails face = new FaceDetails(); face.questUID = foe.ParentQuest.UID; face.targetFoe = foe.Symbol; face.targetRace = Races.Breton; face.gender = foe.Gender; face.faceIndex = UnityEngine.Random.Range(0, faceCount); face.factionFaceIndex = -1; return(face); }
/// <summary> /// Given a FaceDetails on given face of the cube, /// rotates the cube, and returns the new face and correctly oriented FaceDetails /// </summary> internal static (FaceDir, FaceDetails) ApplyRotator(FaceDir faceDir, FaceDetails faceDetails, MatrixInt3x3 rotator) { var rotatedFaceDirForward = rotator.Multiply(faceDir.Forward()); var rotatedFaceDirUp = rotator.Multiply(faceDir.Up()); var rotatedFaceDirRight = rotator.Multiply(Vector3.Cross(faceDir.Forward(), faceDir.Up())); var rotatedFaceDir = FromNormal(rotatedFaceDirForward); var trueUp = rotatedFaceDir.Up(); var trueForward = rotatedFaceDirForward; // = rotatedFaceDir.Forward(); var trueRight = Vector3.Cross(trueForward, trueUp); // Find the rotation that will map rotatedFaceDirUp to trueUp // and rotatedFaceDirRight to trueRight var dot = Vector3.Dot(rotatedFaceDirUp, trueUp); var cross = Vector3.Dot(rotatedFaceDirUp, trueRight); Rotation faceRot; if (dot == 1) { faceRot = new Rotation(); } else if (dot == -1) { faceRot = new Rotation(180); } else if (cross == 1) { faceRot = new Rotation(270); } else if (cross == -1) { faceRot = new Rotation(90); } else { throw new Exception(); } if (Vector3.Dot(Vector3.Cross(rotatedFaceDirForward, rotatedFaceDirUp), rotatedFaceDirRight) < 0) { faceRot = new Rotation(360 - faceRot.RotateCw, true); } var rotatedFaceDetails = faceDetails.RotateBy(faceRot); return(rotatedFaceDir, rotatedFaceDetails); }
// By calling this function, Unity will draw the box plane around the face at the correct position void DrawPlane(BoundingBox[] boxes, FaceDetails[] faces) { // First loops through the amount of boxes there are for (int i = 0; i < boxCount; i++) { // Get all the boxes and faces BoundingBox box = boxes[i]; FaceDetails face = faces[i]; GameObject plane = planes[i]; TextMesh script = texts[i].GetComponent <TextMesh>(); // Get screen point to world space Ray ray = firstPersonCamera.ScreenPointToRay(new Vector3((float)box.CenterX, (float)box.CenterY, 0.15f)); // Put ray until 0.5f Vector3 worldPoint = ray.GetPoint(0.5f); // Scale things correctly since the original box around the face is too big plane.transform.localScale = new Vector3((float)(box.Width) / 2800, (float)(box.Height) / 2800, 0.0001f); // 2800 and 6000 plane.transform.position = worldPoint; plane.transform.LookAt(firstPersonCamera.transform); // Section for displaying text script.text = "Age: " + (int)face.AgeLow + " - " + (int)face.AgeHigh + "\n" + "Smile - " + face.SmileValue + " (" + ((float)face.SmileConfidence).ToString("F2") + "%)\n" + face.GenderValue + " (" + ((float)face.GenderConfidence).ToString("F2") + "%)\n"; // Make the text have the same rotation as the plane script.transform.rotation = new Quaternion(0, 1, 0, 0) * plane.transform.rotation; // Put the text relative to the plane script.transform.position = plane.transform.position + plane.transform.TransformDirection(new Vector3(-0.01f - ((float)box.Width / 5600), 0.07f, 0)); // Enable all renderers plane.GetComponent <Renderer>().enabled = true; script.GetComponent <Renderer>().enabled = true; } }
// This function is the same as the one above except that it parses for facial details instead public FaceDetails[] ParseResponseFace(string responseText) { // FaceDetails array FaceDetails[] faces = new FaceDetails[100]; // Face Details string boundingbox = "BoundingBox"; string ageLow = "'Low': "; string ageHigh = "'High': "; string smileValue = "'Smile': {'Value': "; string smileConfidence = "'Smile': {'Value': "; string genderValue = "'Gender': {'Value': '"; string genderConfidence = "'Gender': {'Value': '"; int wordOccurence = 0; int count = 0; int index = 0; long ten = 1; // Check for multiple bounding boxes while ((wordOccurence = responseText.IndexOf(boundingbox, wordOccurence)) != -1) { // Create new face detail after deleting the old ones FaceDetails face = new FaceDetails(); if (texts[count] != null) { Destroy(texts[count]); } GameObject text = new GameObject(); text.transform.SetParent(this.transform); text.transform.localScale = new Vector3(0.01f, 0.01f, 0.01f); TextMesh textMesh = text.AddComponent <TextMesh>(); textMesh.color = Color.red; // Check for Age if (responseText.Contains(ageLow) && responseText.Contains(ageHigh)) { // Check for age low while (responseText[responseText.IndexOf(ageLow, wordOccurence) + ageLow.Length + index] != ',') { face.AgeLow += (decimal)(char.GetNumericValue(responseText[responseText.IndexOf(ageLow, wordOccurence) + ageLow.Length + index]) / ten); ten *= 10; index++; } index = 0; ten = 1; // Check for age high while (responseText[responseText.IndexOf(ageHigh, wordOccurence) + ageHigh.Length + index] != ',') { face.AgeHigh += (decimal)(char.GetNumericValue(responseText[responseText.IndexOf(ageHigh, wordOccurence) + ageHigh.Length + index]) / ten); ten *= 10; index++; } index = 0; ten = 1; // Modulate ageLow and ageHigh face.AgeLow *= 10; face.AgeHigh *= 10; face.AgeHigh += 1; } // Check for Smile if (responseText.Contains(smileValue)) { // Check for age low while (responseText[responseText.IndexOf(smileValue, wordOccurence) + smileValue.Length + index] != ',') { face.SmileValue += responseText[responseText.IndexOf(smileValue, wordOccurence) + smileValue.Length + index]; index++; } index = 0; ten = 1; smileConfidence += face.SmileValue + ", 'Confidence': "; // Check for age high while (responseText[responseText.IndexOf(smileConfidence, wordOccurence) + smileConfidence.Length + index] != ',') { if (responseText[responseText.IndexOf(smileConfidence, wordOccurence) + smileConfidence.Length + index] == '.') { index++; } face.SmileConfidence += (decimal)(char.GetNumericValue(responseText[responseText.IndexOf(smileConfidence, wordOccurence) + smileConfidence.Length + index]) / ten); ten *= 10; index++; } index = 0; ten = 1; // Modlulate confidence face.SmileConfidence *= 10; } // Check for gender if (responseText.Contains(genderValue)) { // Check for age low while (responseText[responseText.IndexOf(genderValue, wordOccurence) + genderValue.Length + index] != '\'') { face.GenderValue += responseText[responseText.IndexOf(genderValue, wordOccurence) + genderValue.Length + index]; index++; } index = 0; ten = 1; genderConfidence += face.GenderValue + "', 'Confidence': "; // Check for age high while (responseText[responseText.IndexOf(genderConfidence, wordOccurence) + genderConfidence.Length + index] != ',') { if (responseText[responseText.IndexOf(genderConfidence, wordOccurence) + genderConfidence.Length + index] == '.') { index++; } face.GenderConfidence += (decimal)(char.GetNumericValue(responseText[responseText.IndexOf(genderConfidence, wordOccurence) + genderConfidence.Length + index]) / ten); ten *= 10; index++; } index = 0; ten = 1; // Modulate confidence face.GenderConfidence *= 10; } // Face logs //Debug.Log("face.AgeLow = " + (int)face.AgeLow + " face.AgeHigh = " + (int)face.AgeHigh); //Debug.Log("face.SmileValue = " + face.SmileValue + " face.SmileConfidence = " + face.SmileConfidence); //Debug.Log("face.GenderValue = " + face.GenderValue + " face.GenderConfidence = " + face.GenderConfidence); // Increase number of wordOccurence wordOccurence += responseText.IndexOf(boundingbox, wordOccurence); // Add the boxes to the array faces[count] = face; texts[count] = text; // Increase count count++; } // Return the faces detected (ie info) return(faces); }
public async Task <FaceResult> GetFaceResult(Stream imageStream) { try { var result = await _faceClient.Face.DetectWithStreamAsync(imageStream, true, true, new List <FaceAttributeType> { FaceAttributeType.Emotion, FaceAttributeType.Gender, FaceAttributeType.Age }); var faceResult = new FaceResult(); foreach (var face in result) { var emotionType = string.Empty; var emotionValue = 0.0; var emotion = face.FaceAttributes.Emotion; if (emotion.Anger > emotionValue) { emotionValue = emotion.Anger; emotionType = "Anger"; } if (emotion.Contempt > emotionValue) { emotionValue = emotion.Contempt; emotionType = "Contempt"; } if (emotion.Disgust > emotionValue) { emotionValue = emotion.Disgust; emotionType = "Disgust"; } if (emotion.Fear > emotionValue) { emotionValue = emotion.Fear; emotionType = "Fear"; } if (emotion.Happiness > emotionValue) { emotionValue = emotion.Happiness; emotionType = "Happiness"; } if (emotion.Neutral > emotionValue) { emotionValue = emotion.Neutral; emotionType = "Neutral"; } if (emotion.Sadness > emotionValue) { emotionValue = emotion.Sadness; emotionType = "Sadness"; } if (emotion.Surprise > emotionValue) { emotionType = "Surprise"; } var faceDetails = new FaceDetails { Gender = face.FaceAttributes.Gender.ToString(), Emotion = emotionType }; faceResult.Details.Add(faceDetails); } return(faceResult); } catch (Exception ex) { return(new FaceResult()); } }
public void Deconstruct(out Vector3Int offset, out FaceDir faceDir, out FaceDetails faceDetails) { offset = this.offset; faceDir = this.faceDir; faceDetails = this.faceDetails; }
public OrientedFace(Vector3Int offset, FaceDir faceDir, FaceDetails faceDetails) { this.offset = offset; this.faceDir = faceDir; this.faceDetails = faceDetails; }
/// <summary> /// Finds the face details for a cell with a given offeset. /// </summary> public bool TryGet(Vector3Int offset, FaceDir faceDir, out FaceDetails details) { details = faceDetails.SingleOrDefault(x => x.offset == offset && x.faceDir == faceDir).faceDetails; return(details != null); }