예제 #1
0
        private async Task <SimilarFaceMatch> GetSimilarFace(Face detectedFace)
        {
            SimilarFaceMatch result = new SimilarFaceMatch();

            try
            {
                Tuple <SimilarPersistedFace, string> similarPersistedFace = await FaceListManager.FindSimilarPersistedFaceAsync(await this.GetImageStreamCallback(), detectedFace.FaceId, detectedFace.FaceRectangle);

                if (similarPersistedFace != null)
                {
                    bool isNew = (similarPersistedFace.Item2 == null);
                    result = new SimilarFaceMatch()
                    {
                        Face = detectedFace, SimilarPersistedFace = similarPersistedFace.Item1, isNew = isNew
                    };
                }
            }
            catch (Exception e)
            {
                ErrorTrackingHelper.TrackException(e, "FaceListManager.FindSimilarPersistedFaceAsync error");

                if (this.ShowDialogOnFaceApiErrors)
                {
                    await ErrorTrackingHelper.GenericApiCallExceptionHandler(e, "Failure finding similar faces");
                }
            }

            return(result);
        }
예제 #2
0
        private async Task CreatePrsonIfNoSimilarFaceExistsAsync(List <FaceSendInfo> facesInfo, Guid newPersonID, Face f)
        {
            //TODO return person result so we can change candidate if we are not going with the one selected

            //We try to find person also thru similar face api
            SimilarFaceMatch result = await GetSimilarFace(f);

            using (var db = new KioskDBContext())
            {
                //If we create new similar face, we create also new person
                if (result.isNew)
                {
                    //We create db where we map SimilarPersonID to PersonID, because those are different in cognitive services
                    var perResult = await CreatePerson(facesInfo, newPersonID, f);

                    db.SimilarFaces.Add(new DBSimilarFace()
                    {
                        CreatedAt = DateTime.Now, FaceId = result.SimilarPersistedFace.PersistedFaceId.ToString(), PersonId = perResult.ToString()
                    });
                    await db.SaveChangesAsync();
                }

                else
                {
                    string personId = "";
                    try
                    {
                        personId = db.SimilarFaces.Where(sf => sf.FaceId == result.SimilarPersistedFace.PersistedFaceId.ToString()).FirstOrDefault().PersonId;

                        var person = await FaceServiceHelper.GetPersonAsync(groupId, new Guid(personId));

                        //Fill new info
                        var fi = facesInfo.Where(fin => fin.faceId == f.FaceId.ToString()).FirstOrDefault();
                        fi.canid   = personId;
                        fi.canname = person.Name;
                        fi.canconf = result.SimilarPersistedFace.Confidence;

                        //We did not identified person thru person group and we needed to use silimar face api, so we add picture
                        await AddFaceToPerson(f, person, new Guid(personId));
                    }
                    catch (Exception)
                    {
                        //Person was not found due to old entry in local DB (Exception thrown by FaceApi GetPersonAsync) or face was created only in list when not using complex identification

                        //If person is only in list,  we need to create it also in person list
                        if (personId == "")
                        {
                            var perResult2 = await CreatePerson(facesInfo, newPersonID, f);

                            db.SimilarFaces.Add(new DBSimilarFace()
                            {
                                CreatedAt = DateTime.Now, FaceId = result.SimilarPersistedFace.PersistedFaceId.ToString(), PersonId = perResult2.ToString()
                            });
                            await db.SaveChangesAsync();
                        }

                        //We clean the old entry from DB and create new Person
                        var oldDbEntry = db.SimilarFaces.Where(sf => sf.FaceId == result.SimilarPersistedFace.PersistedFaceId.ToString()).FirstOrDefault();
                        var perResult  = await CreatePerson(facesInfo, newPersonID, f);

                        if (oldDbEntry != null)
                        {
                            db.SimilarFaces.Update(oldDbEntry);
                            oldDbEntry.FaceId   = result.SimilarPersistedFace.PersistedFaceId.ToString();
                            oldDbEntry.PersonId = perResult.ToString();
                        }
                        else
                        {
                            db.SimilarFaces.Add(new DBSimilarFace()
                            {
                                CreatedAt = DateTime.Now, FaceId = result.SimilarPersistedFace.PersistedFaceId.ToString(), PersonId = perResult.ToString()
                            });
                        }

                        await db.SaveChangesAsync();
                    }
                }
            }
        }
        public async Task <List <FaceSendInfo> > IdentifyOrAddPersonWithEmotionsAsync(string groupName, double confidence)
        {
            var time = DateTime.Now;
            //We also add emotions
            var facesInfo = new List <FaceSendInfo>();

            foreach (var f in this.DetectedFaces)
            {
                var fsi = new FaceSendInfo();
                var e   = CoreUtil.FindEmotionForFace(f, this.DetectedEmotion);

                fsi.faceId = f.FaceId.ToString();
                fsi.age    = f.FaceAttributes.Age;

                fsi.faceRecHeight = f.FaceRectangle.Height;
                fsi.faceRecLeft   = f.FaceRectangle.Left;
                fsi.faceRecTop    = f.FaceRectangle.Top;
                fsi.faceRecWidth  = f.FaceRectangle.Width;

                fsi.gender = f.FaceAttributes.Gender;

                fsi.smile = f.FaceAttributes.Smile;

                fsi.beard     = f.FaceAttributes.FacialHair.Beard;
                fsi.moustache = f.FaceAttributes.FacialHair.Moustache;
                fsi.sideburns = f.FaceAttributes.FacialHair.Sideburns;

                fsi.glasses = f.FaceAttributes.Glasses.ToString();

                fsi.headYaw   = f.FaceAttributes.HeadPose.Yaw;
                fsi.headRoll  = f.FaceAttributes.HeadPose.Roll;
                fsi.headPitch = f.FaceAttributes.HeadPose.Pitch;

                fsi.anger     = e.Scores.Anger;
                fsi.contempt  = e.Scores.Contempt;
                fsi.disgust   = e.Scores.Disgust;
                fsi.fear      = e.Scores.Fear;
                fsi.happiness = e.Scores.Happiness;
                fsi.neutral   = e.Scores.Neutral;
                fsi.sadness   = e.Scores.Sadness;
                fsi.surprise  = e.Scores.Surprise;

                fsi.timeStamp = time;
                fsi.facesNo   = this.DetectedFaces.Count();

                facesInfo.Add(fsi);
            }
            var newPersonID = Guid.NewGuid();

            //Move to initialization
            try
            {
                var g = await FaceServiceHelper.CreatePersonGroupIfNoGroupExists(groupName);

                groupId = g.PersonGroupId;
            }
            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, "Problem creating group");

                if (this.ShowDialogOnFaceApiErrors)
                {
                    await ErrorTrackingHelper.GenericApiCallExceptionHandler(e, "Problem creating group");
                }
            }


            List <IdentifiedPerson> ipresult = new List <IdentifiedPerson>();

            // Compute Face Identification and Unique Face Ids
            //We need to map detected faceID with actual personID (Identified face)
            try
            {
                IdentifyResult[] groupResults = await this.IdentifyFacesAsync(groupId);

                foreach (var f in this.DetectedFaces)
                {
                    if (groupResults != null && groupResults.Where(gr => gr.FaceId == f.FaceId).Any() && groupResults.Where(gr => gr.FaceId == f.FaceId).FirstOrDefault().Candidates.Any())
                    {
                        var candidates = groupResults.Where(gr => gr.FaceId == f.FaceId).FirstOrDefault().Candidates.OrderByDescending(ca => ca.Confidence);

                        var    fi = facesInfo.Where(fin => fin.faceId == f.FaceId.ToString()).FirstOrDefault();
                        int    i  = 0;
                        Person p  = new Person();
                        foreach (var can in candidates)
                        {
                            switch (i)
                            {
                            case 0:
                                fi.can1id   = can.PersonId.ToString();
                                fi.can1conf = can.Confidence;
                                p           = await FaceServiceHelper.GetPersonAsync(groupId, can.PersonId);

                                fi.can1name = p.Name;
                                if (can.Confidence >= confidence)
                                {
                                    ipresult.Add(new IdentifiedPerson()
                                    {
                                        Person = p, Confidence = can.Confidence, FaceId = f.FaceId
                                    });
                                    if (p.PersistedFaceIds.Length == 248)
                                    {
                                        Guid persistedFaceId = p.PersistedFaceIds.OrderBy(x => Guid.NewGuid()).FirstOrDefault();
                                        await FaceServiceHelper.DeletePersonFaceAsync(groupId, can.PersonId, persistedFaceId);
                                    }
                                    try
                                    {
                                        await FaceServiceHelper.AddPersonFaceAsync(groupId, can.PersonId, await this.GetImageStreamCallback(), "", f.FaceRectangle);
                                    }
                                    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, "Problem adding face to group");

                                        if (this.ShowDialogOnFaceApiErrors)
                                        {
                                            await ErrorTrackingHelper.GenericApiCallExceptionHandler(e, "Problem adding face to group");
                                        }
                                    }
                                }
                                else
                                {
                                    //create new Guy if confidence not sufficient
                                    SimilarFaceMatch result = await GetSimilarFace(f);

                                    //using (var db = new KioskDbContext())
                                    //{
                                    //    Blogs.ItemsSource = db.Blogs.ToList();
                                    //}

                                    await CreatePerson(facesInfo, newPersonID, f);
                                }
                                break;

                            case 1:
                                fi.can2id   = can.PersonId.ToString();
                                fi.can2conf = can.Confidence;
                                p           = await FaceServiceHelper.GetPersonAsync(groupId, can.PersonId);

                                fi.can2name = p.Name;
                                break;

                            case 2:
                                fi.can3id   = can.PersonId.ToString();
                                fi.can3conf = can.Confidence;
                                p           = await FaceServiceHelper.GetPersonAsync(groupId, can.PersonId);

                                fi.can3name = p.Name;
                                break;

                            case 3:
                                fi.can4id   = can.PersonId.ToString();
                                fi.can4conf = can.Confidence;
                                p           = await FaceServiceHelper.GetPersonAsync(groupId, can.PersonId);

                                fi.can4name = p.Name;
                                break;
                            }
                            i++;
                        }
                    }

                    else
                    {
                        //if no candidate we also need to create new person
                        await CreatePerson(facesInfo, newPersonID, f);
                    }
                    try
                    {
                        await FaceServiceHelper.TrainPersonGroupAsync(groupId);
                    }
                    catch (Exception e)
                    {
                        // Catch error with training of group
                        ErrorTrackingHelper.TrackException(e, "Problem training group");

                        if (this.ShowDialogOnFaceApiErrors)
                        {
                            await ErrorTrackingHelper.GenericApiCallExceptionHandler(e, "Problem training group");
                        }
                    }
                }
            }
            catch (Exception e)
            {
                // Catch error with training of group
                ErrorTrackingHelper.TrackException(e, "Problem with cognitive services");

                if (this.ShowDialogOnFaceApiErrors)
                {
                    await ErrorTrackingHelper.GenericApiCallExceptionHandler(e, "Problem with cognitive services");
                }
            }
            return(facesInfo);
        }