/// <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;

            MainWindow mainWindow = Window.GetWindow(this) as MainWindow;
            string subscriptionKey = mainWindow._scenariosControl.SubscriptionKey;

            var faceServiceClient = new FaceServiceClient(subscriptionKey);

            // Test whether the group already exists
            try
            {
                MainWindow.Log("Request: Group {0} will be used for build person database. Checking whether group exists.", GroupName);

                await faceServiceClient.GetPersonGroupAsync(GroupName);
                groupExists = true;
                MainWindow.Log("Response: Group {0} exists.", GroupName);
            }
            catch (FaceAPIException ex)
            {
                if (ex.ErrorCode != "PersonGroupNotFound")
                {
                    MainWindow.Log("Response: {0}. {1}", ex.ErrorCode, ex.ErrorMessage);
                    return;
                }
                else
                {
                    MainWindow.Log("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 faceServiceClient.DeletePersonGroupAsync(GroupName);
                }
                else
                {
                    return;
                }
            }

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

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

            if (result == System.Windows.Forms.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
                MainWindow.Log("Request: Creating group \"{0}\"", GroupName);
                try
                {
                    await faceServiceClient.CreatePersonGroupAsync(GroupName, GroupName);
                    MainWindow.Log("Response: Success. Group \"{0}\" created", GroupName);
                }
                catch (FaceAPIException ex)
                {
                    MainWindow.Log("Response: {0}. {1}", ex.ErrorCode, ex.ErrorMessage);
                    return;
                }

                int processCount = 0;
                bool forceContinue = false;

                MainWindow.Log("Request: Preparing faces for identification, detecting faces in chosen 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;

                    var faces = new ObservableCollection<Face>();
                    p.Faces = faces;

                    // Call create person REST API, the new create person id will be returned
                    MainWindow.Log("Request: Creating person \"{0}\"", p.PersonName);
                    p.PersonId = (await faceServiceClient.CreatePersonAsync(GroupName, p.PersonName)).PersonId.ToString();
                    MainWindow.Log("Response: Success. Person \"{0}\" (PersonID:{1}) created", p.PersonName, p.PersonId);

                    // 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;

                                using (var fStream = File.OpenRead(imgPath))
                                {
                                    try
                                    {
                                        // Update person faces on server side
                                        var persistFace = await faceServiceClient.AddPersonFaceAsync(GroupName, Guid.Parse(p.PersonId), fStream, imgPath);
                                        return new Tuple<string, ClientContract.AddPersistedFaceResult>(imgPath, persistFace);
                                    }
                                    catch (FaceAPIException)
                                    {
                                        // Here we simply ignore all detection failure in this sample
                                        // You may handle these exceptions by check the Error.Error.Code and Error.Message property for ClientException object
                                        return new Tuple<string, ClientContract.AddPersistedFaceResult>(imgPath, null);
                                    }
                                }
                            },
                            img).Unwrap().ContinueWith((detectTask) =>
                            {
                                // Update detected faces for rendering
                                var detectionResult = detectTask.Result;
                                if (detectionResult == null || detectionResult.Item2 == null)
                                {
                                    return;
                                }

                                this.Dispatcher.Invoke(
                                    new Action<ObservableCollection<Face>, string, ClientContract.AddPersistedFaceResult>(UIHelper.UpdateFace),
                                    faces,
                                    detectionResult.Item1,
                                    detectionResult.Item2);
                            }));
                        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", System.Windows.Forms.MessageBoxButtons.YesNo);
                            if (continueProcess == System.Windows.Forms.DialogResult.Yes)
                            {
                                forceContinue = true;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                    Persons.Add(p);

                    await Task.WhenAll(tasks);
                }

                MainWindow.Log("Response: Success. Total {0} faces are detected.", Persons.Sum(p => p.Faces.Count));

                try
                {
                    // Start train person group
                    MainWindow.Log("Request: Training group \"{0}\"", GroupName);
                    await faceServiceClient.TrainPersonGroupAsync(GroupName);

                    // Wait until train completed
                    while (true)
                    {
                        await Task.Delay(1000);
                        var status = await faceServiceClient.GetPersonGroupTrainingStatusAsync(GroupName);
                        MainWindow.Log("Response: {0}. Group \"{1}\" training process is {2}", "Success", GroupName, status.Status);
                        if (status.Status != Contract.Status.Running)
                        {
                            break;
                        }
                    }
                }
                catch (FaceAPIException ex)
                {
                    MainWindow.Log("Response: {0}. {1}", ex.ErrorCode, ex.ErrorMessage);
                }
            }
        }
        /// <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;
            }



        }
