В Части 1 статьи я рассказал о веб-компонентах и ​​о том, как их создавать с помощью StencilJS.

Во второй части я объясняю, как я создал Smile to Unlock, используя API HTML5 и Azure Emotive API.

Во-первых, я собираюсь объяснить, как получить изображение пользователя с помощью API HTML5. Затем я воспользуюсь этим изображением с API-интерфейсами Azure Emotive для расчета счастья. В заключение я покажу вам, как генерировать событие из веб-компонента, чтобы сообщить потребителю, что пользователь улыбнулся.

Примечание

Весь исходный код этой статьи можно найти здесь: https://github.com/jawache/smile-to-unlock.

Как сделать снимок с камеры пользователя?

Вы можете использовать встроенный API камеры, чтобы просто сделать снимок пользователя. Для более драматичного эффекта я хотел показать пользователю то, что видит камера, в прямом эфире, дать ему время подготовиться, а затем сделать снимок через три секунды.

Для этого необходимо выполнить следующие шаги:

  1. Запустите камеру и транслируйте вывод в видеотег на вашей странице.
  2. Захватите кадр из видео как файл PNG.

Для начала в шаблоне нашего компонента должен быть тег video:

<video id="video">Video stream not available.</video>

Примечание

У него также есть video ID.

Затем в коде нашего компонента мы берем ссылку на этот элемент с помощью, возможно, некоторого кода, подобного следующему:

this.video = this.el.querySelector("#video") as HTMLVideoElement;

Теперь, когда у нас есть ссылка на видеоэлемент, мы можем запустить камеру и передать вывод на этот видеоэлемент на странице:

navigator.mediaDevices
	.getUserMedia({ video: true }) (1)
	.then(stream => {
	this.video.src = window.URL.createObjectURL(stream); (2)
	return this.video.play(); (3)
	})

1 Мы запрашиваем видео с камеры.
2 Мы конвертируем возвращенный поток в URL, который мы можем присвоить свойству src элемента video.
3 Запускаем камеру.

Приведенный выше код просто начинает показывать прямую трансляцию с камеры в теге видео. Затем мы хотим сделать снимок с камеры. Метод, который я использовал, заключался в том, чтобы взять неподвижное изображение из видео и нарисовать его в элементе холста, а затем скрыть элемент видео.

Первым делом нужно добавить элемент холста в наш шаблон:

<canvas id="picture">&nbsp;</canvas>

Как и раньше, мы берем ссылку на этот холст и сохраняем ее в нашем компоненте:

this.canvas = this.el.querySelector("canvas") as HTMLCanvasElement;

Затем с помощью нескольких строк кода мы можем взять стоп-кадр из видеопотока и сохранить его на холсте, например:

let context = this.canvas.getContext("2d"), (1)
    width = this.video.videoWidth,
    height = this.video.videoHeight;

if (width && height) {
	this.canvas.width = width; (2)
	this.canvas.height = height;

	context.drawImage(this.video, 0, 0, width, height); (3)
}

1 Получите ссылку на canvas и ширину / высоту видео.
2 Установите такую ​​же ширину и высоту холста, как и видео.
3 На холсте сделайте копию текущего кадра видео.

Как распознать улыбку?

Обнаружение улыбки может показаться самой сложной частью всего этого компонента, но на самом деле оно оказалось самым простым. Я использовал Azure Emotive API.

Это часть набора API-интерфейсов на платформе Azure под названием Cognitive Services. Коллекция API-интерфейсов искусственного интеллекта, которые либо имеют встроенное высокоуровневое машинное обучение, либо основаны на предварительно обученных моделях. Emotive API - это последние. Они основаны на предварительно обученной модели, которая при передаче изображения возвращает массив лиц с некоторыми данными об обнаруженных эмоциях на этих лицах.

[
  {
    "faceRectangle": {
      "top": 114,
      "left": 212,
      "width": 65,
      "height": 65
    },
    "scores": {
      "anger": 1.0570484e-8,
      "contempt": 1.52679547e-9,
      "disgust": 1.60232943e-7,
      "fear": 6.00660363e-12,
      "happiness": 0.9999998,
      "neutral": 9.449728e-9,
      "sadness": 1.23025981e-8,
      "surprise": 9.91396e-10
    }
  },
  .
  .
  .
]

Что мне нравится в API Cognitive Services, так это то, что не нужно глубоко разбираться в ИИ, чтобы их использовать. Практически все, что вам нужно сделать, чтобы использовать их, - это сделать запрос к URL-адресу.

