Exemple #1
0
        public async Task <FaceAnalyzeResponse> AnalyzeAsync(string imageUrl, IFormFile file,
                                                             FaceDetectionModel detectionModel, bool enableIdentification, FaceRecognitionModel recognitionModel,
                                                             FaceIdentificationGroupType identificationGroupType, string identificationGroupId)
        {
            // Face
            if (!string.IsNullOrWhiteSpace(imageUrl))
            {
                var face      = FaceProcessByUrlAsync(imageUrl, detectionModel, enableIdentification, recognitionModel, identificationGroupType, identificationGroupId);
                var imageInfo = ImageInfoProcessor.GetImageInfoFromImageUrlAsync(imageUrl, _httpClientFactory);

                // Combine
                var task = Task.WhenAll(face, imageInfo);
                try
                {
                    await task;
                    return(new FaceAnalyzeResponse
                    {
                        ImageInfo = imageInfo.Result,
                        FaceResult = face.Result
                    });
                }
                catch (APIErrorException ex)
                {
                    var exceptionMessage = ex.Response.Content;
                    var parsedJson       = JToken.Parse(exceptionMessage);

                    if (ex.Response.StatusCode == System.Net.HttpStatusCode.BadRequest)
                    {
                        return(new FaceAnalyzeResponse
                        {
                            ApiRequestErrorMessage = $"Bad request thrown by the underlying API from Microsoft:",
                            ApiRequestErrorContent = parsedJson.ToString(Formatting.Indented)
                        });
                    }
                    else
                    {
                        return(new FaceAnalyzeResponse
                        {
                            OtherErrorMessage = $"Error thrown by the underlying API from Microsoft:",
                            OtherErrorContent = parsedJson.ToString(Formatting.Indented)
                        });
                    }
                }
            }
            else
            {
                using (var analyzeStream = new MemoryStream())
                    using (var outputStream = new MemoryStream())
                    {
                        // Get initial value
                        await file.CopyToAsync(analyzeStream);

                        analyzeStream.Seek(0, SeekOrigin.Begin);
                        await analyzeStream.CopyToAsync(outputStream);

                        // Reset the stream for consumption
                        analyzeStream.Seek(0, SeekOrigin.Begin);
                        outputStream.Seek(0, SeekOrigin.Begin);

                        try
                        {
                            var face = await FaceProcessByStreamAsync(analyzeStream, detectionModel, enableIdentification, recognitionModel, identificationGroupType, identificationGroupId);

                            var imageInfo = ImageInfoProcessor.GetImageInfoFromStream(outputStream, file.ContentType);

                            return(new FaceAnalyzeResponse
                            {
                                ImageInfo = imageInfo,
                                FaceResult = face
                            });
                        }
                        catch (APIErrorException ex)
                        {
                            var exceptionMessage = ex.Response.Content;
                            var parsedJson       = JToken.Parse(exceptionMessage);

                            if (ex.Response.StatusCode == System.Net.HttpStatusCode.BadRequest)
                            {
                                return(new FaceAnalyzeResponse
                                {
                                    ApiRequestErrorMessage = $"Bad request thrown by the underlying API from Microsoft:",
                                    ApiRequestErrorContent = parsedJson.ToString(Formatting.Indented)
                                });
                            }
                            else
                            {
                                return(new FaceAnalyzeResponse
                                {
                                    OtherErrorMessage = $"Error thrown by the underlying API from Microsoft:",
                                    OtherErrorContent = parsedJson.ToString(Formatting.Indented)
                                });
                            }
                        }
                    }
            }
        }