Beispiel #3
0
        private async void faceIdentifyBtn_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                faceIdentifyBtn.IsEnabled = false;
                //capture photo than save.
                captureImage.Source = webImage.Source;
                Helper.SaveImageCapture((BitmapSource)captureImage.Source);

                string getDirectory = Directory.GetCurrentDirectory();
                string filePath     = getDirectory + "\\test1.jpg";

                System.Drawing.Image image1 = System.Drawing.Image.FromFile(filePath);

                var faceServiceClient = new FaceServiceClient(faceAPISubscriptionKey);
                try
                {
                    Title = String.Format("Request: Training group \"{0}\"", GroupName);
                    await faceServiceClient.TrainPersonGroupAsync(GroupName);

                    TrainingStatus trainingStatus = null;
                    while (true)
                    {
                        await Task.Delay(1000);

                        trainingStatus = await faceServiceClient.GetPersonGroupTrainingStatusAsync(GroupName);

                        Title = String.Format("Response: {0}. Group \"{1}\" training process is {2}", "Success", GroupName, trainingStatus.Status);
                        if (trainingStatus.Status.ToString() != "running")
                        {
                            break;
                        }
                    }
                }
                catch (FaceAPIException ex)
                {
                    Title = String.Format("Response: {0}. {1}", ex.ErrorCode, ex.ErrorMessage);
                    faceIdentifyBtn.IsEnabled = true;
                }

                Title = "Detecting....";

                using (Stream s = File.OpenRead(filePath))
                {
                    var faces = await faceServiceClient.DetectAsync(s);

                    var faceIds = faces.Select(face => face.FaceId).ToArray();

                    var             faceRects = faces.Select(face => face.FaceRectangle);
                    FaceRectangle[] faceRect  = faceRects.ToArray();
                    if (faceRect.Length == 1)
                    {
                        Title = String.Format("Detection Finished. {0} face(s) detected", faceRect.Length);
                        speechSynthesizer.SpeakAsync("We have detected.");
                        speechSynthesizer.SpeakAsync(faceRect.Length.ToString());
                        speechSynthesizer.SpeakAsync("face.");
                        speechSynthesizer.SpeakAsync("Please Wait we are identifying your face.");

                        await Task.Delay(3000);

                        Title = "Identifying.....";
                        try
                        {
                            Console.WriteLine("Group Name is : {0}, faceIds is : {1}", GroupName, faceIds);
                            var results = await faceServiceClient.IdentifyAsync(GroupName, faceIds);

                            foreach (var identifyResult in results)
                            {
                                Title = String.Format("Result of face: {0}", identifyResult.FaceId);

                                if (identifyResult.Candidates.Length == 0)
                                {
                                    Title = String.Format("No one identified");
                                    MessageBox.Show("Hi, Make sure you have registered your face. Try to register now.");
                                    speechSynthesizer.SpeakAsync("Sorry. No one identified.");
                                    speechSynthesizer.SpeakAsync("Please make sure you have previously registered your face with us.");
                                    registerBtn.IsEnabled     = true;
                                    faceIdentifyBtn.IsEnabled = false;
                                    return;
                                }
                                else
                                {
                                    // Get top 1 among all candidates returned
                                    var candidateId = identifyResult.Candidates[0].PersonId;
                                    var person      = await faceServiceClient.GetPersonAsync(GroupName, candidateId);

                                    faceIdentifiedUserName = person.Name.ToString();
                                    Title = String.Format("Identified as {0}", person.Name);
                                    speechSynthesizer.SpeakAsync("Hi.");
                                    speechSynthesizer.Speak(person.Name.ToString());
                                    speechSynthesizer.SpeakAsync("Now you need to verify your voice.");
                                    speechSynthesizer.SpeakAsync("To verify your voice. Say like that.");
                                    speechSynthesizer.SpeakAsync("My voice is stronger than my password. Verify my voice.");
                                    faceIdentifyBtn.IsEnabled = false;
                                    identifyRecord.IsEnabled  = true;
                                }
                            }
                            GC.Collect();
                        }
                        catch (FaceAPIException ex)
                        {
                            Title = String.Format("Failed...Try Again.");
                            speechSynthesizer.SpeakAsync("First register your face.");
                            Console.WriteLine("Error : {0} ", ex.Message);
                            image1.Dispose();
                            File.Delete(filePath);
                            GC.Collect();
                            registerBtn.IsEnabled = true;
                            return;
                        }
                    }
                    else if (faceRect.Length > 1)
                    {
                        Title = String.Format("More than one faces detected. Make sure only one face is in the photo. Try again..");
                        speechSynthesizer.SpeakAsync("More than one faces detected. Make sure only one face is in the photo. Try again..");
                        faceIdentifyBtn.IsEnabled = true;
                        return;
                    }
                    else
                    {
                        Title = String.Format("No one detected in the photo. Please make sure your face is infront of the webcam. Try again with the correct photo.");
                        speechSynthesizer.SpeakAsync("No one detected. Please make sure your face is infront of the webcam. Try again with the correct photo.");
                        faceIdentifyBtn.IsEnabled = true;
                        return;
                    }

                    image1.Dispose();
                    File.Delete(filePath);
                    GC.Collect();
                    await Task.Delay(2000);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error : ", ex.Message);
                faceIdentifyBtn.IsEnabled = true;
                GC.Collect();
            }
        }
