public static async Task ResetFaceLists() { faceLists = new Dictionary <string, FaceListInfo>(); try { IEnumerable <FaceListMetadata> metadata = await FaceServiceHelper.GetFaceListsAsync(FaceListsUserDataFilter); foreach (var item in metadata) { await FaceServiceHelper.DeleteFaceListAsync(item.FaceListId); } } catch (Exception e) { ErrorTrackingHelper.TrackException(e, "Error resetting face lists"); } }
public static async Task Initialize() { faceLists = new Dictionary <string, FaceListInfo>(); try { IEnumerable <FaceListMetadata> metadata = await FaceServiceHelper.GetFaceListsAsync(FaceListsUserDataFilter); foreach (var item in metadata) { faceLists.Add(item.FaceListId, new FaceListInfo { FaceListId = item.FaceListId, LastMatchTimestamp = DateTime.Now }); } } catch (Exception e) { ErrorTrackingHelper.TrackException(e, "Face API GetFaceListsAsync error"); } }
private async Task <TResponse> RunTaskWithAutoRetryOnQuotaLimitExceededError <TResponse>(Func <Task <TResponse> > action) { int retriesLeft = RetryCountOnQuotaLimitError; int delay = RetryDelayOnQuotaLimitError; TResponse response = default(TResponse); while (true) { try { response = await action(); break; } catch (FaceAPIException exception) when(exception.HttpStatus == (System.Net.HttpStatusCode) 429 && retriesLeft > 0) { ErrorTrackingHelper.TrackException(exception, "Face API throttling error"); if (retriesLeft == 1 && Throttled != null) { Throttled(); } await Task.Delay(delay); retriesLeft--; delay *= 2; Console.WriteLine("delay: " + delay); Console.WriteLine("retriesLeft: " + retriesLeft); continue; } catch (FaceAPIException exception) when(exception.HttpStatus != (System.Net.HttpStatusCode) 429 || retriesLeft <= 0) { throw exception; } } return(response); }
public async Task AnalyzeImageAsync(bool detectCelebrities = false, IEnumerable <VisualFeature> visualFeatures = null) { try { if (visualFeatures == null) { visualFeatures = DefaultVisualFeatures; } if (this.ImageUrl != null) { this.AnalysisResult = await VisionServiceHelper.AnalyzeImageAsync( this.ImageUrl, visualFeatures, detectCelebrities?new string[] { "Celebrities" } : null); } else if (this.GetImageStreamCallback != null) { this.AnalysisResult = await VisionServiceHelper.AnalyzeImageAsync( this.GetImageStreamCallback, visualFeatures, detectCelebrities?new string[] { "Celebrities" } : null); } } catch (Exception e) { this.AnalysisResult = new Microsoft.ProjectOxford.Vision.Contract.AnalysisResult(); if (this.ShowDialogOnFaceApiErrors) { await ErrorTrackingHelper.GenericApiCallExceptionHandler(e, "Lỗi phân tích."); } } finally { this.ComputerVisionAnalysisCompleted?.Invoke(this, EventArgs.Empty); } }
public async Task DescribeAsync() { try { if (this.ImageUrl != null) { this.AnalysisResult = await VisionServiceHelper.DescribeAsync(this.ImageUrl); } else if (this.GetImageStreamCallback != null) { this.AnalysisResult = await VisionServiceHelper.DescribeAsync(this.GetImageStreamCallback); } } catch (Exception e) { this.AnalysisResult = new Microsoft.ProjectOxford.Vision.Contract.AnalysisResult(); if (this.ShowDialogOnFaceApiErrors) { await ErrorTrackingHelper.GenericApiCallExceptionHandler(e, "Lỗi phân tích."); } } }
public async Task FindSimilarPersistedFacesAsync() { this.SimilarFaceMatches = Enumerable.Empty <SimilarFaceMatch>(); if (this.DetectedFaces == null || !this.DetectedFaces.Any()) { return; } List <SimilarFaceMatch> result = new List <SimilarFaceMatch>(); foreach (Face detectedFace in this.DetectedFaces) { try { SimilarPersistedFace similarPersistedFace = await FaceListManager.FindSimilarPersistedFaceAsync(this.GetImageStreamCallback, detectedFace.FaceId, 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, "Không tìm thấy khuôn mặt tương tự"); } } } this.SimilarFaceMatches = result; }
public async Task IdentifyFacesAsync() { this.IdentifiedPersons = Enumerable.Empty <IdentifiedPerson>(); Guid[] detectedFaceIds = this.DetectedFaces?.Select(f => f.FaceId).ToArray(); if (detectedFaceIds != null && detectedFaceIds.Any()) { List <IdentifiedPerson> result = new List <IdentifiedPerson>(); IEnumerable <PersonGroup> personGroups = Enumerable.Empty <PersonGroup>(); try { personGroups = await FaceServiceHelper.GetPersonGroupsAsync(PeopleGroupsUserDataFilter); } catch (Exception e) { ErrorTrackingHelper.TrackException(e, "Nhận diện khuôn mặt trong nhóm lỗi"); if (this.ShowDialogOnFaceApiErrors) { await ErrorTrackingHelper.GenericApiCallExceptionHandler(e, "Lỗi lấy nhóm nhận diện"); } } foreach (var group in personGroups) { try { IdentifyResult[] groupResults = await FaceServiceHelper.IdentifyAsync(group.PersonGroupId, detectedFaceIds); foreach (var match in groupResults) { if (!match.Candidates.Any()) { continue; } Person person = await FaceServiceHelper.GetPersonAsync(group.PersonGroupId, match.Candidates[0].PersonId); IdentifiedPerson alreadyIdentifiedPerson = result.FirstOrDefault(p => p.Person.PersonId == match.Candidates[0].PersonId); if (alreadyIdentifiedPerson != null) { // We already tagged this person in another group. Replace the existing one if this new one if the confidence is higher. if (alreadyIdentifiedPerson.Confidence < match.Candidates[0].Confidence) { alreadyIdentifiedPerson.Person = person; alreadyIdentifiedPerson.Confidence = match.Candidates[0].Confidence; alreadyIdentifiedPerson.FaceId = match.FaceId; } } else { result.Add(new IdentifiedPerson { Person = person, Confidence = match.Candidates[0].Confidence, FaceId = match.FaceId }); } } } catch (Exception e) { // Catch errors with individual groups so we can continue looping through all groups. Maybe an answer will come from // another one. // ErrorTrackingHelper.TrackException(e, "Lỗi nhận diện khuôn mặt"); if (this.ShowDialogOnFaceApiErrors) { // await ErrorTrackingHelper.GenericApiCallExceptionHandler(e, "Lỗi nhận diện khuôn mặt"); } } } this.IdentifiedPersons = result; } this.OnFaceRecognitionCompleted(); }
public static async Task <SimilarPersistedFace> FindSimilarPersistedFaceAsync(Func <Task <Stream> > imageStreamCallback, Guid faceId, Face face) { if (faceLists == null) { await Initialize(); } Tuple <SimilarPersistedFace, string> bestMatch = null; bool foundMatch = false; foreach (var faceListId in faceLists.Keys) { try { SimilarPersistedFace 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 <SimilarPersistedFace, string>(similarFace, faceListId); } } else { bestMatch = new Tuple <SimilarPersistedFace, 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 matched anything on it) 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 }); } AddPersistedFaceResult addResult = null; bool failedToAddToNonFullList = false; foreach (var faceList in faceLists) { if (faceList.Value.IsFull) { continue; } try { addResult = await FaceServiceHelper.AddFaceToFaceListAsync(faceList.Key, imageStreamCallback, face.FaceRectangle); break; } catch (Exception ex) { if (ex is FaceAPIException && ((FaceAPIException)ex).ErrorCode == "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 == 64) { // 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 addResult = await FaceServiceHelper.AddFaceToFaceListAsync(newFaceListId, imageStreamCallback, face.FaceRectangle); } if (addResult != null) { bestMatch = new Tuple <SimilarPersistedFace, string>(new SimilarPersistedFace { Confidence = 1, PersistedFaceId = addResult.PersistedFaceId }, null); } } return(bestMatch?.Item1); }