public static async Task UpdatePersonGroupsWithNewRecModelAsync()

in Kiosk/ServiceHelpers/FaceServiceHelper.cs [333:417]


        public static async Task UpdatePersonGroupsWithNewRecModelAsync(PersonGroup oldPersonGroup, string userDataFilder, IProgress<FaceIdentificationModelUpdateStatus> progress = null)
        {
            try
            {

                bool allPeopleHaveAtLeastOneFaceMigrated = true;

                // just make sure the person group use previous recognition model
                bool isOldPersonGroup = oldPersonGroup?.RecognitionModel != null && !oldPersonGroup.RecognitionModel.Equals(LatestRecognitionModelName, StringComparison.OrdinalIgnoreCase);

                // get persons
                IList<Person> personsInGroup = isOldPersonGroup ? await GetPersonsAsync(oldPersonGroup.PersonGroupId) : new List<Person>();
                if (personsInGroup.Any())
                {
                    // create new person group
                    string newPersonGroupId = Guid.NewGuid().ToString();
                    await CreatePersonGroupAsync(newPersonGroupId, oldPersonGroup.Name, userDataFilder);

                    // create new persons
                    var newPersonList = new List<Tuple<Person, Person>>();
                    foreach (Person oldPerson in personsInGroup)
                    {
                        Person newPerson = await CreatePersonAsync(newPersonGroupId, oldPerson.Name);
                        newPersonList.Add(new Tuple<Person, Person>(oldPerson, newPerson));
                    }

                    // add face images
                    foreach (var (personItem, index) in newPersonList.Select((v, i) => (v, i)))
                    {
                        Person oldPerson = personItem.Item1;
                        Person newPerson = personItem.Item2;

                        // get face images from the old model
                        var personFaces = new List<PersistedFace>();
                        foreach (Guid face in oldPerson.PersistedFaceIds)
                        {
                            PersistedFace personFace = await GetPersonFaceAsync(oldPersonGroup.PersonGroupId, oldPerson.PersonId, face);
                            personFaces.Add(personFace);
                        }

                        bool addedAtLeastOneFaceImageForPerson = false;
                        // add face images to the new model
                        foreach (PersistedFace persistedFace in personFaces)
                        {
                            try
                            {
                                bool isUri = !string.IsNullOrEmpty(persistedFace.UserData) ? Uri.IsWellFormedUriString(persistedFace.UserData, UriKind.Absolute) : false;
                                if (isUri)
                                {
                                    await AddPersonFaceFromUrlAsync(newPersonGroupId, newPerson.PersonId, imageUrl: persistedFace.UserData, userData: persistedFace.UserData, targetFaceRect: null);
                                }
                                else
                                {
                                    StorageFile localImage = await StorageFile.GetFileFromPathAsync(persistedFace.UserData);
                                    await AddPersonFaceFromStreamAsync(newPersonGroupId, newPerson.PersonId, imageStreamCallback: localImage.OpenStreamForReadAsync, userData: localImage.Path, targetFaceRect: null);
                                }

                                addedAtLeastOneFaceImageForPerson = true;
                            }
                            catch { /* Ignore the error and continue. Other images might work */ }
                        }

                        if (!addedAtLeastOneFaceImageForPerson)
                        {
                            allPeopleHaveAtLeastOneFaceMigrated = false;
                        }

                        progress?.Report(new FaceIdentificationModelUpdateStatus { State = FaceIdentificationModelUpdateState.Running, Count = index + 1, Total = personsInGroup.Count });
                    }

                    // delete old person group
                    await DeletePersonGroupAsync(oldPersonGroup.PersonGroupId);

                    // train new person group
                    await TrainPersonGroupAsync(newPersonGroupId);
                }

                progress?.Report(new FaceIdentificationModelUpdateStatus { State = allPeopleHaveAtLeastOneFaceMigrated ? FaceIdentificationModelUpdateState.Complete : FaceIdentificationModelUpdateState.CompletedWithSomeEmptyPeople });
            }
            catch (Exception ex)
            {
                ErrorTrackingHelper.TrackException(ex, "Face API: Update PersonGroup using new recognition model error");
                progress?.Report(new FaceIdentificationModelUpdateStatus { State = FaceIdentificationModelUpdateState.Error });
            }
        }