Exemple #2
0
        private async Task <List <FaceAnalyzeItem> > DetectedFacesProcessAsync(IList <DetectedFace> detectedFaces, FaceDetectionModel detectionModel, bool enableIdentification, FaceRecognitionModel recognitionModel, FaceIdentificationGroupType identificationGroupType, string identificationGroupId)
        {
            var unidentifiedResults = detectedFaces.Select(f => new FaceAnalyzeItem {
                DetectedFace = f
            }).ToList();

            if (!enableIdentification || detectedFaces.Count == 0)
            {
                return(unidentifiedResults);
            }

            // Check identification group training status and getting person list for name consolidation
            TrainingStatus identificationGroupTrainingStatus;
            IList <Person> identificationGroupPersons;

            if (FaceIdentificationGroupType.PersonGroup.Equals(identificationGroupType))
            {
                try
                {
                    identificationGroupTrainingStatus = await _faceClient.PersonGroup.GetTrainingStatusAsync(identificationGroupId);
                }
                catch (APIErrorException ex)
                {
                    // If group has never been trained, a 404 is thrown by the API
                    if ("PersonGroupNotTrained".Equals(ex.Body.Error.Code))
                    {
                        // TO DO - Add error info in reply
                        return(unidentifiedResults);
                    }
                    else
                    {
                        throw;
                    }
                }

                identificationGroupPersons = await _faceClient.PersonGroupPerson.ListAsync(identificationGroupId);
            }
            else
            {
                try
                {
                    identificationGroupTrainingStatus = await _faceClient.LargePersonGroup.GetTrainingStatusAsync(identificationGroupId);
                }
                catch (APIErrorException ex)
                {
                    // If group has never been trained, a 404 is thrown by the API
                    if ("PersonGroupNotTrained".Equals(ex.Body.Error.Code))
                    {
                        // TO DO - Add error info in reply
                        return(unidentifiedResults);
                    }
                    else
                    {
                        throw;
                    }
                }

                identificationGroupPersons = await _faceClient.LargePersonGroupPerson.ListAsync(identificationGroupId);
            }

            if (!TrainingStatusType.Succeeded.Equals(identificationGroupTrainingStatus.Status) ||
                identificationGroupPersons == null || identificationGroupPersons.Count == 0)
            {
                // TO DO - Add error info in reply
                return(unidentifiedResults);
            }

            // Identification request: max 10 faces / request (API limitation)
            var batchSize           = 10;
            var batchCount          = (int)Math.Ceiling((double)detectedFaces.Count / batchSize);
            var identificationTasks = new Task <IEnumerable <FaceAnalyzeItem> > [batchCount];

            for (var i = 0; i < batchCount; i++)
            {
                identificationTasks[i] = FaceIdentifyAsync(
                    detectedFaces.Skip(i * batchSize).Take(batchSize),
                    identificationGroupType,
                    identificationGroupId,
                    identificationGroupPersons
                    );
            }

            var identificationResults = await Task.WhenAll(identificationTasks.ToArray());

            var identifiedFaces = identificationResults.SelectMany(i => i).ToList();

            return(identifiedFaces);
        }
Exemple #3
0
        private async Task <IEnumerable <FaceAnalyzeItem> > FaceIdentifyAsync(IEnumerable <DetectedFace> detectedFaces, FaceIdentificationGroupType identificationGroupType, string identificationGroupId, IList <Person> identificationGroupPersons)
        {
            // Call Identification operation
            var identificationResults = FaceIdentificationGroupType.PersonGroup.Equals(identificationGroupType)
                ? await _faceClient.Face.IdentifyAsync(detectedFaces.Select(d => d.FaceId).ToList(),
                                                       personGroupId : identificationGroupId,
                                                       largePersonGroupId : null)
                : await _faceClient.Face.IdentifyAsync(detectedFaces.Select(d => d.FaceId).ToList(),
                                                       personGroupId : null,
                                                       largePersonGroupId : identificationGroupId);

            // Consolidate identifications with info from identification group
            return(detectedFaces.Select(f => new FaceAnalyzeItem()
            {
                DetectedFace = f,
                IdentificationCandidates =
                    identificationResults?
                    .SingleOrDefault(r => r.FaceId == f.FaceId.Value)?
                    .Candidates?
                    .Select(c =>
                            new IdentificationCandidate
                {
                    IdentifyCandidate = c,
                    PersonName = identificationGroupPersons.SingleOrDefault(p => p.PersonId == c.PersonId)?.Name
                }).ToList()
            }));
        }
Exemple #4
0
        private async Task <List <FaceAnalyzeItem> > FaceProcessByStreamAsync(Stream imageStream, FaceDetectionModel detectionModel, bool enableIdentification, FaceRecognitionModel recognitionModel, FaceIdentificationGroupType identificationGroupType, string identificationGroupId)
        {
            var returnFaceId           = false;
            var returnFaceLandmarks    = true;
            var returnFaceAttributes   = FaceAttributes;
            var targetRecognitionModel = FaceRecognitionModel.recognition_01;

            if (FaceDetectionModel.detection_02.Equals(detectionModel))
            {
                returnFaceLandmarks  = false;
                returnFaceAttributes = new List <FaceAttributeType?>();
            }

            if (enableIdentification)
            {
                returnFaceId           = true;
                targetRecognitionModel = recognitionModel;
            }

            var detectedFaces = await _faceClient.Face.DetectWithStreamAsync(
                imageStream,
                returnFaceId : returnFaceId,
                returnFaceLandmarks : returnFaceLandmarks,
                returnFaceAttributes : returnFaceAttributes,
                recognitionModel : targetRecognitionModel.ToString(),
                returnRecognitionModel : true,
                detectionModel : detectionModel.ToString()
                );

            // Process detected faces
            return(await DetectedFacesProcessAsync(detectedFaces, detectionModel, enableIdentification, recognitionModel, identificationGroupType, identificationGroupId));
        }