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.
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.
Related
I try to deserialize my JSON Response which is at below, but when i print the content of each parameter, it shows error.
My JSON Resposne:
[
{
"faceRectangle": {
"top": 214,
"left": 472,
"width": 450,
"height": 450
},
"faceAttributes": {
"age": 19.0,
"emotion": {
"anger": 0.0,
"contempt": 0.0,
"disgust": 0.0,
"fear": 0.0,
"happiness": 0.0,
"neutral": 0.996,
"sadness": 0.003,
"surprise": 0.001
}
}
}
]
I able to deserialize my code with this:
public static async Task<List<RootObject>> MakeAnalysisRequest(string imageFilePath)
{
HttpClient client = new HttpClient();
// Request headers.
client.DefaultRequestHeaders.Add(
"Ocp-Apim-Subscription-Key", subscriptionKey);
// Request parameters. A third optional parameter is "details".
string requestParameters = "&returnFaceId=false&returnFaceLandmarks=false&returnFaceAttributes=age,emotion";
// Assemble the URI for the REST API Call.
string uri = uriBase + "?" + requestParameters;
HttpResponseMessage response;
// Request body. Posts a locally stored JPEG image.
byte[] byteData = GetImageAsByteArray(imageFilePath);
using (ByteArrayContent content = new ByteArrayContent(byteData))
{
// This example uses content type "application/octet-stream".
// The other content types you can use are "application/json"
// and "multipart/form-data".
content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
// Execute the REST API call.
response = await client.PostAsync(uri, content);
// Get the JSON response.
string contentString = await response.Content.ReadAsStringAsync();
// Display the JSON response.
Console.WriteLine("\nResponse:\n");
string format = JsonPrettyPrint(contentString);
var deserializedJson = JsonConvert.DeserializeObject<List<RootObject>>(format);
Console.WriteLine(format);
Console.WriteLine(deserializedJson);
Console.WriteLine("\nPress Enter to exit...");
return deserializedJson;
}
}
But when i try to print each parameter value, it shows error:
var output1 = MakeAnalysisRequest(imageFilePath).Result;
var x= output1[0].FaceAttributes.Emotion.Anger;
Console.WriteLine(x);
var y = output1[1].FaceAttributes.Emotion.Neutral;
Console.WriteLine(y);
if (x >= 0.5)
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer(#"D:\Degree course outline\FYP2019\soft.wav");
player.Play();
}
if (y>= 0.5)
{
System.Media.SoundPlayer player = new System.Media.SoundPlayer(#"D:\Degree course outline\FYP2019\soft.wav");
player.Play();
}
My error code is like this:
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
How could i solve it?
Thanks
My class object:
class Program
{
public class FaceRectangle
{
public int Top { get; set; }
public int Left { get; set; }
public int Width { get; set; }
public int Height { get; set; }
}
public class Emotion
{
public double Anger { get; set; }
public double Contempt { get; set; }
public double Disgust { get; set; }
public double Fear { get; set; }
public double Happiness { get; set; }
public double Neutral { get; set; }
public double Sadness { get; set; }
public double Surprise { get; set; }
}
public class FaceAttributes
{
public double Age { get; set; }
public Emotion Emotion { get; set; }
}
public class RootObject
{
public FaceRectangle FaceRectangle { get; set; }
public FaceAttributes FaceAttributes { get; set; }
}
Try this code:
var output1 = await MakeAnalysisRequest(imageFilePath);
if (output1 != null && output1.Count > 0)
{
var x= output1[0].FaceAttributes.Emotion.Anger;
Console.WriteLine(x);
}
if (output1 != null && output1.Count > 1)
{
var y = output1[1].FaceAttributes.Emotion.Neutral;
}
The out of range exception is there because your deserialized output does not have enough elements to access. Please share your class object for more help.
Also try to avoid using the .Result to get the return value from asynch as it could lead to deadlocks.
Edit after providing class
With your class being like this then change your code accordingly:
var output1 = await MakeAnalysisRequest(imageFilePath);
if (output1 != null && output1.Count > 0)
{
var x= output1[0].FaceAttributes.Emotion.Anger;
Console.WriteLine(x);
var y = output1[0].FaceAttributes.Emotion.Neutral;
Console.WriteLine(y);
}
There is only one RootObject in your jsons array that is comprised of two others.
Json array [] object {}
An array with two objects looks like this [{},{}] and not like this [{{},{}}]
I want to send Post Request with C# WebClient with this Json Schema :
[
{
"id": "00000000-0000-0000-0000-000000000000",
"points": [
{
"timestamp": "2017-12-04T16:07:44.562Z",
"value": 0
}
]
}
]
I've tried This :
public class RequestData
{
public string id {get; set; }
public points points { get; set; }
}
public class points
{
public DateTime timestamp { get; set; }
public float value { get; set; }
}
My Program :
Random number = new Random();
var req = new RequestData();
req.id = "0e13d9c-571c-44f4-b796-7c40c0e20a1d";
req.points = new points { timestamp = DateTime.UtcNow, value =
number.Next(100, 99999) };
JsonSerializerSettings settings = new JsonSerializerSettings();
var data = JsonConvert.SerializeObject(req);
WebClient client = new WebClient();
client.Headers.Add(HttpRequestHeader.Authorization,
AquaAtuhorization.accessToken);
client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
client.UploadString ("http://localhost:8080/api/v1/data/writeNumericValues",
data );
And I always get Http 415 (Unsupported Media Type).
How could I format my C# Object as the restApi accepeted Format.
Look at the JSON, the square brackets [ ] denote that something is an array. In this case both RequestData and points have to be an array, see the example below:
public class RequestData
{
public string id { get; set; }
public List<points> points { get; set; } // I use list, could be an array
}
public class points
{
public DateTime timestamp { get; set; }
public float value { get; set; }
}
Then construct your req object like this:
var req = new List<RequestData> // Again I use list, could be an array
{
new RequestData
{
id = "0e740d9c-571c-44f4-b796-7c40c0e20a1d",
points = new List<points> // Defined as a list, even though it has one entry
{
new points
{
timestamp = DateTime.UtcNow,
value = number.Next(100, 99999)
}
}
}
};
Then just serialize it as normal, the result will be the below:
[
{
"id":"0e740d9c-571c-44f4-b796-7c40c0e20a1d",
"points":[
{
"timestamp":"2017-12-04T17:12:25.8957648Z",
"value":59522.0
}
]
}
]
Your Json class needs to be like this, see http://json2csharp.com/ or use paste as JSON from VS https://blog.codeinside.eu/2014/09/08/Visual-Studio-2013-Paste-Special-JSON-And-Xml/
public class Point
{
public DateTime timestamp { get; set; }
public int value { get; set; }
}
public class RootObject
{
public string id { get; set; }
public List<Point> points { get; set; }
}`
This class I created myself:
public class member
{
public string account_name { get; set; }
public long account_id { get; set; }
public Rootobject[] rootobject { get; set; }
}
This are the classes VS created for me autmatically using an example JSON answer:
public class Rootobject
{
public string status { get; set; }
public Meta meta { get; set; }
public Data data { get; set; }
}
public class Meta
{
public int count { get; set; }
}
public class Data
{
public _507888780[] _507888780 { get; set; }
}
public class _507888780
{
public All all { get; set; }
public int tank_id { get; set; }
}
public class All
{
public int spotted { get; set; }
public int hits_percents { get; set; }
public int wins { get; set; }
...
}
A small part of the JSON response from the API server I use looks like this:
{
"status": "ok",
"meta": {
"count": 1
},
"data": {
"507888780": [
{
"all": {
"spotted": 467,
"hits_percents": 83,
"wins": 281,
},
"tank_id": 2849
},
{
"all": {
"spotted": 224,
"hits_percents": 63,
"wins": 32,
},
"tank_id": 9473
},
}
}
This is the code I use to read out the tanks a member has (including all the stats) where Request(string) is just the http request.
private List<member> memberlist = new List<member>(100);
private void DoStuff()
{
memberlist = JsonConvert.DeserializeObject<List<member>>(result_member);
foreach (var member in memberlist)
{
string result_tank = Request("https://api.worldoftanks.eu/wot/tanks/stats/?application_id=" + application_id + "&account_id=" + member.account_id + "&tank_id=" + tanks + "&fields=all.battles%2C+all.wins%2C+all.damage_dealt%2C+all.frags%2C+all.hits_percents%2C+all.piercings%2C+all.shots%2C+all.spotted%2C+all.survived_battles%2C+all.tanking_factor");
var Rootobject = JsonConvert.DeserializeObject<Rootobject>(result_tank);
foreach (var tank in _507888780)
{
richTextBox1.Text += Rootobject.data._507888780[tank].tank_id + Rootobject.data._507888780[tank].all.spotted.ToString() + "...";
}
}
}
Now, I want to be able to search up all the different tanks including their stats for all members. Right now I'm getting the error in the line I want to print "Type Tank_Statistics._507888780 cannot be implicitly converted to int." Earlier on I alos got an error with a missing IEnumerable which I dont have right now though..
Anyways .. I can't make it work somehow.. it would be very kind if someone would be able to help me on this ;)
Seems that you should replace this
richTextBox1.Text += Rootobject.data._507888780[tank].tank_id + Rootobject.data._507888780[tank].all.spotted.ToString() + "...";
to this
richTextBox1.Text += tank.tank_id + tank.all.spotted.ToString() + "...";
I am trying to build a site using ASP.NET MVC 4 and C# to search for the top 5 albums of a musical artist using the Spotify web api.
Here is my code so far:
public ActionResult Result(string Artist)
{
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://api.spotify.com/");
// what goes here to authenticate and get the info?
return View();
}
I can not find information that tells me how to authenticate and then retrieve the information using C#.
Edit: I should mention that I am an absolute beginner with this stuff and while I did read the spotify api reference, it did not help me because it does not explain enough detail.
For example the web api user guide talks about GET, POST, etc but does not give any code to help explain how to use it. The only code on there is:
$ curl -H "Authorization: Basic Yjc...cK" -d grant_type=refresh_token -d refresh_token=AQD...f0 "https://accounts.spotify.com/api/token"
{
"error": "invalid_client",
"error_description": "Invalid client secret"
}
Which is confusing to me because I don't know where to put it, I don't know what language the code is, etc.
There are no C# examples that I can find. Even the code examples are all javascript which does not help me.
You should see this maybe help to you
TagSearch
using System;
using System.Net;
using System.Text;
using System.Linq;
using System.Collections.Generic;
namespace TagSearch.Plugins
{
public class Spotify : IClass
{
#region JsonParseData
public class Rootobject
{
public Tracks tracks { get; set; }
}
public class Tracks
{
public List<Item> items { get; set; }
}
public class Item
{
public Album album { get; set; }
public List<Artist> artists { get; set; }
public int disc_number { get; set; }
public string name { get; set; }
public int track_number { get; set; }
}
public class Album
{
public string href { get; set; }
public string release_date { get; set; }
public string release_date_precision { get; set; }
public List<Image> images { get; set; }
public string name { get; set; }
}
public class Image
{
public int height { get; set; }
public string url { get; set; }
public int width { get; set; }
}
public class Artist
{
public string name { get; set; }
}
#endregion
protected Dictionary<String, int> _TempTotal;
protected Dictionary<String, List<ITag>> _TempTag;
private object _Lock = new object();
public Spotify()
{
JParse = new System.Text.Json.JsonParser();
_TempTotal = new Dictionary<string, int>();
_TempTag = new Dictionary<String, List<ITag>>();
}
public override void Search(string Name)
{
GetInfo(Name);
}
protected override void GetInfo(string Name)
{
lock (_Lock)
{
_TempTotal.Add(Name, -1);
_TempTag.Add(Name, new List<ITag>());
}
var web = new IWebClient();
web.DownloadDataCompleted += DownloadDataCompleted;
web.DownloadDataAsync(new Uri("https://api.spotify.com/v1/search?&type=track&limit=50&q=" + Uri.EscapeDataString(Name.ToLower())), new IWebClient.WebClientState(Name, 1, null));
while (_TempTotal[Name] != _TempTag[Name].Count) { System.Threading.Thread.Sleep(1000); }
OnEvent(Name,_TempTag[Name]);
_TempTotal.Remove(Name);
_TempTag.Remove(Name);
base.GetInfo(Name);
}
protected void DownloadDataCompleted(dynamic sender, dynamic e)
{
if (e.Result != null)
{
string Name = e.UserState.Name;
switch ((int)e.UserState.State)
{
case 1:
var _RootObject = JParse.Parse<Rootobject>(Encoding.UTF8.GetString(e.Result));
_TempTotal[Name] = _RootObject.tracks.items.Count;
foreach (var Json in _RootObject.tracks.items)
{
var web = new IWebClient();
web.DownloadDataCompleted += DownloadDataCompleted;
web.DownloadDataAsync(new Uri(Json.album.href), new IWebClient.WebClientState(Name, 2, new ITag(this.GetType(), Json.name, Json.album.name, Json.artists[0].name, null, DateTime.MinValue, Json.disc_number, Json.track_number)));
System.Threading.Thread.Sleep(250);
}
sender.Dispose();
break;
case 2:
var Json2 = JParse.Parse<Album>(System.Text.Encoding.UTF8.GetString(e.Result));
e.UserState.State = 3;
switch ((string)Json2.release_date_precision)
{
case "year": e.UserState.Tag.RelaseDate = DateTime.Parse(Json2.release_date + "-01-01"); break;
case "month": e.UserState.Tag.RelaseDate = DateTime.Parse(Json2.release_date + "-01"); break;
case "day": e.UserState.Tag.RelaseDate = DateTime.Parse(Json2.release_date); break;
}
sender.DownloadDataAsync(new Uri(Json2.images[0].url), e.UserState);
break;
case 3:
e.UserState.Tag.Cover = e.Result;
_TempTag[Name].Add(e.UserState.Tag);
sender.Dispose();
break;
}
}
}
}
}
I try to get the first image from wikipedia api. I wrote the following C# code to retrieve the source from Thumbnail. But whenever I run the code it shows exception
An unhandled exception of type 'Newtonsoft.Json.JsonReaderException'
occurred in Newtonsoft.Json.dll Additional information: Unexpected
character encountered while parsing value: <. Path '', line 0,
position 0.
My code is as follows
public class Thumbnail
{
public string source { get; set; }
public int width { get; set; }
public int height { get; set; }
}
public class Pageval
{
public int pageid { get; set; }
public int ns { get; set; }
public string title { get; set; }
public Thumbnail thumbnail { get; set; }
public string pageimage { get; set; }
}
public class Query
{
public Dictionary<string, Pageval> pages { get; set; }
}
public class RootObject
{
public string batchcomplete { get; set; }
public Query query { get; set; }
}
class Class1
{
public static PictureBox Image1 = new PictureBox();
public static Label Image1_title = new Label();
public static void Load_Image(string name1, string LocationName)
{
var startPath = Application.StartupPath;
string Imagefolder = Path.Combine(startPath, "Image");
string subImageFolder = Path.Combine(Imagefolder, LocationName);
System.IO.Directory.CreateDirectory(subImageFolder);
using (var wc = new System.Net.WebClient())
{
var uri = ("https://en.wikipedia.org/w/api.php?action=query&prop=pageimages&pithumbsize=400&titles="+name1);
var response = wc.DownloadString(new Uri(uri));
var responseJson = JsonConvert.DeserializeObject<RootObject>(response);
var firstKey = responseJson.query.pages.First().Key;
string image1 = responseJson.query.pages[firstKey].thumbnail.source;
string Image_title = responseJson.query.pages[firstKey].title;
Image1.SizeMode = PictureBoxSizeMode.StretchImage;
Image1.LoadAsync(image1);
Image1_title.Text = Image_title;
}
}
}
}
In form1.cs I call this class in the follwing way. and in Textbox I wrote the name such as Berlin.
private void button1_Click(object sender, EventArgs e)
{
Class1.Image1 = pictureBox1;
Class1.Load_Image(textBox1.Text, textBox1.Text);
}
I am not finding out what is the problem with this code
The json I got is
{
"batchcomplete": "",
"query": {
"pages": {
"3354": {
"pageid": 3354,
"ns": 0,
"title": "Berlin",
"thumbnail": {
"source": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Siegessaeule_Aussicht_10-13_img4_Tiergarten.jpg/400px-Siegessaeule_Aussicht_10-13_img4_Tiergarten.jpg",
"width": 400,
"height": 267
},
"pageimage": "Siegessaeule_Aussicht_10-13_img4_Tiergarten.jpg"
}
}
}
}
If you look at the output of your query, it says this:
This is the HTML representation of the JSON format. HTML is good for debugging, but is unsuitable for application use.
Specify the format parameter to change the output format. To see the non-HTML representation of the JSON format, set format=json.
If you follow that advice, it should fix your error.
To display image from URL you need to use WebClient to load image in local system.
ie.
string remoteUri = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Siegessaeule_Aussicht_10-13_img4_Tiergarten.jpg/400px-Siegessaeule_Aussicht_10-13_img4_Tiergarten.jpg";
string fileName = "MyImage.jpg",
WebClient myWebClient = new WebClient();
myWebClient.DownloadFile(remoteUri,fileName);