The person entity.
            private async Task <List <FaceImage> > DownloadPersonFaces(Microsoft.ProjectOxford.Face.Contract.Person groupPerson)
            {
                var imgs    = new List <FaceImage>();
                var fimages = new List <FaceImage>();

                foreach (var faceId in groupPerson.PersistedFaceIds)
                {
                    var fm = new FaceImage(await Synchron.Instance.GetFace(faceId))
                    {
                        MicrosoftId = faceId
                    };
                    imgs.Add(fm);
                }

                //foreach (var face in groupPerson.PersistedFaceIds.Select(async x =>
                //{
                //	var fm = new FaceImage(await Synchron.Instance.GetFace(x));
                //	fm.MicrosoftId = x;
                //	return fm;
                //}).ToList())
                //	imgs.Add(await face);
                return(imgs);
            }
        /// <summary>
        /// Pick the root person database folder, to minimum the data preparation logic, the folder should be under following construction
        /// Each person's image should be put into one folder named as the person's name
        /// All person's image folder should be put directly under the root person database folder
        /// </summary>
        /// <param name="sender">Event sender</param>
        /// <param name="e">Event argument</param>
        private async void FolderPicker_Click(object sender, RoutedEventArgs e)
        {
            bool groupExists = false;

            // Test whether the group already exists
            try
            {
                Output = Output.AppendLine(string.Format("Request: Group {0} will be used for build person database. Checking whether group exists.", GroupName));
                await App.Instance.GetPersonGroupAsync(GroupName);
                groupExists = true;
                Output = Output.AppendLine(string.Format("Response: Group {0} exists.", GroupName));
            }
            catch (ClientException ex)
            {
                if (ex.Error.Code != "PersonGroupNotFound")
                {
                    Output = Output.AppendLine(string.Format("Response: {0}. {1}", ex.Error.Code, ex.Error.Message));
                    return;
                }
                else
                {
                    Output = Output.AppendLine(string.Format("Response: Group {0} does not exist before.", GroupName));
                }
            }

            if (groupExists)
            {
                var cleanGroup = System.Windows.MessageBox.Show(string.Format("Requires a clean up for group \"{0}\" before setup new person database. Click OK to proceed, group \"{0}\" will be fully cleaned up.", GroupName), "Warning", MessageBoxButton.OKCancel);
                if (cleanGroup == MessageBoxResult.OK)
                {
                    await App.Instance.DeletePersonGroupAsync(GroupName);
                }
                else
                {
                    return;
                }
            }

            // Show folder picker
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            var result = dlg.ShowDialog();

            // Set the suggestion count is intent to minimum the data preparetion step only,
            // it's not corresponding to service side constraint
            const int SuggestionCount = 15;

            if (result == DialogResult.OK)
            {
                // User picked a root person database folder
                // Clear person database
                Persons.Clear();
                TargetFaces.Clear();
                SelectedFile = null;

                // Call create person group REST API
                // Create person group API call will failed if group with the same name already exists
                Output = Output.AppendLine(string.Format("Request: Creating group \"{0}\"", GroupName));
                try
                {
                    await App.Instance.CreatePersonGroupAsync(GroupName, GroupName);
                    Output = Output.AppendLine(string.Format("Response: Success. Group \"{0}\" created", GroupName));
                }
                catch (ClientException ex)
                {
                    Output = Output.AppendLine(string.Format("Response: {0}. {1}", ex.Error.Code, ex.Error.Message));
                    return;
                }

                int processCount = 0;
                bool forceContinue = false;

                Output = Output.AppendLine("Request: Preparing faces for identification, detecting faces in choosen folder.");

                // Enumerate top level directories, each directory contains one person's images
                foreach (var dir in System.IO.Directory.EnumerateDirectories(dlg.SelectedPath))
                {
                    var tasks = new List<Task>();
                    var tag = System.IO.Path.GetFileName(dir);
                    Person p = new Person();
                    p.PersonName = tag;

                    // Call create person REST API, the new create person id will be returned
                    var faces = new ObservableCollection<Face>();
                    p.Faces = faces;
                    Persons.Add(p);

                    // Enumerate images under the person folder, call detection
                    foreach (var img in System.IO.Directory.EnumerateFiles(dir, "*.jpg", System.IO.SearchOption.AllDirectories))
                    {
                        tasks.Add(Task.Factory.StartNew(
                            async (obj) =>
                            {
                                var imgPath = obj as string;

                                // Call detection REST API
                                using (var fStream = File.OpenRead(imgPath))
                                {
                                    try
                                    {
                                        var face = await App.Instance.DetectAsync(fStream);
                                    return new Tuple<string, ClientContract.Face[]>(imgPath, face);
                                    }
                                    catch (ClientException)
                                    {
                                        // Here we simply ignore all detection failure in this sample
                                        // You may handle these exceptions by check the Error.Code and Error.Message property for ClientException object
                                        return new Tuple<string, ClientContract.Face[]>(imgPath, null);
                                    }
                                }
                            },
                            img).Unwrap().ContinueWith((detectTask) =>
                            {
                                // Update detected faces for rendering
                                var detectionResult = detectTask.Result;
                                if (detectionResult == null || detectionResult.Item2 == null)
                                {
                                    return;
                                }

                                foreach (var f in detectionResult.Item2)
                                {
                                    this.Dispatcher.Invoke(
                                        new Action<ObservableCollection<Face>, string, ClientContract.Face>(UIHelper.UpdateFace),
                                        faces,
                                        detectionResult.Item1,
                                        f);
                                }
                            }));
                        if (processCount >= SuggestionCount && !forceContinue)
                        {
                            var continueProcess = System.Windows.Forms.MessageBox.Show("The images loaded have reached the recommended count, may take long time if proceed. Would you like to continue to load images?", "Warning", MessageBoxButtons.YesNo);
                            if (continueProcess == DialogResult.Yes)
                            {
                                forceContinue = true;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                    await Task.WhenAll(tasks);
                }

                Output = Output.AppendLine(string.Format("Response: Success. Total {0} faces are detected.", Persons.Sum(p => p.Faces.Count)));

                try
                {
                    // Update person faces on server side
                    foreach (var p in Persons)
                    {
                        // Call person update REST API
                        Output = Output.AppendLine(string.Format("Request: Creating person \"{0}\"", p.PersonName));
                        p.PersonId = (await App.Instance.CreatePersonAsync(GroupName, p.Faces.Select(face => Guid.Parse(face.FaceId)).ToArray(), p.PersonName)).PersonId.ToString();
                        Output = Output.AppendLine(string.Format("Response: Success. Person \"{0}\" (PersonID:{1}) created, {2} face(s) added.", p.PersonName, p.PersonId, p.Faces.Count));
                    }

                    // Start train person group
                    Output = Output.AppendLine(string.Format("Request: Training group \"{0}\"", GroupName));
                    await App.Instance.TrainPersonGroupAsync(GroupName);

                    // Wait until train completed
                    while (true)
                    {
                        await Task.Delay(1000);
                        var status = await App.Instance.GetPersonGroupTrainingStatusAsync(GroupName);
                        Output = Output.AppendLine(string.Format("Response: {0}. Group \"{1}\" training process is {2}", "Success", GroupName, status.Status));
                        if (status.Status != "running")
                        {
                            break;
                        }
                    }
                }
                catch (ClientException ex)
                {
                    Output = Output.AppendLine(string.Format("Response: {0}. {1}", ex.Error.Code, ex.Error.Message));
                }
            }
        }
Beispiel #3
0
 private void NewPersonButton_OnClick(object sender, RoutedEventArgs e)
 {
     var person = new Person();
     SelectedPerson = person;
     _isSaveNew = true;
 }
Beispiel #4
0
 private async Task UpdatePersonAsync(Person person)
 {
     await
         _client.UpdatePersonAsync(SelectedPersonGroupItem.Group.PersonGroupId, person.PersonId, person.FaceIds,
             person.Name, person.UserData);
 }
Beispiel #5
0
 private async Task<CreatePersonResult> CreatePersonAsync(Person person)
 {
     return await _client.CreatePersonAsync(SelectedPersonGroupItem.Group.PersonGroupId, person.FaceIds, person.Name, person.UserData);
 }
Beispiel #6
0
        public static BitmapSource DrawFaces(BitmapSource baseImage, Microsoft.ProjectOxford.Face.Contract.Face[] faces, Microsoft.ProjectOxford.Face.Contract.Person person)
        {
            if (faces == null)
            {
                return(baseImage);
            }

            Action <DrawingContext, double> drawAction = (drawingContext, annotationScale) =>
            {
                for (int i = 0; i < faces.Length; i++)
                {
                    var face = faces[i];
                    if (face.FaceRectangle == null)
                    {
                        continue;
                    }

                    Rect faceRect = new Rect(
                        face.FaceRectangle.Left, face.FaceRectangle.Top,
                        face.FaceRectangle.Width, face.FaceRectangle.Height);
                    string text = "";

                    if (person != null)
                    {
                        text += person.Name;
                    }

                    faceRect.Inflate(6 * annotationScale, 6 * annotationScale);

                    double lineThickness = 4 * annotationScale;

                    drawingContext.DrawRectangle(
                        Brushes.Transparent,
                        new Pen(s_lineBrush, lineThickness),
                        faceRect);

                    if (text != "")
                    {
                        FormattedText ft = new FormattedText(text,
                                                             CultureInfo.CurrentCulture, FlowDirection.LeftToRight, s_typeface,
                                                             16 * annotationScale, Brushes.Black);

                        var pad = 3 * annotationScale;

                        var ypad   = pad;
                        var xpad   = pad + 4 * annotationScale;
                        var origin = new System.Windows.Point(
                            faceRect.Left + xpad - lineThickness / 2,
                            faceRect.Top - ft.Height - ypad + lineThickness / 2);
                        var rect = ft.BuildHighlightGeometry(origin).GetRenderBounds(null);
                        rect.Inflate(xpad, ypad);

                        drawingContext.DrawRectangle(s_lineBrush, null, rect);
                        drawingContext.DrawText(ft, origin);
                    }
                }
            };

            return(DrawOverlay(baseImage, drawAction));
        }
        /// <summary>
        /// Add photos to the training group using Microsoft Face API
        /// </summary>
        /// <param name="Photos">List of photos to add</param>
        /// <param name="PersonGroupID">Name of the training group</param>
        /// <returns></returns>
        public async Task addPhotosToTrainingGroup(Dictionary<string, PhotoPerson> Photos, string PersonGroupID)
        {
            IFaceServiceClient faceClient = new FaceServiceClient(SubscriptionKey);

            // Get the group and add photos to the group.
            // The input dictionary is organized by person ID.  The output dictionary is organized by the GUID returned by the added photo from the API.
            try
            {
                await faceClient.GetPersonGroupAsync(PersonGroupID);

                // training photos can support multiple pictures per person (more pictures will make the training more effective).  
                // each photo is added as a Face object within the Face API and attached to a person.

                foreach (PhotoPerson person in Photos.Values)
                {
                    Person p = new Person();
                    p.Name = person.Name;
                    p.PersonId = Guid.NewGuid();

                    List<Guid> faceIDs = new List<Guid>();

                    
                    foreach (Photo photo in person.Photos)
                    {
                        Stream stream = new MemoryStream(photo.Image);
                        Face[] face = await faceClient.DetectAsync(stream);

                        // check for multiple faces - should only have one for a training set.
                        if (face.Length != 1)
                            throw new FaceDetectionException("Expected to detect 1 face but found " + face.Length + " faces for person " + p.Name);
                        else
                            faceIDs.Add(face[0].FaceId);
                    }

                    Guid[] faceIDarray = faceIDs.ToArray();

                    // create the person in the training group with the image array of faces.
                    CreatePersonResult result = await faceClient.CreatePersonAsync(PersonGroupID, faceIDarray, p.Name, null);
                    p.PersonId = result.PersonId;
                    TrainingPhotos.Add(p.PersonId, person);

                }

                await faceClient.TrainPersonGroupAsync(PersonGroupID);
                // Wait until train completed
                while (true)
                {
                    await Task.Delay(1000);
                    var status = await faceClient.GetPersonGroupTrainingStatusAsync(PersonGroupID);
                    if (status.Status != "running")
                    {
                        break;
                    }
                }
            }
            catch (ClientException ex)
            {
                throw;
            }



        }