Запросить ключ доступа

Самый простой способ начать - получить пробный ключ на странице когнитивных услуг. Он предоставляет вам бесплатный доступ в течение 30 дней и требует минимальной настройки. Даже после бесплатного пробного периода API будет бесплатным для первых 30 000 вызовов (да, я сказал 30 000!)

(1) Перейдите на https://azure.microsoft.com/en-gb/try/cognitive-services/?api=emotion-api&WT.mc_id=ashussai и щелкните Get Api Key для Emotion API.

(2) Примите любые условия

(3) Создайте учетную запись или войдите в систему

(4) Вот и все! Запишите ключи и URL-адрес конечной точки, они вам понадобятся позже.

Вызов API

Чтобы вызвать API, мы делаем POST-запрос к конечной точке API, который предоставляется нам при прохождении регистрации. Для меня API был: https://westus.api.cognitive.microsoft.com/emotion/v1.0/recognize.

У API есть несколько параметров. Вы можете передать URL-адрес изображения для проверки или передать изображение как большой двоичный объект в вызове API. Мы используем последний метод. Однако теперь, когда изображение находится в элементе холста, действительно очень легко получить BLOB: мы просто используем функцию toBlob на canvas, например:

getImageBlob(): Promise<Blob> { (1)
    return new Promise(resolve => {
      this.canvas.toBlob(blob => resolve(blob)); (2)
    });
  }

1 Это вспомогательная функция нашего компонента, которая возвращает обещание, которое преобразуется в большой двоичный объект.
2. Функция toBlob имеет обратный вызов, который мы используем для разрешения Promise и передачи большого двоичного объекта.
Затем мы используем этот большой двоичный объект для вызова Emotive API:

let blob = await this.getImageBlob(); (1)
let response = await fetch(this.apiUrl, {
	headers: {
	"Ocp-Apim-Subscription-Key": this.apiKey, (2)
	"Content-Type": "application/octet-stream" (3)
	},
	method: "POST",
	body: blob (4)
});
let faces = await response.json();(5)

1 Здесь мы берем каплю с холста.
2 Для аутентификации нам нужно передать API ключ нашего приложения, который мы получили при регистрации в Cognitive Services.
3 Нам нужно указать поток октетов, поскольку мы передаем двоичный blob.
4 Мы передаем большой двоичный объект как тело сообщения.
5 В случае успеха мы получаем ответ в виде json.

faces теперь содержит объект с эмоциональной оценкой для каждого обнаруженного лица, например:

{
	"anger": 1.0570484e-8,
	"contempt": 1.52679547e-9,
	"disgust": 1.60232943e-7,
	"fear": 6.00660363e-12,
	"happiness": 0.9999998,
	"neutral": 9.449728e-9,
	"sadness": 1.23025981e-8,
	"surprise": 9.91396e-10
}

Я предположил, что на картинке будет только один пользователь, поэтому я просто беру оценку счастья по первому лицу:

if (faces.length > 0) {
    let face = faces[0];
    this.happiness = face.scores.happiness;
}

Если пользователь достаточно доволен, мы можем отправить событие, например:

unlockContent() {
    this.userSmiled.emit({ score: this.happiness });
}

Затем потребитель веб-компонента использует это событие для разблокировки содержимого:

var locker = document.querySelector('smile-to-unlock');

locker.addEventListener("userSmiled", function (ev) {
	console.log(ev.detail.score);

	// Hide the hider so we show the content

	// End the locker so the camera is shutdown
	locker.end();
})

"Вывод"

В этом руководстве я объяснил только основные концепции, необходимые для понимания кода, который можно найти здесь: https://github.com/jawache/smile-to-unlock . Если вы хотите узнать больше, прочтите исходный код.

Что касается StencilJS, несколько вещей все еще находятся в разработке, и функциональность добавляется с бешеной скоростью. Вы должны ожидать хороших результатов от этого проекта в будущем. Но не ждите, что это руководство будет оставаться в актуальном состоянии!

Начать работу с когнитивными API от Azure очень просто. Просто создайте учетную запись, и все готово! Конечно, с Emotive API очень весело поиграть, но это еще не все. Посмотрите и вдохновитесь на создание чего-нибудь. Если вы дадите мне знать, я с радостью расскажу об этом!

Первоначально опубликовано на сайте codecraft.tv 1 декабря 2017 г.