public MatchedSimilarFace(SimilarFace similarFace) { similarFace.Validate(); FaceId = similarFace.FaceId; PersistedFaceId = similarFace.PersistedFaceId; Confidence = similarFace.Confidence; }
public async Task FindSimilarPersistedFacesAsync() { this.SimilarFaceMatches = Enumerable.Empty <SimilarFaceMatch>(); if (this.DetectedFaces == null || !this.DetectedFaces.Any()) { return; } List <SimilarFaceMatch> result = new List <SimilarFaceMatch>(); foreach (DetectedFace detectedFace in this.DetectedFaces) { try { SimilarFace similarPersistedFace = null; if (this.ImageUrl != null) { similarPersistedFace = await FaceListManager.FindSimilarPersistedFaceAsync(ImageUrl, detectedFace.FaceId.GetValueOrDefault(), detectedFace); } else { similarPersistedFace = await FaceListManager.FindSimilarPersistedFaceAsync(this.GetImageStreamCallback, detectedFace.FaceId.GetValueOrDefault(), detectedFace); } if (similarPersistedFace != null) { result.Add(new SimilarFaceMatch { Face = detectedFace, SimilarPersistedFace = similarPersistedFace }); } } catch (Exception e) { ErrorTrackingHelper.TrackException(e, "FaceListManager.FindSimilarPersistedFaceAsync error"); if (this.ShowDialogOnFaceApiErrors) { await ErrorTrackingHelper.GenericApiCallExceptionHandler(e, "Failure finding similar faces"); } } } this.SimilarFaceMatches = result; }
/// <summary> /// Busca si existen rostros actualmente registrados. /// </summary> /// <param name="faceId"></param> /// <param name="facesIds"></param> /// <param name="mode"></param> /// <returns></returns> private async Task <Coincidence> FindSimilarFaceAsync(Guid faceId, Guid[] facesIds, FindSimilarMatchMode mode) { try { SimilarFace[] similarFaces = await _faceClient.FindSimilarAsync(faceId, facesIds, mode); SimilarFace similarFace = similarFaces.ToList().Where(x => x.Confidence > 0.30).FirstOrDefault(); return(new Entities.Coincidence { MatchId = (similarFace != null) ? similarFace.FaceId : Guid.Empty, Confidence = (similarFace != null) ? similarFace.Confidence : 0, NewId = faceId }); } catch (Exception ex) { throw ex; } }
private static async Task <SimilarFace> FindSimilarOrInsertAsync(string imageUrl, Func <Task <Stream> > imageStreamCallback, Guid faceId, DetectedFace face) { if (faceLists == null) { await Initialize(); } Tuple <SimilarFace, string> bestMatch = null; bool foundMatch = false; foreach (var faceListId in faceLists.Keys) { try { SimilarFace similarFace = (await FaceServiceHelper.FindSimilarAsync(faceId, faceListId))?.FirstOrDefault(); if (similarFace == null) { continue; } foundMatch = true; if (bestMatch != null) { // We already found a match for this face in another list. Replace the previous one if the new confidence is higher. if (bestMatch.Item1.Confidence < similarFace.Confidence) { bestMatch = new Tuple <SimilarFace, string>(similarFace, faceListId); } } else { bestMatch = new Tuple <SimilarFace, string>(similarFace, faceListId); } } catch (Exception e) { // Catch errors with individual face lists so we can continue looping through all lists. Maybe an answer will come from // another one. ErrorTrackingHelper.TrackException(e, "Face API FindSimilarAsync error"); } } if (!foundMatch) { // If we are here we didnt' find a match, so let's add the face to the first FaceList that we can add it to. We // might create a new list if none exist, and if all lists are full we will delete the oldest face list (based on when we // last match anything on) so that we can add the new one. double maxAngle = 30; if (face.FaceAttributes.HeadPose != null && (Math.Abs(face.FaceAttributes.HeadPose.Yaw) > maxAngle || Math.Abs(face.FaceAttributes.HeadPose.Pitch) > maxAngle || Math.Abs(face.FaceAttributes.HeadPose.Roll) > maxAngle)) { // This isn't a good frontal shot, so let's not use it as the primary example face for this person return(null); } if (!faceLists.Any()) { // We don't have any FaceLists yet. Create one string newFaceListId = Guid.NewGuid().ToString(); await FaceServiceHelper.CreateFaceListAsync(newFaceListId, "ManagedFaceList", FaceListsUserDataFilter); faceLists.Add(newFaceListId, new FaceListInfo { FaceListId = newFaceListId, LastMatchTimestamp = DateTime.Now }); } PersistedFace addResult = null; bool failedToAddToNonFullList = false; foreach (var faceList in faceLists) { if (faceList.Value.IsFull) { continue; } try { if (imageUrl != null) { addResult = await FaceServiceHelper.AddFaceToFaceListFromUrlAsync(faceList.Key, imageUrl, face.FaceRectangle); } else { addResult = await FaceServiceHelper.AddFaceToFaceListFromStreamAsync(faceList.Key, imageStreamCallback, face.FaceRectangle); } break; } catch (Exception ex) { if (ex is APIErrorException && ((APIErrorException)ex).Response.StatusCode == (System.Net.HttpStatusCode) 403) { // FaceList is full. Continue so we can try again with the next FaceList faceList.Value.IsFull = true; continue; } else { failedToAddToNonFullList = true; break; } } } if (addResult == null && !failedToAddToNonFullList) { // We were not able to add the face to an existing list because they were all full. // If possible, let's create a new list now and add the new face to it. If we can't (e.g. we already maxed out on list count), // let's delete an old list, create a new one and add the new face to it. if (faceLists.Count == MaxFaceListCount) { // delete oldest face list var oldestFaceList = faceLists.OrderBy(fl => fl.Value.LastMatchTimestamp).FirstOrDefault(); faceLists.Remove(oldestFaceList.Key); await FaceServiceHelper.DeleteFaceListAsync(oldestFaceList.Key); } // create new list string newFaceListId = Guid.NewGuid().ToString(); await FaceServiceHelper.CreateFaceListAsync(newFaceListId, "ManagedFaceList", FaceListsUserDataFilter); faceLists.Add(newFaceListId, new FaceListInfo { FaceListId = newFaceListId, LastMatchTimestamp = DateTime.Now }); // Add face to new list if (imageUrl != null) { addResult = await FaceServiceHelper.AddFaceToFaceListFromUrlAsync(newFaceListId, imageUrl, face.FaceRectangle); } else { addResult = await FaceServiceHelper.AddFaceToFaceListFromStreamAsync(newFaceListId, imageStreamCallback, face.FaceRectangle); } } if (addResult != null) { bestMatch = new Tuple <SimilarFace, string>(new SimilarFace { Confidence = 1, PersistedFaceId = addResult.PersistedFaceId }, null); } } return(bestMatch?.Item1); }
private void ShowFaceTrackingVisualization(Windows.Foundation.Size framePixelSize, IEnumerable <Windows.Media.FaceAnalysis.DetectedFace> detectedFaces) { this.FaceTrackingVisualizationCanvas.Children.Clear(); double actualWidth = this.FaceTrackingVisualizationCanvas.ActualWidth; double actualHeight = this.FaceTrackingVisualizationCanvas.ActualHeight; if (captureManager.CameraStreamState == Windows.Media.Devices.CameraStreamState.Streaming && detectedFaces != null && actualWidth != 0 && actualHeight != 0) { double widthScale = framePixelSize.Width / actualWidth; double heightScale = framePixelSize.Height / actualHeight; foreach (Windows.Media.FaceAnalysis.DetectedFace face in detectedFaces) { RealTimeFaceIdentificationBorder faceBorder = new RealTimeFaceIdentificationBorder(); this.FaceTrackingVisualizationCanvas.Children.Add(faceBorder); faceBorder.ShowFaceRectangle((uint)(face.FaceBox.X / widthScale), (uint)(face.FaceBox.Y / heightScale), (uint)(face.FaceBox.Width / widthScale), (uint)(face.FaceBox.Height / heightScale)); if (this.realTimeDataProvider != null) { Microsoft.Azure.CognitiveServices.Vision.Face.Models.DetectedFace detectedFace = this.realTimeDataProvider.GetLastFaceAttributesForFace(face.FaceBox); IdentifiedPerson identifiedPerson = this.realTimeDataProvider.GetLastIdentifiedPersonForFace(face.FaceBox); SimilarFace similarPersistedFace = this.realTimeDataProvider.GetLastSimilarPersistedFaceForFace(face.FaceBox); string uniqueId = null; if (similarPersistedFace != null) { uniqueId = similarPersistedFace.PersistedFaceId.GetValueOrDefault().ToString("N").Substring(0, 4); } if (detectedFace != null && detectedFace.FaceAttributes != null) { if (identifiedPerson != null && identifiedPerson.Person != null) { // age, gender and id available faceBorder.ShowIdentificationData(detectedFace.FaceAttributes.Age.GetValueOrDefault(), detectedFace.FaceAttributes.Gender?.ToString(), (uint)Math.Round(identifiedPerson.Confidence * 100), identifiedPerson.Person.Name, uniqueId: uniqueId); } else { // only age and gender available faceBorder.ShowIdentificationData(detectedFace.FaceAttributes.Age.GetValueOrDefault(), detectedFace.FaceAttributes.Gender?.ToString(), 0, null, uniqueId: uniqueId); } faceBorder.ShowRealTimeEmotionData(detectedFace.FaceAttributes.Emotion); } else if (identifiedPerson != null && identifiedPerson.Person != null) { // only id available faceBorder.ShowIdentificationData(0, null, (uint)Math.Round(identifiedPerson.Confidence * 100), identifiedPerson.Person.Name, uniqueId: uniqueId); } else if (uniqueId != null) { // only unique id available faceBorder.ShowIdentificationData(0, null, 0, null, uniqueId: uniqueId); } } if (SettingsHelper.Instance.ShowDebugInfo) { this.FaceTrackingVisualizationCanvas.Children.Add(new TextBlock { Text = string.Format("Coverage: {0:0}%", 100 * ((double)face.FaceBox.Height / this.videoProperties.Height)), Margin = new Thickness((uint)(face.FaceBox.X / widthScale), (uint)(face.FaceBox.Y / heightScale), 0, 0) }); } } } }