TensorFlow.js и clmtrackr.js: отслеживание направления взгляда пользователя в браузере |
||
МЕНЮ Искусственный интеллект Поиск Регистрация на сайте Помощь проекту ТЕМЫ Новости ИИ Искусственный интеллект Разработка ИИГолосовой помощник Городские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Техническое зрение Чат-боты Авторизация |
2018-10-11 17:31 Автор статьи, перевод которой мы публикуем, предлагает поговорить о решении задач из сферы компьютерного зрения исключительно средствами веб-браузера. Решить подобную задачу не так уж и трудно благодаря JavaScript-библиотеке TensorFlow. Вместо того, чтобы обучать собственную модель и предлагать её пользователям в составе готового продукта, мы дадим им возможность самостоятельно собрать данные и обучить модель прямо в браузере, на собственном компьютере. При таком подходе серверная обработка данных совершенно не нужна. Испытать то, созданию чего посвящён этот материал, можно здесь. Вам для этого понадобится современный браузер, веб-камера и мышь. Вот исходный код проекта. Он не рассчитан на работу на мобильных устройствах, автор материала говорит, что у него не было времени на соответствующие доработки. Кроме того, он отмечает, что рассматриваемая тут задача усложнится в том случае, если придётся обрабатывать видеопоток с движущейся камеры.
Идея Давайте, используя технологии машинного обучения, выясним, куда именно смотрит пользователь, когда разглядывает веб-страницу. Сделаем это, наблюдая за его глазами с помощью веб-камеры. Для обнаружения лица на изображении я воспользовался библиотекой, которая называется clmtrackr. Она не идеальна, но отличается маленькими размерами, хорошей производительностью, и, в целом, достойно справляется со своей задачей. Если в качестве входа для простой свёрточной нейронной сети используется маленькое, но с умом подобранное изображение, сеть, без особых проблем, сможет обучиться. Вот как выглядит этот процесс: Входное изображение, модель — свёрточная нейронная сеть, координаты, предсказанное сетью место на странице, куда смотрит пользователь. Здесь будет описана полностью рабочая минимальная реализации рассмотренной в этом разделе идеи. Проект, код которого находится в этом репозитории, обладает множеством дополнительных возможностей. Подготовка Для начала загрузим
Получение видеопотока с веб-камеры Для того чтобы активировать веб-камеру и вывести видеопоток на страницу нам понадобится получить разрешение пользователя. Здесь я не привожу код, решающий проблемы совместимости проекта с различными браузерами. Мы будем исходить из предположения, в соответствии с которым наши пользователи работают в интернете с применением последней версии Google Chrome.
Теперь поработаем с файлом main.js :
Попробуйте этот код у себя. Когда вы откроете страницу, браузер должен запросить разрешение, а затем на экране появится картинка с веб-камеры. Позже мы расширим код функции onStreaming() .Поиск лица Теперь давайте воспользуемся библиотекой clmtrackr.js для поиска лица на видео. Для начала инициализируем систему слежения за лицом, добавив следующий код после
Теперь, в функции onStreaming() , мы подключаем систему поиска лица, добавляя туда следующую команду:
Это всё, что нам нужно. Теперь система сможет распознать лицо в видеопотоке. Не верите? Давайте, для того, чтобы вы в этом убедились, нарисуем вокруг лица «маску». Для того чтобы это сделать, нам нужно вывести изображение поверх элемента, ответственного за показ видео. Рисовать что-либо на HTML-страницах можно с помощью тега <canvas> . Поэтому создадим такой элемент, наложив его на элемент, выводящий видео. В этом нам поможет следующий код, который надо добавить в HTML-файл под уже имеющимся там элементом <video> :
Если хотите — можете переместить встроенный стиль в отдельный CSS-файл. Тут мы добавили на страницу элемент <canvas> того же размера, что и элемент <video> . То, что элементы будут расположены в одной и той же позиции, обеспечивают использованные здесь стили.Теперь, каждый раз, когда браузер выводит очередной кадр видео, мы собираемся рисовать что-то на элементе <canvas> . Выполнение какого-либо кода при выводе каждого кадра выполняется с помощью механизма requestAnimationLoop() . Прежде чем мы выведем что-либо в элемент <canvas> , нам нужно удалить с него то, что было на нём раньше, очистив его. Затем мы можем предложить clmtrackr выполнять вывод графики прямо на элемент <canvas> .Вот код, реализующий то, о чём мы только что говорили. Добавить его надо ниже команды ctrack.init() :
Теперь вызовем функцию trackingLoop() в функции onStreaming() сразу после ctrack.start() . Эта функция будет сама планировать собственный перезапуск в каждом кадре.Обновите страницу и посмотрите в веб-камеру. Вы должны увидеть зелёную «маску» вокруг лица в окне видео. Иногда для того чтобы система правильно распознала лицо, нужно немного подвигать головой в кадре. Результаты распознавания лица Выявление области изображения, содержащей глаза Теперь нам нужно обнаружить прямоугольную область изображения, в которой находятся глаза, и поместить её на отдельный элемент Решим, что глаза — это прямоугольная часть изображения, границы которой касаются точек 23, 28, 24 и 26, расширенная на 5 пикселей в каждом направлении. Этот прямоугольник должен включать в себя всё, что для нас важно, если только пользователь не слишком сильно наклоняет голову. Теперь, прежде чем мы сможем воспользоваться этим фрагментом изображения, нам нужен ещё один элемент <canvas> для его вывода. Его размеры будут равны 50x25 пикселей. Прямоугольник с глазами будет вписан в этот элемент. Небольшие деформации изображения — это не проблема.Добавьте в HTML-файл этот код, описывающий элемент <canvas> , в который попадёт та часть изображения, на которой имеются глаза:
Следующая функция вернёт координаты x и y , а также ширину и высоту прямоугольника, окружающего глаза. Она, в качестве входных данных, принимает массив positions , полученный от clmtrackr. Обратите внимание на то, что каждая координата, полученная от clmtrackr, имеет компоненты x и y . Эту функцию надо добавить в main.js :
Теперь, в каждом кадре, мы собираемся извлекать из видеопотока прямоугольник с глазами, обводить его красной линией на элементе <canvas> , который наложен на элемент <video> , а затем копировать его в новый элемент <canvas> . Обратите внимание на то, что для того, чтобы правильно выявить нужную нам область, мы будем рассчитывать показатели resizeFactorX и resizeFactorY .Замените следующим кодом блок if в функции trackingLoop() :
Перезагрузив теперь страницу, вы должны увидеть красный прямоугольник вокруг глаз, а то, что содержит этот прямоугольник — в соответствующем элементе <canvas> . Если ваши глаза больше моих — поэкспериментируйте с функцией getEyeRectangle .Элемент <canvas>, выводящий прямоугольник, содержащий изображение глаз пользователя Сбор данных Существует много способов сбора данных. Я решил использовать информацию, которую можно получить от мыши и клавиатуры. В нашем проекте сбор данных выглядит так. ?Отслеживание перемещений мыши Для того чтобы узнать, где именно на веб-странице расположен указатель мыши, нам понадобится обработчик события
?Захват изображений Для захвата изображения, выводимого элементом
Обратите внимание на то, что функция tf.tidy() используется для того, чтобы навести порядок после завершения работы.Мы могли бы просто сохранить все образцы в одной большой обучающей выборке, однако в машинном обучении важно проверять качество обучения модели. Именно поэтому нам надо сохранить некоторые образцы в отдельной контрольной выборке. После этого мы можем проверить поведение модели на новых для неё данных и узнать, не произошло ли чрезмерного обучения модели. Для этой цели 20% от общего количества образцов включены в контрольную выборку. Вот код, который используется для сбора данных и формирования выборок:
И, наконец, нам надо привязать эту функцию к клавише Пробел :
Теперь каждый раз, когда нажимают на клавишу Пробел , изображение глаз и координаты указателя мыши добавляются в один из наборов данных.Обучение модели Создадим простую свёрточную нейронную сеть. TensorFlow.js предоставляет для этой цели API, напоминающее Keras. У сети должен быть слой
Прежде чем приступать к обучению сети, мы задаём фиксированное количество эпох и переменный размер пакета (так как мы, возможно, будем работать с очень маленькими наборами данных).
Теперь добавим на страницу кнопку для запуска обучения. Этот код идёт в HTML-файл:
Этот код надо добавить в JS-файл:
Куда смотрит пользователь? Теперь, когда мы можем собирать данные и подготовили модель, можно начать предсказывать место на странице, куда смотрит пользователь. Укажем на это место с помощью зелёного кружка, который перемещается по экрану.
Для того чтобы перемещать его по странице, мы периодически передаём текущее изображение глаз нейронной сети и задаём ей вопрос о том, куда смотрит пользователь. Модель в ответ выдаёт две координаты, по которым должен быть перемещён кружок:
Я установил интервал на 100 миллисекунд. Если ваш компьютер не такой мощный, как мой, возможно, вы решите его увеличить. Итоги Теперь у нас готово всё, что нужно для реализации идеи, изложенной в самом начале этого материала. Испытайте то, что у нас получилось. Подвигайте курсором мыши, следя за ним глазами, и понажимайте клавишу Пробел. Потом нажмите кнопку запуска обучения.
Источник: habr.com Комментарии: |
|