Skip to content

Instantly share code, notes, and snippets.

@muvaf
Last active September 19, 2023 11:01
Show Gist options
  • Save muvaf/4a856bd85244570cb7cf200e39c1ef5d to your computer and use it in GitHub Desktop.
Save muvaf/4a856bd85244570cb7cf200e39c1ef5d to your computer and use it in GitHub Desktop.
Here is the script I used for Emotion Recognition in Unity [Microsoft Cognitive Services]
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Globalization;
using System;
public class EmotionService : MonoBehaviour {
WebCamTexture webCamTexture;
public float photoInterval = 1.0f;
public float time;
public int num = 0;
public string aiUrl = "https://westus.api.cognitive.microsoft.com/emotion/v1.0/recognize";
public string secretKey = "YOUR-SECRET-KEY";
private byte[] lastPhoto;
public bool isActive = true;
public Texture2D[] textures;
void Awake()
{
time = photoInterval;
isActive = SceneInteractions.isEmotionServiceActive;
}
void Start()
{
if (isActive)
{
if (WebCamTexture.devices.Length > 1)
webCamTexture = new WebCamTexture(WebCamTexture.devices[1].name);
else
webCamTexture = new WebCamTexture();
webCamTexture.Play();
}
//TakePhoto();
}
void Update()
{
transform.position = new Vector3(transform.position.x, GameObject.Find("Main Camera").GetComponent<Camera>().ViewportToWorldPoint(new Vector3(0.8f, 0.92f, 0)).y, transform.position.z);
if (isActive)
{
time -= Time.deltaTime;
if (time < 0)
{
StartCoroutine(TakePhoto());
time = photoInterval;
}
}
}
IEnumerator TakePhoto()
{
// NOTE - you almost certainly have to do this here:
yield return new WaitForEndOfFrame();
Texture2D photo = new Texture2D(webCamTexture.width, webCamTexture.height);
photo.SetPixels(webCamTexture.GetPixels());
photo.Apply();
if (WebCamTexture.devices.Length > 1)
photo = rotateTexture(photo);
//GameObject.Find("front").GetComponent<Renderer>().material.mainTexture = photo;
//Encode to a JPG for upload speed
lastPhoto = photo.EncodeToJPG(30);
//File.WriteAllBytes("photo" + num +".jpg", lastPhoto);
sendPhoto();
Debug.Log("took photo");
num++;
}
void sendPhoto()
{
Dictionary<string, string> headers = new Dictionary<string, string>();
headers["Content-Type"] = "application/octet-stream";
headers["Ocp-Apim-Subscription-Key"] = secretKey;
WWW www = new WWW(aiUrl, lastPhoto, headers);
StartCoroutine(WaitForRequest(www));
}
IEnumerator WaitForRequest(WWW www)
{
Debug.Log("started to send");
yield return www;
Debug.Log("came back");
// check for errors
if (www.error == null)
{
if (www.text.Length > 100)
{
string happiness = www.text.Substring(www.text.IndexOf("happiness") + 11, www.text.IndexOf("neutral") - (www.text.IndexOf("happiness") + 13));
float happinessIndex = float.Parse(happiness, CultureInfo.InvariantCulture.NumberFormat);
broadcastEmotion(happinessIndex);
}else
{
Debug.Log(www.text);
}
}
else
{
Debug.Log("WWW Error: " + www.error);
}
}
void broadcastEmotion(float happinessIndex)
{
//score
string stringOnScene = string.Format("{0:0}", happinessIndex * 10);
int integerFormat = Convert.ToInt32(stringOnScene);
SceneInteractions.score += integerFormat;
Debug.Log("brd: " + happinessIndex + "form" + integerFormat);
//smiley update
if (integerFormat <= 2)
GetComponent<Renderer>().material.mainTexture = textures[0];
else if (integerFormat <= 4)
GetComponent<Renderer>().material.mainTexture = textures[1];
else if (integerFormat <= 6)
GetComponent<Renderer>().material.mainTexture = textures[2];
else if (integerFormat <= 8)
GetComponent<Renderer>().material.mainTexture = textures[3];
else if (integerFormat <= 10)
GetComponent<Renderer>().material.mainTexture = textures[4];
//speed
GameObject.Find("Player").GetComponent<PlayerRun>().takeHappinessIndex(happinessIndex);
}
public Texture2D rotateTexture(Texture2D image)
{
Texture2D target = new Texture2D(image.height, image.width, image.format, false); //flip image width<>height, as we rotated the image, it might be a rect. not a square image
Color32[] pixels = image.GetPixels32(0);
pixels = rotateTextureGrid(pixels, image.width, image.height);
target.SetPixels32(pixels);
target.Apply();
//flip image width<>height, as we rotated the image, it might be a rect. not a square image
return target;
}
public Color32[] rotateTextureGrid(Color32[] tex, int wid, int hi)
{
Color32[] ret = new Color32[wid * hi]; //reminder we are flipping these in the target
for (int y = 0; y < hi; y++)
{
for (int x = 0; x < wid; x++)
{
ret[(hi - 1) - y + x * hi] = tex[x + y * wid]; //juggle the pixels around
}
}
return ret;
}
}
@muvaf
Copy link
Author

muvaf commented Sep 19, 2023

@SouhaF I don't know. This is from 2016, likely everything has changed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment