Search code examples
c#apiemotionazure-cognitive-services

Displaying Project Oxford's Emotion API result in C#


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.


Solution

  • 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.