Search code examples
androidazureattributesazure-cognitive-servicesface-api

Face API - Variation in # of Emotion Attributes


I am using the Microsoft Face API to detect faces and emotions in Android. I have a TreeMap whose key is the probability of an emotion attribute with the value being the attributes name like so:

TreeMap<Double, String> treeMap = new TreeMap<>();
treeMap.put(person.faceAttributes.emotion.happiness, "Happiness");
treeMap.put(person.faceAttributes.emotion.anger, "Anger");
treeMap.put(person.faceAttributes.emotion.disgust, "Disgust");
treeMap.put(person.faceAttributes.emotion.sadness, "Sadness");
treeMap.put(person.faceAttributes.emotion.neutral, "Neutral");
treeMap.put(person.faceAttributes.emotion.surprise, "Surprise");
treeMap.put(person.faceAttributes.emotion.fear, "Fear");

(person is an object of the type Face)

What I want to do is rank those 7 emotions from most likely to least likely but the problem is that the size of treeMap varies. For example, when I choose to get the emotion attributes of a face that is smiling, treeMap.size() returns 2. When I choose to get the emotion attributes of a face that is mainly neutral, treeMap.size() returns 3.

Does anyone know why this behavior is occurring even though I have added 7 key-value pairs to treeMap using treeMap.put()? I have found that the key-value pairs which do exist in treeMap are the most likely emotions, but even if the other attributes were to be 0, why aren't they still being added to treeMap.


Solution

  • The reason that this error is occurring is because you are using a TreeMap which only allows unique keys. What this means is that if there are more than one emotions with 0.0% confidence, then only the last one will be stored because the key for your TreeMap is a Double.

    Therefore, with the code that you have posted, you will only receive the emotions that had different percentages of confidence levels. To fix this problem what you should do is switch the types of the TreeMap like so:

    TreeMap<String, Double> treeMap = new TreeMap<>();
    

    Now, if you want to sort the TreeMap by the values, Double, and not the key, you will have to use a Comparator. You can find a good solution here about how to do that.

    Basically what that solution does is take the Map passed in, makes a list of the values, sorts the values, and then returns back the sorted Map. I hope this answers your question!