コード例 #1
0
        private void _updateFacesList(JArray ja)
        {
            ObservableCollection <Face> newColl = new ObservableCollection <Face>();

            // Main face computation
            int   mainFaceID  = -1;
            float maxHeadSize = -1;

            // Copy new faces in existing list
            if (ja != null)
            {
                foreach (var v in ja)
                {
                    // Parse basic info
                    int    id     = int.Parse(v["id"].ToString());
                    string gender = v["gender"].ToString();

                    string age        = v["age"].ToString();
                    var    ageInteger = Int16.Parse(age);
                    string ageRange   = ageInteger <= 16 ? "child" :
                                        ageInteger <= 30 ? "young adult" :
                                        ageInteger <= 45 ? "middle-aged adult" : "old-aged adult";

                    var x = float.Parse(v["location"]["x"].ToString(), CultureInfo.InvariantCulture); // TODO: normalize? (or on C++ side?)
                    var y = float.Parse(v["location"]["y"].ToString(), CultureInfo.InvariantCulture);

                    var width  = float.Parse(v["location"]["width"].ToString(), CultureInfo.InvariantCulture);
                    var height = float.Parse(v["location"]["height"].ToString(), CultureInfo.InvariantCulture);

                    // Intuiface coordinates system: move X&Y coords to represent the center of the head, not the top left corner
                    x += width / 2;
                    y += height / 2;

                    // TODO: estimate distance in cm based on head size and camera focal / calibration step ??
                    var faceSize = (int)(width * height * 100 * 100); // Current value: % of head area over total image area

                    var mainEmotion           = v["mainEmotion"]["emotion"].ToString();
                    var mainEmotionConfidence = float.Parse(v["mainEmotion"]["confidence"].ToString(), CultureInfo.InvariantCulture);

                    // Parse additional emotions
                    EmotionConfidence emotionConfidence = new EmotionConfidence();
                    emotionConfidence.Angry     = float.Parse(v["emotions"]["anger"].ToString(), CultureInfo.InvariantCulture);
                    emotionConfidence.Happy     = float.Parse(v["emotions"]["happy"].ToString(), CultureInfo.InvariantCulture);
                    emotionConfidence.Neutral   = float.Parse(v["emotions"]["neutral"].ToString(), CultureInfo.InvariantCulture);
                    emotionConfidence.Sad       = float.Parse(v["emotions"]["sad"].ToString(), CultureInfo.InvariantCulture);
                    emotionConfidence.Surprised = float.Parse(v["emotions"]["surprise"].ToString(), CultureInfo.InvariantCulture);

                    // Parse head pose estimation
                    HeadPoseEstimation headPoseEstimation = new HeadPoseEstimation();
                    headPoseEstimation.Pitch = float.Parse(v["headpose"]["pitch"].ToString(), CultureInfo.InvariantCulture);
                    headPoseEstimation.Yaw   = float.Parse(v["headpose"]["yaw"].ToString(), CultureInfo.InvariantCulture);
                    headPoseEstimation.Roll  = float.Parse(v["headpose"]["roll"].ToString(), CultureInfo.InvariantCulture);

                    // If face size filtering is active, check is head is bigger than threshold
                    if (faceSize < m_dMinimumFaceSize)
                    {
                        // Don't add face to list
                        continue;
                    }

                    // TODO: use real "distance" and take the min one.
                    if (faceSize > maxHeadSize)
                    {
                        maxHeadSize = faceSize;
                        mainFaceID  = id;
                    }

                    newColl.Add(new Face()
                    {
                        Id                    = id,
                        X                     = x,
                        Y                     = y,
                        Width                 = width,
                        Height                = height,
                        FaceSize              = faceSize,
                        Gender                = gender,
                        Age                   = age,
                        AgeRange              = ageRange,
                        MainEmotion           = mainEmotion,
                        MainEmotionConfidence = mainEmotionConfidence,
                        EmotionConfidence     = emotionConfidence,
                        HeadPoseEstimation    = headPoseEstimation
                    });
                }
            }

            // Order by ID
            newColl = new ObservableCollection <Face>(newColl.OrderBy(i => i.Id));

            // Compare old (current) list and new list

            var removed = Faces.Except(newColl);
            var added   = newColl.Except(Faces);

            if (removed.Count() > 0)
            {
                foreach (var face in removed)
                {
                    // Raise face lost event
                    Console.WriteLine("Face lost: " + face);
                    RaiseFaceLost(face.Id, face.Gender, face.Age, face.DwellTime);
                    m_startTimeMap.Remove(face.Id);
                }
            }
            if (added.Count() > 0)
            {
                foreach (var face in added)
                {
                    // Raise face added event
                    Console.WriteLine("Face added: " + face);
                    RaiseFaceDetected(face.Id, face.Gender, face.Age);
                    m_startTimeMap.Add(face.Id, DateTime.Now);
                }
            }

            // Update elements in current list with new list

            int newCount = newColl.Count;
            int oldCount = Faces.Count;

            if (newCount != oldCount)
            {
                // Raise face count changed event
                Console.WriteLine("Face count changed: " + newCount);
                RaiseFaceCountChanged(newCount);
            }

            // Adjust number of faces in Faces
            // New users to add
            if (newCount > oldCount)
            {
                for (int i = 0; i < newCount - oldCount; i++)
                {
                    Faces.Add(new Face());
                }
            }
            // Users to remove
            else if (newCount < oldCount)
            {
                for (int i = newCount; i < oldCount; i++)
                {
                    Faces.RemoveAt(newCount);
                }
            }

            // Copy new coll properties in existing faces list.
            int index = 0;

            foreach (var item in newColl)
            {
                try
                {
                    Faces[index].Id        = item.Id;
                    Faces[index].X         = item.X;
                    Faces[index].Y         = item.Y;
                    Faces[index].Width     = item.Width;
                    Faces[index].Height    = item.Height;
                    Faces[index].Gender    = item.Gender;
                    Faces[index].Age       = item.Age;
                    Faces[index].AgeRange  = item.AgeRange;
                    Faces[index].DwellTime = (DateTime.Now - m_startTimeMap[item.Id]).TotalSeconds;

                    Faces[index].FaceSize = item.FaceSize;

                    Faces[index].MainEmotion           = item.MainEmotion;
                    Faces[index].MainEmotionConfidence = item.MainEmotionConfidence;

                    // Additional emotions
                    Faces[index].EmotionConfidence = item.EmotionConfidence;

                    // Head pose estimation
                    Faces[index].HeadPoseEstimation = item.HeadPoseEstimation;
                }
                catch (Exception ex)
                {
                    ActivityLog += ex.Message + "\n";

                    throw;
                }

                index++;
            }

            // Update face count
            FaceCount = Faces.Count();

            // Copy main face info
            if (FaceCount > 0)
            {
                var item = Faces.FirstOrDefault(i => i.Id == mainFaceID);
                if (item != null)
                {
                    MainFace.Id       = item.Id;
                    MainFace.X        = item.X;
                    MainFace.Y        = item.Y;
                    MainFace.Width    = item.Width;
                    MainFace.Height   = item.Height;
                    MainFace.FaceSize = item.FaceSize;
                    MainFace.Gender   = item.Gender;

                    MainFace.Age       = item.Age;
                    MainFace.AgeRange  = item.AgeRange;
                    MainFace.DwellTime = (DateTime.Now - m_startTimeMap[item.Id]).TotalSeconds;

                    MainFace.MainEmotion           = item.MainEmotion;
                    MainFace.MainEmotionConfidence = item.MainEmotionConfidence;

                    // Additional emotions
                    MainFace.EmotionConfidence = item.EmotionConfidence;

                    // Head pose estimation
                    MainFace.HeadPoseEstimation = item.HeadPoseEstimation;

                    // Mark the face detected
                    IsMainFaceDetected = true;
                }
                else
                {
                    IsMainFaceDetected = false;
                }
            }
            else
            {
                IsMainFaceDetected = false;
            }
        }