Beispiel #4
0
        private async void btn_Train_Click(object sender, EventArgs e)
        {
            //Abrimos un dialogo de seleccion de carpetas
            FolderBrowserDialog dialog = new FolderBrowserDialog();

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                //Si se ha seleccionado un directorio, hacemos su info
                DirectoryInfo directory = new DirectoryInfo(dialog.SelectedPath);

                //Comprobamos que el directorio tiene carpetas de personas
                if (directory.GetDirectories().Count() == 0)
                {
                    return;
                }

                //=====Empezamos a crear el grupo de trabajo
                //Creamos el cliente
                var faceServiceClient = new FaceServiceClient(FaceAPIKey, FaceAPIEndPoint);

                //Vamos a trabajar desde 0 siempre, asi que comprobamos si hay grupos, y si los hay los borramos
                var groups = await faceServiceClient.ListPersonGroupsAsync();

                foreach (var group in groups)
                {
                    await faceServiceClient.DeletePersonGroupAsync(group.PersonGroupId);
                }
                //Creamos un grupo
                await faceServiceClient.CreatePersonGroupAsync(GroupGUID, "FixedBuffer");

                foreach (var person in directory.GetDirectories())
                {
                    //Comprobamos que tenga imagenes
                    if (person.GetFiles().Count() == 0)
                    {
                        return;
                    }

                    //Obtenemos el nombre que le vamos a dar a la persona
                    var personName = person.Name;

                    lbl_Status.Text = $"Entrenando a {personName}";

                    //Añadimos a una persona al grupo
                    var personResult = await faceServiceClient.CreatePersonAsync(GroupGUID, personName);

                    //Añadimos todas las fotos a la persona
                    foreach (var file in person.GetFiles())
                    {
                        using (var fStream = File.OpenRead(file.FullName))
                        {
                            try
                            {
                                //Cargamos la imagen en el pictureBox
                                pct_Imagen.Image = new Bitmap(fStream);
                                //Reiniciamos el Stream
                                fStream.Seek(0, SeekOrigin.Begin);
                                // Actualizamos las caras en el servidor
                                var persistFace = await faceServiceClient.AddPersonFaceInPersonGroupAsync(GroupGUID, personResult.PersonId, fStream, file.FullName);
                            }
                            catch (FaceAPIException ex)
                            {
                                lbl_Status.Text = "";
                                MessageBox.Show($"Imposible seguir, razón:{ex.ErrorMessage}");
                                return;
                            }
                        }
                    }
                }

                try
                {
                    //Entrenamos el grupo con todas las personas que hemos metido
                    await faceServiceClient.TrainPersonGroupAsync(GroupGUID);

                    // Esperamos a que el entrenamiento acabe
                    while (true)
                    {
                        await Task.Delay(1000);

                        var status = await faceServiceClient.GetPersonGroupTrainingStatusAsync(GroupGUID);

                        if (status.Status != Microsoft.ProjectOxford.Face.Contract.Status.Running)
                        {
                            break;
                        }
                    }

                    //Si hemos llegado hasta aqui, el entrenamiento se ha completado
                    btn_Find.Enabled = true;
                    lbl_Status.Text  = $"Entrenamiento completado";
                }
                catch (FaceAPIException ex)
                {
                    lbl_Status.Text = "";
                    MessageBox.Show($"Response: {ex.ErrorCode}. {ex.ErrorMessage}");
                }
                GC.Collect();
            }
        }
        private async Task <string> Train(string testImageFile, string name)
        {
            string result = "";

            try
            {
                Nullable <System.Guid> personId = null;

                var faceServiceClient = new FaceServiceClient(subscriptionKey, apiRootUrl);


                // I have already created a person group. If you haven't created please use the below code to create before get
                // await faceServiceClient.CreatePersonGroupAsync(personGroupId, "<friendly name to your group>");
                var personGroup = await faceServiceClient.GetPersonGroupAsync(personGroupId);

                var persons = await faceServiceClient.GetPersonsAsync(personGroupId);

                if (persons != null)
                {
                    foreach (var item in persons)
                    {
                        if (item.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
                        {
                            personId = item.PersonId;
                        }
                    }
                }

                if (personId == null)
                {
                    CreatePersonResult personCreate = await faceServiceClient.CreatePersonAsync(
                        // Id of the PersonGroup that the person belonged to
                        personGroupId,
                        // Name of the person
                        name
                        );

                    personId = personCreate.PersonId;
                }

                if (personId == null)
                {
                    return("personId is null");
                }

                using (Stream s = System.IO.File.OpenRead(testImageFile))
                {
                    // Detect faces in the image and add to Anna
                    await faceServiceClient.AddPersonFaceAsync(
                        personGroupId, personId.Value, s);
                }


                await faceServiceClient.TrainPersonGroupAsync(personGroupId);

                TrainingStatus trainingStatus = null;

                while (true)
                {
                    trainingStatus = await faceServiceClient.GetPersonGroupTrainingStatusAsync(personGroupId);

                    if (trainingStatus.Status != Status.Running)
                    {
                        break;
                    }

                    await Task.Delay(1000);
                }


                result = "Successfully trained";
            }
            catch (FaceAPIException e)
            {
                result = e.Message;
            }

            return(result);
        }
Beispiel #6
0
        private void CreatePersonGroup(List <Contact> lstContacts)
        {
            try
            {
                using (var faceServiceClient = new FaceServiceClient(this.strSubscriptionKey, this.strEndpoint))
                {
                    bool isGroupExists = CheckIfGroupExists();
                    if (!isGroupExists)
                    {
                        Task taskCreatePersonGroup = Task.Run(async() => await faceServiceClient.CreatePersonGroupAsync(this.PersonGroupId, "Dynamics 365 Contacts"));
                    }

                    lstContacts.ForEach(contact =>
                    {
                        Task <CreatePersonResult> taskCreatePerson = Task.Run(async() => await faceServiceClient.CreatePersonAsync(
                                                                                  // Id of the PersonGroup that the person belonged to
                                                                                  this.PersonGroupId,
                                                                                  contact.FullName, contact.Id));

                        while (!taskCreatePerson.IsCompleted)
                        {
                            taskCreatePerson.Wait();
                        }
                        CreatePersonResult person = taskCreatePerson.Result as CreatePersonResult;
                        using (Stream stream = new MemoryStream(contact.ImageBytes))
                        {
                            Task <AddPersistedFaceResult> taskPersisted = Task.Run(async() => await faceServiceClient.AddPersonFaceAsync(PersonGroupId, person.PersonId, stream));
                            while (!taskPersisted.IsCompleted)
                            {
                                taskPersisted.Wait();
                            }
                            AddPersistedFaceResult persistedFaces = taskPersisted.Result as AddPersistedFaceResult;
                            Persons.Add(new Person()
                            {
                                PersonName      = contact.FullName,
                                PersonId        = person.PersonId.ToString(),
                                PersistedFaceId = persistedFaces.PersistedFaceId.ToString()
                            });
                        }
                    });
                    Task taskTrainPerson = Task.Run(async() => await faceServiceClient.TrainPersonGroupAsync(this.PersonGroupId));
                    while (!taskTrainPerson.IsCompleted)
                    {
                        taskTrainPerson.Wait();
                    }
                    while (true)
                    {
                        try
                        {
                            Task <TrainingStatus> taskTrainingStatus = Task.Run(async() => await faceServiceClient.GetPersonGroupTrainingStatusAsync(this.PersonGroupId));
                            if (taskTrainingStatus.Result.Status != Status.Running)
                            {
                                break;
                            }
                            else
                            {
                                taskTrainingStatus.Wait();
                            }
                        }
                        catch (FaceAPIException fEx)
                        {
                            continue;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }