0

I have trouble displaying the result returned by Emotion API. Result is returned in form of Emotion[]. The code is as follows

    private async void button2_Click(object sender, EventArgs e)
    {
        try
        {
            pictureBox2.Image = (Bitmap)pictureBox1.Image.Clone();
            String s = System.Windows.Forms.Application.StartupPath + "\\" + "emotion.jpg";
            pictureBox2.Image.Save(s);

            string imageFilePath = s;// System.Windows.Forms.Application.StartupPath + "\\" + "testing.jpg"; 
            Uri fileUri = new Uri(imageFilePath);

            BitmapImage bitmapSource = new BitmapImage();
            bitmapSource.BeginInit();
            bitmapSource.CacheOption = BitmapCacheOption.None;
            bitmapSource.UriSource = fileUri;
            bitmapSource.EndInit();

         //   _emotionDetectionUserControl.ImageUri = fileUri;
           // _emotionDetectionUserControl.Image = bitmapSource;

            System.Windows.MessageBox.Show("Detecting...");

            ***Emotion[] emotionResult*** = await UploadAndDetectEmotions(imageFilePath);

            System.Windows.MessageBox.Show("Detection Done");

        }
        catch (Exception ex)
        {
            System.Windows.MessageBox.Show(ex.ToString());
        }
    }

and I need to find the most dominant emotion from results of various emotions.

1 Answers1

1

I went to the API reference. It returns JSON like this:

[
  {
    "faceRectangle": {
      "left": 68,
      "top": 97,
      "width": 64,
      "height": 97
    },
    "scores": {
      "anger": 0.00300731952,
      "contempt": 5.14648448E-08,
      "disgust": 9.180124E-06,
      "fear": 0.0001912825,
      "happiness": 0.9875571,
      "neutral": 0.0009861537,
      "sadness": 1.889955E-05,
      "surprise": 0.008229999
    }
  }
]

I pasted that into http://json2csharp.com/ and it generated some classes for me. (I renamed the root class to Emotion and replaced the scores class with an IDictionary<string, double>. That's because you don't just want a property for each emotion. You want a set that you can sort to find the highest emotion. (IDictionary<string, double> was what most easy to deserialize the json into.)

public class FaceRectangle
{
    public int left { get; set; }
    public int top { get; set; }
    public int width { get; set; }
    public int height { get; set; }
}

public class Emotion
{
    public FaceRectangle faceRectangle { get; set; }
    public IDictionary<string, double> scores { get; set; }
}

Then I wrote a unit test and pasted in the JSON from Microsoft's API page to see if I could deserialize it. I added the Newtsonsoft.Json Nuget package and wrote this:

[TestClass]
public class DeserializeEmotion
{
    [TestMethod]
    public void DeserializeEmotions()
    {
        var emotions = JsonConvert.DeserializeObject<Emotion[]>(JSON);
        var scores = emotions[0].scores;
        var highestScore = scores.Values.OrderByDescending(score => score).First();
        //probably a more elegant way to do this.
        var highestEmotion = scores.Keys.First(key => scores[key] == highestScore);
        Assert.AreEqual("happiness", highestEmotion);
    }

    private const string JSON =
        "[{'faceRectangle': {'left': 68,'top': 97,'width': 64,'height': 97},'scores': {'anger': 0.00300731952,'contempt': 5.14648448E-08,'disgust': 9.180124E-06,'fear': 0.0001912825,'happiness': 0.9875571,'neutral': 0.0009861537,'sadness': 1.889955E-05,'surprise': 0.008229999}}]";

}

The test passes, so that's it. You've got a Dictionary<string,double> containing the scores, so you can both display them and find the emotion with the highest score.

Scott Hannen
  • 21,450
  • 3
  • 33
  • 44
  • I did find these class definitions within the files of Emotion API examples, but issue is that I was unable to convert it to Dictionary or a List even with inbuilt commands. I suppose there has to be a way around without conflicting with the class definitions in the Microsoft.ProjectOxford.Emotion.Contract files. – Shubham Dave Apr 03 '16 at 11:27
  • Scott's suggestion is pretty good, but if you're already using the client SDK, it involves serializing the Emotion[] to string and back in the _other_ Emotion[]. Another option is something like this: ``var top = emotions.Select(emotion => { var dict = new Dictionary(); foreach (var property in typeof(Scores).GetProperties()) { dict.Add(property.Name, (float)property.GetValue(emotion.Scores)); } return dict.OrderByDescending(kv => kv.Value).ThenBy(kv => kv.Key).First(); });`` – cthrash Apr 04 '16 at 19:21
  • @ScottHannen My project is working thank you for the help :) – Shubham Dave Apr 06 '16 at 05:54