Search code examples
c#wpfaffdex-sdk

Why does the OnImageResults listener keep appending faces to the collection when a face is lost instead of reinserting at the beginning?


I'm currently developing a desktop software solution that uses real-time communication to transfer data from a client to a server using sockets in C# WPF . The client and the server are defined in the same application but the role is decided based on the user type (student is client and teacher acts as a server)

I'm using the Affdex 3.0 SDK to capture the facial expressions data of the students and then send it to the server.

My issue is that the first time the CameraDetector is started and the first face tracked, everything works fine, but as soon as the face is lost and then re-enters the image to be tracked again, the newly detected face is appended to the collection instead of being re-inserted at the beginning and triggers a key not found exception. I've thought about looping through the collection until it finds a face valid face but it's not an ideal solution.

public void onImageResults(Dictionary<int, Affdex.Face> faces, Affdex.Frame image)
    {
        Affdex.Face face;
        if (faces.Count() >= 1)
        {
            try
            {
                face = faces[0];
                UpdateExpressionsDials(face);
            }
            catch(Exception e)
            {
                Console.WriteLine("face failed " + e.Message.ToString());
            }
        }
    }

This fails with a face failed The given key was not present in the dictionary. A first chance exception of type 'System.Collections.Generic.KeyNotFoundException' occurred in mscorlib.dll.

Is there a better way of doing this? Would it be wise to create a wrapper around the Listener and make sure that if there is a face, it's always at the beginning?

This is my first question so please do let me know if I've omitted anything from the question. Thanks


Solution

  • The onImageResults call returns a Dictionary<int, Affdex.Face> faces which is a dictionary of a key=an int representing the face id and a value=Affdex.Face.

    Your code assumes that the face id is going to be always 0, which is incorrect.

    That statement

    face = faces[0]
    

    creates an empty node in the Dictionary with key=0

    Instead you should be iterating over the Dictionary items

    foreach (KeyValuePair<int, Affdex.Face> pair in Faces)
    {
        Affdex.Face face = pair.Value;
        UpdateExpressionsDials(face);
    }
    

    Alternatively, if you only know that the Dictionary will at most will have one entry that is by setting the number of faces to be detected to 1. Then, you can just use the Collection.First().Value