Microsoft Cognitive Services Notes: Emotion API (Node.js)

El set de servicios de cognitive services de Microsoft, proyecto conocido como «Project Oxford» hasta el pasado build (evento en donde se realizo su lanzamiento oficial), es una colección de APIS gratuitas que nos permite construir aplicaciones inteligentes,con solo unas cuantas lineas de código, sobre cualquier plataforma(python, Android,iOs,C#, java etc), para cualquier tipo de dispositivo.  Tal como lo menciono Harry Shum, Vicepresidente ejecutivo de Microsoft Research «Give your apps a human side»; Estas APIS estan agrupadas en 5 areas principales: Computer Vision, Speech Recognition,Natural language, Knowledge y Search, durante su intervención en el build, Harry menciono  algunas showcase apps, que vale la pena mencionarlas:

How-Old.net: Es una aplicación que a partir de una fotografia,usando el  API de face recognition, incluida dentro de la suite de servicios de cognitive services, es capaz de predecir la edad de la persona.

TwinsOrNot.net: Esta aplicación, al igual que el anterior, se apoya en el API de face recognition y la de Bing, para determinar el porcentaje de parecido entre dos personas. si llega al 100% eso quiere decir que has encontrado a tu gemelo!.

Es realmente fascinante lo que podemos llegar  a hacer, si integramos en nuestros desarrollos este tipo de servicios, A continuación le dejo un ejemplo de ello, presentado por el Microsoft CEO Satya Nadella,  durante el keynote :

En este primer post introductivo, les enseñaré como consumir el api de reconocimiento de emociones usando Node.js.

El API de reconocimiento de emociones, recibe como entrada una imagen e identifica dentro de la misma las caras de las personas y sus emociones, actualmente este servicio que se encuentra en beta, es capaza de detectar emociones de alegría, tristeza, sorpresa, ira, miedo, desprecio, disgusto o neutral; Al momento de usar el API, debemos de considerar lo siguiente: Los formatos de imagen soportados son: JPEG, PNG, GIF, BMP, el tamaño de la imagen no debe exceder los 4mb, el tamaño de las caras debe estar entre 36×36 hasta 4096×4096 pixeles para poder ser detectadas. Para cada imagen, el número máximo de caras detectadas es 64. Si no se detecta ninguna cara, el servicio devolverá una matriz vacía. El desprecio y disgusto son emociones experimentales.

Para Empezar debemos ingresar al sitio de Microsoft Cognitive services, registrarnos y posteriormente iniciar sesión:

2016-04-11_16-10-06

  • El siguiente paso, consiste en obtener nuestra API Key:

2016-04-13_23-02-28

2016-04-16_18-31-07

A continuación, abrimos visual studio y procedemos entonces a crear nuestro proyecto, desde el menu File/New/New Project:

2016-04-17_0-42-28

Luego, agregamos nuestro archivo de configuración:

2016-04-17_0-45-43

A nuestro archivo de configuración adicionamos dos variables EMOTION_API_KEY, EMOTION_API_ENDPOINT:

config.json:

{
"EMOTION_API_KEY": "<API>",
"EMOTION_API_ENDPOINT": "https://api.projectoxford.ai/emotion/v1.0/recognize"
}
view raw config.json hosted with ❤ by GitHub

Así debe de quedar nuestro archivo server.js

server.js (server)

//1. cargamos nuestras dependencias
var Hapi = require("hapi");
var Path = require('path');
var Util = require("util");
var Fs = require('fs');
var Http = require('http');
var Request = require('request');
//2. Leemos nuestro archivo de configuración
var config = {};
Fs.readFile('./config.json', 'utf8', function (err, data) {
config = JSON.parse(data.toString('utf8').replace(/^\uFEFF/, '')); console.log(config);
});
//3. Instanciamos nuestro objeto server, el cual se encargará de atender y administrar todas las conexiones entrantes.
var server = new Hapi.Server();
//4. Inicializamos los modulos(plugins hapi)
server.register(require('inert'), function (err) {
if (err) {
console.error('Failed to load plugin:', err);
}
});
//5. especificamos el puerto por el cual, nuestro objeto server atenderá conexiones
server.connection({ port : 3000 });
//6. Definimos las rutas de nuestra app
server.route({
path: "/" , method: "GET", handler: {
file: Path.join(__dirname, 'src/views') + "/index.html"
}
});
//7.Contenido estatico de nuestro app (.css, .js, images etc)
server.route({
path: "/public/{path*}", method: "GET", handler: {
directory: { path: Path.join(__dirname, 'public'), listing: true }
}
});
/*
* 8. esta función se encarga de recibir la imagen enviada por el usuario desde la pagina index.html(front-end),
* e invokar el api de reconocimiento de expresiones de cognitive services
*/
server.route({
path: '/upload',
method: 'POST',
config: {
payload: {
//restricciones de archivo
output: 'stream',
maxBytes: 1048576 * 10, /*10MB*/
parse: true,
allow: 'multipart/form-data'
}
}, handler: function (request, reply) {
var data = request.payload;
if (data.file) {
var fileName = Path.basename(data.file.hapi.filename);//obtenemos el nombre de la imagen
var src = Path.join(__dirname, Util.format('public/upload/%s', fileName)); //definimos la ruta en donde quedará guardada la imagen en nuestro server
//copiamos la imagen en nuestro servidor
var stream = Fs.createWriteStream(src);
data.file.pipe(stream);//
//si esta operación se realiza con exito
data.file.on('end', function (err) {
if (err) reply(err);
//invocamos el Api de reconocimiento de expresiones de Microsoft cognitive services
var req = Request(
{
url: config.EMOTION_API_ENDPOINT,//url de la api
method: 'POST',
headers: {
'Content-Type': 'application/octet-stream',//formato de envío de la imagen al api
'Ocp-Apim-Subscription-Key': config.EMOTION_API_KEY,//suscription API KEY
}
}, function (error, response, body) {
if (error) {
reply(error); //en caso de que se algo salga mal, retornamos al cliente dicho error
} else {
// si todo sale bien, devolvemos al cliente la respuesta del API
reply({ 'uri' : Util.format('/public/upload/%s', fileName), 'info': body }).code(200);
}
});
Fs.createReadStream(src).pipe(req);//enviamos la imagen como un stream al api
});
}
}
});
//ejecutamos nuestro server
server.start(function (err) {
if (err) { throw err; } console.log('Server running at:', server.info.uri);
});
view raw server.js hosted with ❤ by GitHub

Creamos dos archivos mas en nuestro proyecto index.html(en la raíz) y app.js (public/js):

index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Emotion API Node js</title>
</head>
<body>
<form id="frmUploadImage">
<input type="file" name="file" id="inputImage">
<button type="submit" class="btn btn-default">Cargar foto</button>
</form>
<canvas id="canvasLoadImage"></canvas>
<script src="/public/vendor/jquery/dist/jquery.js"></script>
<script src="/public/js/app.js"></script>
</body>
</html>
view raw index.html hosted with ❤ by GitHub

app.js (client)

$(document).ready(function () {
$form = $("#frmUploadImage"), $inputFile = $('#inputImage');
$form.on("submit", function (e) {
e.preventDefault();
if ($inputFile.get(0).files.length === 0) {
alert("No ha seleccionado ninguna imagen");
return false;
}
var formData = new FormData($(this)[0]);
//enviamos la imagen cargada por el usuario al servidor
$.ajax({
url: '/upload',
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
processData: false,
success: function (data) {
console.log(data);
previewImage(data);//visualizamos la imagen si todo sale bien
}
});
});
function drawPoint(x, y, ctx) {
ctx.beginPath(); ctx.arc(x, y, 2, 0, 2 * Math.PI, true); ctx.fill();
}
function previewImage(data) {
var c = document.getElementById("canvasLoadImage");
var ctx = c.getContext("2d");
var img = new Image();
img.onload = function () {
//obtenemos las dimensiones de la imagen
c.width = this.width;
c.height = this.height;
//dibujamos la imagen en nuestro canvas
ctx.drawImage(this, 0, 0);
//lista de caras detectadas dentro de la imagen
var faces = JSON.parse(data.info);
$.each(faces, function (index, face) {
//obtenemos la posisción de cada cara dentro de nuestra imagen
var rec = face.faceRectangle;
ctx.fillStyle = '#DF0174';
ctx.globalAlpha = 0.1;
ctx.fillRect(rec.left, rec.top, rec.width, rec.height);
ctx.globalAlpha = 1;
drawPoint(rec.left, rec.top, ctx);
drawPoint(rec.left + rec.width, rec.top, ctx);
drawPoint(rec.left, rec.top + rec.height, ctx);
drawPoint(rec.left + rec.width, rec.top + rec.height, ctx);
ctx.strokeStyle = 'red';
ctx.restore();
ctx.fillStyle = '#DF0174';
ctx.font = "20px Arial";
ctx.stroke();
var max, maxScore;
$.each(face.scores, function (key, value) {
if (!max || parseFloat(value) > parseFloat(max)) {
max = parseFloat(value); maxScore = key;
}
});
ctx.fillText(maxScore, rec.left + (rec.width / 2), rec.top + (rec.height / 2));
});
};
img.src = data.uri;//url de la imagen en el servidor
}
});
view raw app.js hosted with ❤ by GitHub

Y finalmente la demo funcionando!.

El codigo fuente lo pueden descargar de: Emotion-API-Microsoft-Cognitive-Services-Nodejs

Espero les sea de utilidad, hasta la proxima ocasión

Gracias!

Anuncio publicitario

2 comentarios en “Microsoft Cognitive Services Notes: Emotion API (Node.js)

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s