WinkScroll; реализация JavaScript для автоматической прокрутки

В последние годы компьютерное зрение резко эволюционировало и стало широко доступно программистам с открытыми библиотеками, такими как OpenCV. OpenCV предлагает возможности манипулирования изображениями, чтобы извлекать информацию из изображений, такую ​​как классификация объектов, характеристики лиц и позы тела, таким образом, чтобы компьютер видел то, что мы видим в реальном времени, - таким образом, компьютерное зрение. В то же время языки программирования стали намного более мощными инструментами и более простыми в использовании. В настоящее время, например, язык программирования Python делает буквально все, требует небольшого количества кода и работает в любой среде, от огромного облачного сервера Google до картошки в вашем подвале. Своим огромным успехом Python обязан своему очень сильному сообществу, которое производит широкий спектр библиотек с множеством функций и возможностей. Однако недостатком является то, что Python нелегко запустить в браузере, и он обычно запускается на стороне сервера, взаимодействуя с браузером с веб-службами. Следовательно, это может привести к высокой полезной нагрузке и огромным задержкам, особенно когда приходится иметь дело с видеопотоком. Поэтому цель этого проекта - предоставить возможности компьютерного зрения на стороне браузера с использованием существующих JS-библиотек и управлять видеопотоком HTML5 для извлечения информации и реализации функций css (автопрокрутка).

Уровень развития

Существует несколько известных проектов по отслеживанию глаз, о которых мы не будем вдаваться. Вместо этого я хотел бы посоветовать нашим читателям взглянуть на эту статью, в которой сравниваются несколько известных проектов распознавания взглядов. Для нужд этого проекта использовались две библиотеки JavaScript. Face-api.js от Винсента Мюлера использовался для обнаружения лица и извлечения некоторой полезной информации о выражении лица, а также для распознавания положения наших глаз, носа, линии подбородка и т. Д. Библиотека OpenCV, которая известна своими сильными аспектами на Python projects, к счастью, также была преобразована в библиотеку JavaScript (opencv.js) с менее дружелюбной и хорошо документированной средой. Тем не менее, он предоставляет адекватные функции для обработки рамок глаза. И последнее, но не менее важное: проект Антуана Ламе GazeTracking помогает нам окунуться в мир распознавания радужной оболочки глаза, так что его поддержка.

Как это работает

Здесь представлен анализ библиотеки, чтобы лучше понять, как мы собираемся вычесть диафрагму из нашего кадра, и понять, как система поможет нам распознать мигающее движение. Итак, библиотека wink-scroll реализована в следующем порядке:

ОБНАРУЖЕНИЕ ЛИЦА - ›ОБНАРУЖЕНИЕ ОБЪЕКТОВ -› ИЗОЛЯЦИЯ ГЛАЗ - ›ОБРАБОТКА ИЗОБРАЖЕНИЙ -› КАЛИБРОВКА - ›ЦЕНТРОИДА ДИАГРАММЫ

В качестве первого шага создается видеоэлемент в JavaScript через DOM, куда мы загружаем поток веб-камеры. Кроме того, элемент холста помещается поверх видеопотока в абсолютном положении, на котором рисуются оценки face-api для целей отладки. Затем добавляются еще два холста в нижней части видео, где мы собираемся нарисовать глаз и обработанные кадры изображения. Каждый элемент DOM имеет свои параметры CSS, измененные с помощью JavaScript следующим образом:

video.id = “NAME”;
video.width = WIDTH
video.height = HEIGHT
video.style.position = “absolute”;
video.style.top = DISTANCE_T + “px”;
video.style.left = DISTANCE_L + “px”;

Теперь, когда «игровая площадка» настроена, мы можем начать передачу кадра видео в face-api. Мы используем 3 характеристики для сбора информации из API:

  • Обнаружения
  • Выражения
  • Достопримечательности

Мы используем первые две характеристики (обнаружение, выражение) для графического представления, нарисованного на первом холсте. Кроме того, для тестирования мы добавили функцию, которая изменяет цвет фона элемента HTML body при изменении нашего настроения.

Характеристика ориентиров заменяет набор инструментов dlib, который обычно используется python для определения 68 ориентиров лица (показано на рисунке выше) и ранее был обучен ИИ, создав довольно надежную модель, с которой мы можем поиграть. . Этот компонент дает нам доступ к координатам [x, y] 68 ориентиров лица, которые отражают фактическое положение характеристики на кадре камеры. Кроме того, он ранжирует эти характеристики по группам на основе частей лица (например, getLeftEye, getJawline и т. Д.).

