private async Task ProcessPeopleInsightsAsync(ImageAnalyzer analyzer, int frameNumber) { foreach (var item in analyzer.SimilarFaceMatches) { bool demographicsChanged = false; Visitor personInVideo; if (this.peopleInVideo.TryGetValue(item.SimilarPersistedFace.PersistedFaceId, out personInVideo)) { personInVideo.Count++; if (this.pendingIdentificationAttemptCount.ContainsKey(item.SimilarPersistedFace.PersistedFaceId)) { // This is a face we haven't identified yet. See how many times we have tried it, if we need to do it again or stop trying if (this.pendingIdentificationAttemptCount[item.SimilarPersistedFace.PersistedFaceId] <= 5) { string personName = GetDisplayTextForPersonAsync(analyzer, item); if (string.IsNullOrEmpty(personName)) { // Increment the times we have tried and failed to identify this person this.pendingIdentificationAttemptCount[item.SimilarPersistedFace.PersistedFaceId]++; } else { // Bingo! Let's remove it from the list of pending identifications this.pendingIdentificationAttemptCount.Remove(item.SimilarPersistedFace.PersistedFaceId); VideoTrack existingTrack = (VideoTrack)this.peopleListView.Children.FirstOrDefault(f => (Guid)((FrameworkElement)f).Tag == item.SimilarPersistedFace.PersistedFaceId); if (existingTrack != null) { existingTrack.DisplayText = string.Format("{0}, {1}", personName, Math.Floor(item.Face.FaceAttributes.Age)); } } } else { // Give up this.pendingIdentificationAttemptCount.Remove(item.SimilarPersistedFace.PersistedFaceId); } } } else { // New person... let's catalog it. // Crop the face, enlarging the rectangle so we frame it better double heightScaleFactor = 1.8; double widthScaleFactor = 1.8; Rectangle biggerRectangle = new Rectangle { Height = Math.Min((int)(item.Face.FaceRectangle.Height * heightScaleFactor), FrameRelayVideoEffect.LatestSoftwareBitmap.PixelHeight), Width = Math.Min((int)(item.Face.FaceRectangle.Width * widthScaleFactor), FrameRelayVideoEffect.LatestSoftwareBitmap.PixelWidth) }; biggerRectangle.Left = Math.Max(0, item.Face.FaceRectangle.Left - (int)(item.Face.FaceRectangle.Width * ((widthScaleFactor - 1) / 2))); biggerRectangle.Top = Math.Max(0, item.Face.FaceRectangle.Top - (int)(item.Face.FaceRectangle.Height * ((heightScaleFactor - 1) / 1.4))); var croppedImage = await Util.GetCroppedBitmapAsync(analyzer.GetImageStreamCallback, biggerRectangle); if (croppedImage == null || biggerRectangle.Height == 0 && biggerRectangle.Width == 0) { // Couldn't get a shot of this person continue; } demographicsChanged = true; string personName = GetDisplayTextForPersonAsync(analyzer, item); if (string.IsNullOrEmpty(personName)) { personName = item.Face.FaceAttributes.Gender; // Add the person to the list of pending identifications so we can try again on some future frames this.pendingIdentificationAttemptCount.Add(item.SimilarPersistedFace.PersistedFaceId, 1); } personInVideo = new Visitor { UniqueId = item.SimilarPersistedFace.PersistedFaceId }; this.peopleInVideo.Add(item.SimilarPersistedFace.PersistedFaceId, personInVideo); this.demographics.Visitors.Add(personInVideo); // Update the demographics stats. this.UpdateDemographics(item); VideoTrack videoTrack = new VideoTrack { Tag = item.SimilarPersistedFace.PersistedFaceId, CroppedFace = croppedImage, DisplayText = string.Format("{0}, {1}", personName, Math.Floor(item.Face.FaceAttributes.Age)), Duration = (int)this.videoPlayer.NaturalDuration.TimeSpan.TotalSeconds, }; videoTrack.Tapped += this.TimelineTapped; this.peopleListView.Children.Insert(0, videoTrack); } // Update the timeline for this person VideoTrack track = (VideoTrack)this.peopleListView.Children.FirstOrDefault(f => (Guid)((FrameworkElement)f).Tag == item.SimilarPersistedFace.PersistedFaceId); if (track != null) { Emotion matchingEmotion = CoreUtil.FindFaceClosestToRegion(analyzer.DetectedEmotion, item.Face.FaceRectangle); if (matchingEmotion == null) { matchingEmotion = new Emotion { Scores = new EmotionScores { Neutral = 1 } }; } track.SetVideoFrameState(frameNumber, matchingEmotion.Scores); uint childIndex = (uint)this.peopleListView.Children.IndexOf(track); if (childIndex > 5) { // Bring to towards the top so it becomes visible this.peopleListView.Children.Move(childIndex, 5); } } if (demographicsChanged) { this.ageGenderDistributionControl.UpdateData(this.demographics); } this.overallStatsControl.UpdateData(this.demographics); } }
private void UpdateDemographics(ImageAnalyzer img) { if (this.lastSimilarPersistedFaceSample != null) { bool demographicsChanged = false; // Update the Visitor collection (either add new entry or update existing) foreach (var item in this.lastSimilarPersistedFaceSample) { Visitor visitor; if (this.visitors.TryGetValue(item.SimilarPersistedFace.PersistedFaceId, out visitor)) { visitor.Count++; } else { demographicsChanged = true; visitor = new Visitor { UniqueId = item.SimilarPersistedFace.PersistedFaceId, Count = 1 }; this.visitors.Add(visitor.UniqueId, visitor); this.demographics.Visitors.Add(visitor); // Update the demographics stats. We only do it for new visitors to avoid double counting. AgeDistribution genderBasedAgeDistribution = null; if (string.Compare(item.Face.FaceAttributes.Gender, "male", StringComparison.OrdinalIgnoreCase) == 0) { this.demographics.OverallMaleCount++; genderBasedAgeDistribution = this.demographics.AgeGenderDistribution.MaleDistribution; } else { this.demographics.OverallFemaleCount++; genderBasedAgeDistribution = this.demographics.AgeGenderDistribution.FemaleDistribution; } if (item.Face.FaceAttributes.Age < 16) { genderBasedAgeDistribution.Age0To15++; } else if (item.Face.FaceAttributes.Age < 20) { genderBasedAgeDistribution.Age16To19++; } else if (item.Face.FaceAttributes.Age < 30) { genderBasedAgeDistribution.Age20s++; } else if (item.Face.FaceAttributes.Age < 40) { genderBasedAgeDistribution.Age30s++; } else if (item.Face.FaceAttributes.Age < 50) { genderBasedAgeDistribution.Age40s++; } else { genderBasedAgeDistribution.Age50sAndOlder++; } } } if (demographicsChanged) { //this.ageGenderDistributionControl.UpdateData(this.demographics); } //this.overallStatsControl.UpdateData(this.demographics); } }
private async void UpdateDemographics(ImageAnalyzer img) { if (this.lastSimilarPersistedFaceSample != null) { bool demographicsChanged = false; // Update the Visitor collection (either add new entry or update existing) foreach (var item in this.lastSimilarPersistedFaceSample) { Visitor visitor; String unique = "1"; if (this.visitors.TryGetValue(item.SimilarPersistedFace.PersistedFaceId, out visitor)) { visitor.Count++; unique = "0"; } else { demographicsChanged = true; visitor = new Visitor { UniqueId = item.SimilarPersistedFace.PersistedFaceId, Count = 1 }; this.visitors.Add(visitor.UniqueId, visitor); this.demographics.Visitors.Add(visitor); // Update the demographics stats. We only do it for new visitors to avoid double counting. AgeDistribution genderBasedAgeDistribution = null; if (string.Compare(item.Face.FaceAttributes.Gender, "male", StringComparison.OrdinalIgnoreCase) == 0) { this.demographics.OverallMaleCount++; genderBasedAgeDistribution = this.demographics.AgeGenderDistribution.MaleDistribution; } else { this.demographics.OverallFemaleCount++; genderBasedAgeDistribution = this.demographics.AgeGenderDistribution.FemaleDistribution; } if (item.Face.FaceAttributes.Age < 16) { genderBasedAgeDistribution.Age0To15++; } else if (item.Face.FaceAttributes.Age < 20) { genderBasedAgeDistribution.Age16To19++; } else if (item.Face.FaceAttributes.Age < 30) { genderBasedAgeDistribution.Age20s++; } else if (item.Face.FaceAttributes.Age < 40) { genderBasedAgeDistribution.Age30s++; } else if (item.Face.FaceAttributes.Age < 50) { genderBasedAgeDistribution.Age40s++; } else { genderBasedAgeDistribution.Age50sAndOlder++; } } if (lastDetectedFaceSample != null) { Random rand = new Random(); Dictionary <String, String> dictionary = new Dictionary <String, String>(); dictionary["id"] = item.SimilarPersistedFace.PersistedFaceId.ToString(); dictionary["gender"] = item.Face.FaceAttributes.Gender.ToString(); dictionary["age"] = item.Face.FaceAttributes.Age.ToString(); dictionary["date"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm"); dictionary["smile"] = item.Face.FaceAttributes.Smile.ToString(); dictionary["glasses"] = item.Face.FaceAttributes.Glasses.ToString(); dictionary["avgs"] = rand.Next(5, 8).ToString(); dictionary["avgrank"] = (3 + rand.NextDouble() * 1.5).ToString(); EmotionScores averageScores = new EmotionScores { Happiness = img.DetectedFaces.Average(f => f.FaceAttributes.Emotion.Happiness), Anger = img.DetectedFaces.Average(f => f.FaceAttributes.Emotion.Anger), Sadness = img.DetectedFaces.Average(f => f.FaceAttributes.Emotion.Sadness), Contempt = img.DetectedFaces.Average(f => f.FaceAttributes.Emotion.Contempt), Disgust = img.DetectedFaces.Average(f => f.FaceAttributes.Emotion.Disgust), Neutral = img.DetectedFaces.Average(f => f.FaceAttributes.Emotion.Neutral), Fear = img.DetectedFaces.Average(f => f.FaceAttributes.Emotion.Fear), Surprise = img.DetectedFaces.Average(f => f.FaceAttributes.Emotion.Surprise) }; dictionary["isunique"] = unique; dictionary["anger"] = averageScores.Anger.ToString(); dictionary["contempt"] = averageScores.Contempt.ToString(); dictionary["disgust"] = averageScores.Disgust.ToString(); dictionary["fear"] = averageScores.Fear.ToString(); dictionary["happiness"] = averageScores.Happiness.ToString(); dictionary["neutral"] = averageScores.Neutral.ToString(); dictionary["sadness"] = averageScores.Sadness.ToString(); dictionary["surprise"] = averageScores.Surprise.ToString(); //#pragma warning restore 4014 System.Diagnostics.Debug.WriteLine("here!!!!!!!!"); var name = "null"; var person = ""; System.Diagnostics.Debug.WriteLine("Identify? : " + lastIdentifiedPersonSample == null); if (null != lastIdentifiedPersonSample && null != lastIdentifiedPersonSample.First().Item2) { name = lastIdentifiedPersonSample.First().Item2.Person.Name.ToString(); person = lastIdentifiedPersonSample.First().Item2.Person.PersonId.ToString(); } System.Diagnostics.Debug.WriteLine("Name: " + name); System.Diagnostics.Debug.WriteLine("ID: " + person); foreach (KeyValuePair <string, string> entry in dictionary) { System.Diagnostics.Debug.WriteLine(entry.Key.ToString() + ": " + entry.Value.ToString()); // do something with entry.Value or entry.Key } dictionary["personid"] = person; dictionary["personname"] = name; ////#pragma warning disable 4014 String str = SettingsHelper.Instance.IoTHubConnectString; await IoTClient.Start(dictionary, SettingsHelper.Instance.IoTHubConnectString); } } if (demographicsChanged) { this.ageGenderDistributionControl.UpdateData(this.demographics); } this.overallStatsControl.UpdateData(this.demographics); } }