Для библиотеки подмигивания и прокрутки мы собираемся использовать компонент leftEye, который на самом деле является правым глазом, поскольку изображение с камеры является зеркальным. GetLeftEye возвращает массив координат x и y ориентиров правого глаза на канале камеры. После этого мы можем обрезать изображение на участке левого глаза на основе ранее извлеченных координат следующим образом:

ctx.drawImage(
  video, start X, start Y // Frame and starting points
  disX, disY, // Area to crop
  0, 0, // Place the result at 0, 0 in the canvas
  canvas2.width, canvas2.height) // Canvas dimensions

где ctx - это контекст canvas2, полученный функцией getContext.

Поскольку будет сложно дать приоритет тому, кого скрипт будет слушать при подмигивании, библиотека предполагает, что в камере присутствует только один человек. Поэтому мы добавляем условие if, чтобы исключить множественные обнаружения, проверяя, равна ли длина массива обнаружений 1. Теперь, когда у нас есть обрезанный глаз, мы можем нарисовать его на холсте2 и продолжить обработку изображения с помощью openCV.

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

let src = cv.imread(‘canvas2’); // read the cropped frame as an image
let dst = new cv.Mat(); // the destination is an empty Mat array
cv.cvtColor(src, src, cv.COLOR_RGBA2RGB, 0); // setting the colorspace to RGB
cv.bilateralFilter(src, dst, 10, 15, 15); // applying bilateral filter

Параметры фильтра (10, 15, 15) взяты из проекта Антуана Ламе и по результатам хорошо приняты для нашего проекта. Src - это рамка глаза, полученная с canvas2, а dst - это результат примененного фильтра, который мы затем собираемся использовать в качестве источника для следующего фильтра.

Кроме того, мы используем функцию размытия, которая также удаляет некоторый шум, поскольку уменьшается толщина краев.

cv.erode(dst, src, M, anchor, 3, cv.BORDER_CONSTANT, DEFAULT_BORDER_VALUE);

Следующее, что нам нужно сделать, это применить к изображению бинарный порог после перехода от цветового пространства RGB к СЕРЫМ. Но для этого нам нужно пороговое значение, которое откалибровано на основе имеющегося у нас кадра. Есть разные параметры, которые влияют на изображение, например, качество веб-камеры и яркость комнаты. Процесс калибровки проходит следующим образом:

Пороговое значение следует принимать как число, которое при применении к фильтру сделает радужную оболочку глаза различимой. Это значение может быть получено путем калибровки отношения черных пикселей к общему количеству пикселей около 0,48, что является ожидаемым значением для среднего глаза. Мы рекурсивно меняем пороговое значение, пытаясь достичь оптимального соотношения радужная оболочка / изображение, и применяем фильтр следующим образом:

cv.threshold(src, dst, threshold, 255, cv.THRESH_BINARY);

Наконец, мы создаем слой контуров форм кадра, с помощью которого мы можем извлечь центроид, который представляет тогда положение / или отсутствие радужной оболочки (закрытые глаза). После некоторого тестирования было замечено, что значения центроида по оси Y, кажется, смещаются вниз, когда глаз закрыт. Но чтобы различать мигание и мигание (закрытие глаз на более длительный период), мы применяем скользящее среднее (с использованием буфера) к значениям центроидов. В результате снижается уровень шума.

Затем мы можем легко определить, закрыт ли глаз, добавив условие if, а затем просто запустить функцию, которая прокручивает вниз все части текста, которые классифицируются как «winkScroll». На последнем рисунке мы показываем созданную нами среду отладки / площадку, которая состоит из: элемент камеры, два полотна для глаза, отладочный текст и прокручиваемый текст справа.

Последние мысли

Этот проект создается впервые? Нет. Однако мы используем технологии, которые широко известны в очень многообещающем программном стеке (HTML5, JavaScript), и мы готовы мотивировать и вдохновлять других ученых на их использование и реализацию. Кроме того, наша библиотека предоставляет веб-браузеру необходимые инструменты для улучшения работы в Интернете для людей с ограниченными возможностями. Компьютерное зрение - многообещающий и развивающийся технологический аспект, особенно с появлением искусственного интеллекта и глубоких нейронных сетей. Представьте себе все безграничные возможности в областях безопасности, розничной торговли, автомобилестроения, здравоохранения, сельского хозяйства, банковского дела, промышленности, образования. Более того, у людей с особыми потребностями будет шанс в будущем улучшить качество своей жизни. Все, что сейчас имеет значение, - это продолжать внедрять функции компьютерного зрения в нашу среду программирования и позволить ученым и программистам творить чудеса, выводя компьютерную логику и понимание окружающей среды на новый уровень.

Вы можете запустить демо-версию wink-scroll здесь или напрямую клонировать / разветвить ее на GitHub здесь. Буду признателен за любые конструктивные отзывы о моем проекте.