Ардуино графический планшет

Изготавливаем графический планшет из вебкамеры своими руками

Причем тут веб-камера к планшету, скажете вы ? А вот и нет — ведь планшет-то у нас будет виртуальный!

Как-то раз, прочитав о Eye toy от Sony [1], я думал о необычных способах ввода данных в компьютер. В этот момент пришла идея попробовать самостоятельно собрать что-то подобное — благо веб-камера была под рукой.

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

Итак, принцип работы. Располагаем в поле зрения камеры белый лист бумаги. Наклеиваем на кончик ручки цветной маркер. Если перемещать ручку по листу бумаги, то, распознавая цвет маркера на картинке, можно получить координаты ручки в плоскости листа. Если эти координаты превращать в движение курсора на экране, мы получим простейший виртуальный планшет.

Ручка с цветным маркером

Для стабильного распознавания необходимо, чтобы отслеживаемый цвет значительно отличался от фона картинки. Кроме того, этот цвет должен быть насыщенным. Наилучшее, что нашлось под рукой – стикеры, используемые для наклеивания цен на товары. Ярко зеленый цвет отлично контрастирует с фоном картинки.

Берём обычную шариковую ручку.

Берем один стикер, и отрезаем тонкую полоску.

Полоску наматываем на стержень ручки.

Наш «стайлус» готов ! На картинке видно, что насыщенный цвет буквально «горит», и потому будет стабильно распознаваться нашей программой. Наша ручка не имеет датчика нажатия, поэтому пользователь должен будет использовать какую-либо клавишу клавиатуры, например – левый Ctrl.

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

В качестве языка программирования возьмем Delphi, т.к. для него легко найти готовые компоненты для работы с веб-камерой и ком-портом (об этом дальше), и легко делать пользовательский интерфейс. Но, прежде чем запускать редактор, обсудим алгоритмы.

С камеры мы получаем картинку в формате RGB (красный, зеленый, синий). Имея эти данные, мы должны распознать положение (координаты) маркера на картинке. У меня не было желания разбираться со сложными алгоритмами распознавания образов, и поэтому я взял простейший алгоритм: в цикле пройтись по всем пикселам картинки, выбрать из них те, цвет которых похож на цвет маркера, и найти средние координаты этих точек (X,Y).

Сравнивать цвета лучше в пространстве YUV (Y — яркость, UV – цвет), игнорируя яркость (Y). Это для того, чтобы условия освещения не влияли на стабильность распознавания.

Координаты всех точек, похожих на цвет маркера, нужно сложить и поделить на их количество. Таким образом, получим средние координаты, которые и будут положением нашего маркера на картинке.

, где n — количество похожих точек.

Итак, первая версия нашего «драйвера» уже умеет определять координаты маркера на картинке. Однако, координаты на картинке — это еще не координаты на листе бумаги, т.к. лист занимает не всю площадь картинки. Во-вторых, лист расположен под наклоном к плоскости изображения.

Для перевода координат маркера на картинке в координаты на листе бумаги, нам необходимо знать координаты углов листа бумаги на картинке. Для этого просто попросим пользователя «откалибровать» наш виртуальный планшет – кликнуть в углах листа бумаги.
После «калибровки» мы получаем четыре пары координат (x1,y1, x2,y2, x3,y3, x4,y4) на картинке, которые соответствуют углам листа бумаги. Теперь нужно вывести соотношение, которое позволит нам переводить координаты на картинке (x,y) в координаты на листе бумаги (X,Y). По началу, я долго не мог придумать, как это сделать, но потом все же удалось найти решение.

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

Поскольку нас не интересуют реальные размеры в пространстве, а только относительные координаты на листе бумаги, мы можем принять любые координаты, лежащие в трехмерной плоскости. Я выбрал указанные, чтобы получать на выходе координаты X и Y в диапазоне [0..1].

Из курса трехмерной графики мы знаем, что для создания двумерного изображения из трехмерной модели, координаты трехмерных точек умножаются на локальную матрицу объекта и на матрицу камеры:

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

, где f – фокусное расстояние.

Подставляем (1) в (2), и расписываем умножение матрицы на вектор:

, где — элементы суммарной матрицы .gif

Опять же, поскольку нас интересуют только соотношения, фокусное расстояние можно опустить и считать, что оно включено в элементы матрицы , находящиеся в числителе.
Перемножим и распишем (3):

Выразим X,Y (координаты на листе бумаги):

Имея формулы (4), мы может получать координаты на листе бумаги (X,Y) из координат на картинке (x,y). Координаты на листе бумаги будут в диапазоне [0..1] , и останется просто помножить их на разрешение экрана, чтобы получить требуемое положение курсора.

Как найти элементы матрицы для формулы (4)? Нам известны трехмерные координаты углов бумаги ( — приняты ранее) и их координаты на картинке ( — получены при калибровке). Нужно подставить их в формулы (4) и решить полученную систему уравнений.

Мы получаем систему линейных уравнений, которую можно расписать в матричном виде как:

Я дополнил матрицу A нулями снизу, чтобы она получилась квадратной.
Мы получили 8 уравнений и 9 неизвестных. Для нахождения 9 неизвестных недостаточно 8 уравнений. Но мы знаем, что точки (X,Y,Z) лежат в плоскости, и потому линейно зависимы. То есть на самом деле уравнений больше, чем неизвестных, и значит, система имеет решение. Просто скажу, что такие системы уравнений решаются с помощью сингулярного разложения матрицы, которое рассматривать здесь не буду, т.к. наверняка уже и так утомил :).

Усложняем аппаратную часть

Итак, мы уже можем рисовать с помощью нашего планшета! Однако, стабильность распознавания сильно зависит от условий освещения, да и пользоваться клавишей Ctrl для нажатия не очень удобно. Давайте соберем «продвинутый стилус» для нашего планшета.
Чтобы повысить стабильность, я решил поместить на кончик ручки зеленый светодиод. Теперь стабильность распознавания практически не зависит от освещения. В качестве датчика нажатия я взял микропереключатель из старой мышки.

Берем старую шариковую ручку диаметром 1см.

Берем старую COM-мышку.

Из мышки нам понадобится провод с разъемом и микропереключатель.

Микропереключатель вставляем в ручку так, чтобы при надавливании, стержень ручки его включал.

Берем зеленый светодиод. Я немного подпилил его с краев, чтобы сделать меньше.

Приклеиваем светодиод на кончик ручки. Я обернул светодиод фольгой с боков. Теперь в темноте вокруг светодиода не создается ореол, и стабильность распознавания улучшается.

Паяем все по приведенной схеме. Смысл состоит в следующем: светодиод запитывается от сигнальных линий СОМ-порта и постоянно горит. Микропереключатель замыкает цепь приема-передачи, и, таким образом, в нажатом состоянии программа получает «эхо» от посланных данных. Это можно проверить, запустив HyperTerminal и набрав несколько символов на консоли. Когда выключатель отжат — символы не отображаются. Когда нажат — введенные символы передаются терминалом, принимаются обратно и отображаются на консоли.

После сборки у вас должно получиться что-то подобное.

О настройке программного обеспечения

Я постарался сделать ПО с максимально понятным интерфейсом в форме Мастера.
Сразу после запуска, ПО пытается соединиться с веб-камерой и требует калибровки. Остановлюсь отдельно на некоторых страницах Мастера.

На экране выбора веб-камеры необходимо выбрать камеру (Кнопка «Источник…») и формат изображения («Формат…»). Если у вас в системе два устройства видеоввода, например — на видеокарте есть видеовход, то нужно правильно выбрать источник. В настройках формата необходимо выбрать один из следующих форматов: I420, IYUV, UYVY. С другими форматами ПО не работает. Здесь следует также отметить, что при более высоком разрешении веб-камеры часто дают в 2-3 раза ниже FPS, так что, возможно, придется пожертвовать разрешением в пользу скорости реакции. При правильной настройке, в левое окно должно поступать изображение с камеры.

На экране настройки цвета слежения необходимо подобрать параметры «Разброс», «Чувствительность» и цвет слежения такие, чтобы в левой картинке за кончиком ручки четко следовал красный крестик.

Нужно начать с параметра «Чувствительность». Установите его таким, чтобы в правом окне отчетливо выделятся цветом наш маркер. Кликните курсором мыши на изображении маркера в правом или левом окне. Программа запомнила требуемый цвет, и начинает собирать похожие точки. Количество похожих точек отображается под меткой «Samples count:». В левом окне похожие точки помечаются розовым цветом. Необходимо подобрать параметр «Разброс» таким образом, чтобы количество похожих точек примерно равнялось пятидесяти. Возможно, придется отрегулировать размер цветного маркера на кончике ручки и убрать посторонние предметы из поля зрения камеры.

Надеюсь, что остальные экраны Мастера не вызовут вопросов. После завершения Мастера, наш «драйвер» сидит в трее. Включать/выключать планшет также можно клавишей «Scroll lock» клавиатуры.

Думаю, что если у вас когда-нибудь возникало желание купить себе какой-нибудь дешевенький планшет «для поиграться», то для этих целей вам вполне хватит виртуального. Ведь все, что нужно — это закрепить камеру, наклеить маркер на кончик ручки, установить ПО — и планшет готов.

Как вариант, можно рисовать лазерной указкой (или брелком) на стене. Веб-камеру также можно заменить цифровым фотоаппаратом, подключенным к видеовходу видеокарты. Лично я пробовал с Canon A70 + видеовход на GeForce 4 TI4200, а также фотоаппарат Agfa CL20 в режиме веб-камеры.

Я не зря назвал этот планшет «игрушкой». Ему никогда не сравниться с профессиональными планшетами типа Wacom из-за низкого разрешения (а оно примерно на 50% меньше разрешения веб-камеры), а также задержки, возникающей из-за задержки видеосигнала при оцифровке. Для сравнения скажу, что планшет Wacom Intuos работает в разрешении не меньше 1024×768, распознает 512 степеней нажатия и наклон ручки. Кроме того, многие камеры меняют баланс белого при изменении условий освещения, из-за чего цвет слежения изменяется и вызывает проблемы со стабильностью распознавания.

Источник

CameraTablet — как сделать графический планшет при помощи веб-камеры

Здравствуйте, меня зовут Дмитрий. Здесь я хочу рассказать о том, почему меня не устраивает мышка, и как я пытаюсь ее заменить. Я разрабатываю CAE-программы для инженеров (расчет статики и динамики механических систем), треть рабочего времени я работаю как project manager, а в остальное время я — системный архитектор, разработчик и тестер в своем и в чужих проектах. У меня всегда открыты десять-двадцать окон, между которыми мне приходится постоянно прыгать:

  1. Visual Studio – собственно, софт, обычно три-четыре разных solution
  2. SourceSafe – версионирование.
  3. Outlook
  4. Skype
  5. Total Commander – файлы, файлы.
  6. Internet-Explorer – планирование софта, мониторинг продвижения по проекту, doxygen документация и т.д.
  7. Word, Excel – список задач, протоколы заседаний, требования к проекту, быстрое построение графиков и т.д.
  8. PowerPoint – презентации для менеджмента.
  9. Notepad++ — просмотр промежуточных результатов, конфиги, и т.д.
  10. CAE soft наш – тестовая и основная версия.
  11. CAE soft других фирм – для тестов

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

В итоге весь мой рабочий день – это постоянное метание между мышкой и клавиатурой:

  • Мышка: открыть документ, пролистать,
  • Клавиатура: написать три-четыре строчки.
  • Мышка: нажать на кнопку, переместиться в другую программу, нажать на кнопку
  • Клавиатура: в появившемся окне написать 2-3 значения.
  • Мышка: отрыть другое окно. Нажать на кнопку. Выбрать пункт меню. Потом пункт в под-меню. Потом в под-под-меню. Клик! Новое окно!

В один прекрасный момент моя правая рука сказала: «Извини, хозяин, но что-то нагрузка для меня великовата». Кисть болела почти два месяца, сначала слабо, потом все сильнее. В итоге я купил вертикальную мышку, выучил побольше шорткатов в Visual Studio и перешел на Total Commander.

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

Ни одна из стандартных альтернатив мышке мне не нравится: PointStick (пипка в центре клавиатуры для ноутбуков), тачпад, графический планшет – у всех либо точность плохая, либо все равно надо дергать руку с клавиатуры.

Есть еще программы и железо для трекинга глаз, вроде Camera Mouse или Tobii Eye Trackers. Честно, тратить сотню баксов на Tobii Eye Tracker не хотелось, а Camera Mouse очень плохо распознавало положение глаз (подозреваю, что виноваты мои очки).

Программа CameraTablet

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

Как сделан CameraTablet

Писать программу я решил в Python, якобы на этом языке очень быстро можно разрабатывать прототипы. Самое забавное, что в итоге CameraTablet получилась очень небольшим. Больше всего времени понадобилось, чтобы понять, как opencv распознает образы. Плюс немного пришлось повозиться, чтобы найти нормальный скрипт для эмуляции мыши. В остальном благодаря массе библиотек на Python удалось довольно быстро сделать все, что хотелось. Что мне понадобилось в итоге:

  1. opencv
    • распознавание пальца на видео
    • сохранение файла с фотографией пальца
    • калибровка камеры
  2. keyboard – обработка горячих клавиш
  3. TkInter — пять кнопок для GUI.

Единственная более-менее математическая проблема с которой я столкнулся – как вычислить позицию курсора на экране, если известно расположение пальца. Палец перемещается внутри неравностороннего четырехугольника, а курсор движется внутри прямоугольного экрана. Так что проблема сводится к проекции произвольного четырехугольника на прямоугольник. Получилось, хоть и не с первой попытки, но довольно неплохо.

Что дальше

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

Фич, которых на данный момент нет, но которые очень хочется сделать:

  1. Поддержка нескольких мониторов
  2. Эмуляция MouseDown und MouseUp (необходимо для выделения текста)
  3. Поддержка Linux

И тут наступил самый тяжелый момент, когда самое вкусные 20% дела уже сделаны, а в одиночку дальше пилить 80% не хочется. Тогда я и решил, что пришла пора все выложить на GitHub, благо я давно мечтал сделать что-нибудь open source. Буду очень рад, если кто-нибудь захочет принять участие проекте (тестирование, программирование, документация – все, что угодно). И, конечно, было бы интересно послушать мысли на тему интерфейсов человеко-машинных интерфейсов вообще и альтернативы мышам в частности.

Источник

Arduino графический планшет

Дигитайзер на arduino uno

Предисловие

В данной статье я хотел бы поделиться своим опытом работы с сенсорным дисплеем и ардуино уно с аппаратной стороны и с Node.js с программной стороны компьютера.
Однажды мне стало интересно, как же рисуют профессиональные дизайнеры и художники в 21 веке, и я обнаружил, что сегодня цифровые изображения и рисунки создают с помощью цифрового планшета, да не простого, а специального, с чувствительностью к нажатиям и углом стилуса. Так появилась идея создать собственный «дигитайзер». Так как я веб разработчик, то соответственно на стороне ПК я решил использовать веб технологии, но с таким же успехов можно использовать все что угодно. Я расскажу и покажу как передавать на арудуино через serial port данные в простом и удобном формате JSON.

Аппаратная часть

Нам потребуется:

  • Arduino UNO
  • Touch TFT LED display 320 x 480 ( или меньшее, так как максимальное разрешение для 32 кбайт памяти Ардуинки)

Экран с 9.7 см x 6.9 см , 3.95 дюйма был заказан на aliexpress. Обрабатывает также силу нажатия, что мы потом будем использовать для отрисовки. Занимает все порты, так что если нужны будут, то придется параллелить и так красиво на ардуино не «встанет» . Экран заточен под арудино, поэтому он легко становится, из-за высокого разрешения, он занимает все пины.

Необходимые библиотеки для работы с дисплеем и тачем:

  • Adafruit-GFX-Library
  • MCUFRIEND_kbv
  • TFTLCD
  • Touch-Screen-Library

Находятся они быстро и легко на Github. После скачивания, папки с библиотеками нужно поместить в Arduino/ibraries.Вообще хорошей документации я так и не нашел, поэтому пришлось тянуть по кусочку с различных примеров и смотреть исходники. В конце статьи будет ссылка на исходники, где также можно найти эти библиотеки.

Основная идея состоит в том, что в левом углу мы отрисовываем 6 квадратов цветов, при нажатии на которые выбирается соответственный цвет. При касании «рабочей» области рисуем круг с радиусом в зависимости от силы нажатия. При очень сильном нажатии — чистим экран. При каждом касании экрана формируем json и отправляем его на ПК.

Собственно код основной функции с комментариями(весь код прикреплен файлом и его можно найти по ссылке в репозитории):

Собственно с аппаратной частью покончено. Как оно выглядит

ПК часть

На ПК будет слушать Node.js сервер, который по вебсокету будет передавать наш json в браузере, где будет собственно происходить рендеринг картинки.
На фронтэнд части используется React и библиотека Paper.js. В качестве сборщика используется Webpack. Но обо всем по порядку.

Серверная часть (node.js):

Необходимые зависимости хранятся в файлике package.json

Для установки зависимостей нужно ввести npm i.

Для транспортировки данных будет использоваться прекрасная библиотека Socket.io https://www.npmjs.com/package/socket.io , которая создает вебсокет, благодаря которому можно транспортировать данные в реальном времени, не используя модель запрос-ответ.
Для чтения из порта будет использоваться serialport https://www.npmjs.com/package/serialport
Остальные библиотеки больше относятся к экосистеме и фреймворку express https://www.npmjs.com/package/express , которые используются для удобства, без которых вполне можно обойтись.

Основная логика серверного скрипта server.js

В принципе все достаточно просто и очевидно. Никакой особенной логики тут нету. Запускается командой node server.js. (До этого необходимо собрать клиентскую часть)

Клиентская часть (React,Webpack,Paper.js):

Начнем с зависимостей:

Я решил использовать библиотеку React.js https://facebook.github.io/react/ , на которой построен Facebook из-за гибкости и многих готовых компонентиков, из которых легко собрать свой интерфейс. В данном проекте React далеко не обязателен, можно было бы и обычным скриптом все сделать, но у меня была заготовка, которую я решил использовать. Реакт нужен для начальной настройки и каркаса приложения, всю логика отрисовки ложится на библиотеку Paper.js http://paperjs.org/

Отдельно хочу рассказать про сборщик для фронтэнда webpack https://webpack.github.io/ . Суть его в том, что к нему подключаются различные загрузчики контента (css, images, files, json, js) которые загружают картинки, таким образом можно разбить логику на странички. Допустим страница главная home, которая состоит из картинок, стилей и нашего скрипта , который генерирует из всего этого один большой скрипт. если глянуть на приведенный выше package.json, то можно увидеть в разделе scripts 3 команды: test, dev, deploy. Test не интересная, а вот deploy собирает все странички, все скрипты и картинки в один большой скрипт, html, стили и картинки в одно место, которое потом отдает сервер любому подключенному клиенту(браузеру). Команда dev используется для разработки очень удобная: webpack создает фактически сервер, который смотрит и анализирует на изменение кода, автоматические собирает все и обновляет страницу браузера, таким образом не нужно каждый раз обновлять страницу и собирать проект.

webpack.config.js:

Также забыл упомянуть, что использую Babel для фишек ES6/7, которые пока что не поддерживают браузеры. Этот конфиг нужен для разработки.

Все клиентские скрипты описывать не буду, так как они выходят за рамки проекта, остановлюсь только на основном.

dashboard.jsx

Для человека незнакомого с React’ом выглядит достаточно запутанно, но основные моменты, на которых строится вся логика закомментированы. Открываем вебсокет -> получаем порты -> выбираем порт -> получаем данные -> отрисовываем.

Команды для запуска:

$ cd frontend
$ npm run deploy
$ cd api
$ node server.js
Для разработки на фронтенде:
$ npm run dev

Демонстрация работы

+

Источник

CameraTablet — как сделать графический планшет при помощи веб-камеры

Здравствуйте, меня зовут Дмитрий. Здесь я хочу рассказать о том, почему меня не устраивает мышка, и как я пытаюсь ее заменить. Я разрабатываю CAE-программы для инженеров (расчет статики и динамики механических систем), треть рабочего времени я работаю как project manager, а в остальное время я — системный архитектор, разработчик и тестер в своем и в чужих проектах. У меня всегда открыты десять-двадцать окон, между которыми мне приходится постоянно прыгать:

  1. Visual Studio – собственно, софт, обычно три-четыре разных solution
  2. SourceSafe – версионирование.
  3. Outlook
  4. Skype
  5. Total Commander – файлы, файлы.
  6. Internet-Explorer – планирование софта, мониторинг продвижения по проекту, doxygen документация и т.д.
  7. Word, Excel – список задач, протоколы заседаний, требования к проекту, быстрое построение графиков и т.д.
  8. PowerPoint – презентации для менеджмента.
  9. Notepad++ — просмотр промежуточных результатов, конфиги, и т.д.
  10. CAE soft наш – тестовая и основная версия.
  11. CAE soft других фирм – для тестов

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

В итоге весь мой рабочий день – это постоянное метание между мышкой и клавиатурой:

  • Мышка: открыть документ, пролистать,
  • Клавиатура: написать три-четыре строчки.
  • Мышка: нажать на кнопку, переместиться в другую программу, нажать на кнопку
  • Клавиатура: в появившемся окне написать 2-3 значения.
  • Мышка: отрыть другое окно. Нажать на кнопку. Выбрать пункт меню. Потом пункт в под-меню. Потом в под-под-меню. Клик! Новое окно!

В один прекрасный момент моя правая рука сказала: «Извини, хозяин, но что-то нагрузка для меня великовата». Кисть болела почти два месяца, сначала слабо, потом все сильнее. В итоге я купил вертикальную мышку, выучил побольше шорткатов в Visual Studio и перешел на Total Commander.

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

Ни одна из стандартных альтернатив мышке мне не нравится: PointStick (пипка в центре клавиатуры для ноутбуков), тачпад, графический планшет – у всех либо точность плохая, либо все равно надо дергать руку с клавиатуры.

Есть еще программы и железо для трекинга глаз, вроде Camera Mouse или Tobii Eye Trackers. Честно, тратить сотню баксов на Tobii Eye Tracker не хотелось, а Camera Mouse очень плохо распознавало положение глаз (подозреваю, что виноваты мои очки).

Программа CameraTablet

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

Как сделан CameraTablet

Писать программу я решил в Python, якобы на этом языке очень быстро можно разрабатывать прототипы. Самое забавное, что в итоге CameraTablet получилась очень небольшим. Больше всего времени понадобилось, чтобы понять, как opencv распознает образы. Плюс немного пришлось повозиться, чтобы найти нормальный скрипт для эмуляции мыши. В остальном благодаря массе библиотек на Python удалось довольно быстро сделать все, что хотелось. Что мне понадобилось в итоге:

  1. opencv
    • распознавание пальца на видео
    • сохранение файла с фотографией пальца
    • калибровка камеры
  2. keyboard – обработка горячих клавиш
  3. TkInter — пять кнопок для GUI.

Единственная более-менее математическая проблема с которой я столкнулся – как вычислить позицию курсора на экране, если известно расположение пальца. Палец перемещается внутри неравностороннего четырехугольника, а курсор движется внутри прямоугольного экрана. Так что проблема сводится к проекции произвольного четырехугольника на прямоугольник. Получилось, хоть и не с первой попытки, но довольно неплохо.

Что дальше

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

Фич, которых на данный момент нет, но которые очень хочется сделать:

  1. Поддержка нескольких мониторов
  2. Эмуляция MouseDown und MouseUp (необходимо для выделения текста)
  3. Поддержка Linux

И тут наступил самый тяжелый момент, когда самое вкусные 20% дела уже сделаны, а в одиночку дальше пилить 80% не хочется. Тогда я и решил, что пришла пора все выложить на GitHub, благо я давно мечтал сделать что-нибудь open source. Буду очень рад, если кто-нибудь захочет принять участие проекте (тестирование, программирование, документация – все, что угодно). И, конечно, было бы интересно послушать мысли на тему интерфейсов человеко-машинных интерфейсов вообще и альтернативы мышам в частности.

Источник

Изготавливаем графический планшет из вебкамеры своими руками

Причем тут веб-камера к планшету, скажете вы ? А вот и нет — ведь планшет-то у нас будет виртуальный!

Как-то раз, прочитав о Eye toy от Sony [1], я думал о необычных способах ввода данных в компьютер. В этот момент пришла идея попробовать самостоятельно собрать что-то подобное — благо веб-камера была под рукой.

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

Итак, принцип работы. Располагаем в поле зрения камеры белый лист бумаги. Наклеиваем на кончик ручки цветной маркер. Если перемещать ручку по листу бумаги, то, распознавая цвет маркера на картинке, можно получить координаты ручки в плоскости листа. Если эти координаты превращать в движение курсора на экране, мы получим простейший виртуальный планшет.

Ручка с цветным маркером

Для стабильного распознавания необходимо, чтобы отслеживаемый цвет значительно отличался от фона картинки. Кроме того, этот цвет должен быть насыщенным. Наилучшее, что нашлось под рукой – стикеры, используемые для наклеивания цен на товары. Ярко зеленый цвет отлично контрастирует с фоном картинки.

Берём обычную шариковую ручку.

Берем один стикер, и отрезаем тонкую полоску.

Полоску наматываем на стержень ручки.

Наш «стайлус» готов ! На картинке видно, что насыщенный цвет буквально «горит», и потому будет стабильно распознаваться нашей программой. Наша ручка не имеет датчика нажатия, поэтому пользователь должен будет использовать какую-либо клавишу клавиатуры, например – левый Ctrl.

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

В качестве языка программирования возьмем Delphi, т.к. для него легко найти готовые компоненты для работы с веб-камерой и ком-портом (об этом дальше), и легко делать пользовательский интерфейс. Но, прежде чем запускать редактор, обсудим алгоритмы.

С камеры мы получаем картинку в формате RGB (красный, зеленый, синий). Имея эти данные, мы должны распознать положение (координаты) маркера на картинке. У меня не было желания разбираться со сложными алгоритмами распознавания образов, и поэтому я взял простейший алгоритм: в цикле пройтись по всем пикселам картинки, выбрать из них те, цвет которых похож на цвет маркера, и найти средние координаты этих точек (X,Y).

Сравнивать цвета лучше в пространстве YUV (Y — яркость, UV – цвет), игнорируя яркость (Y). Это для того, чтобы условия освещения не влияли на стабильность распознавания.

Координаты всех точек, похожих на цвет маркера, нужно сложить и поделить на их количество. Таким образом, получим средние координаты, которые и будут положением нашего маркера на картинке.

, где n — количество похожих точек.

Итак, первая версия нашего «драйвера» уже умеет определять координаты маркера на картинке. Однако, координаты на картинке — это еще не координаты на листе бумаги, т.к. лист занимает не всю площадь картинки. Во-вторых, лист расположен под наклоном к плоскости изображения.

Для перевода координат маркера на картинке в координаты на листе бумаги, нам необходимо знать координаты углов листа бумаги на картинке. Для этого просто попросим пользователя «откалибровать» наш виртуальный планшет – кликнуть в углах листа бумаги.
После «калибровки» мы получаем четыре пары координат (x1,y1, x2,y2, x3,y3, x4,y4) на картинке, которые соответствуют углам листа бумаги. Теперь нужно вывести соотношение, которое позволит нам переводить координаты на картинке (x,y) в координаты на листе бумаги (X,Y). По началу, я долго не мог придумать, как это сделать, но потом все же удалось найти решение.

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

Поскольку нас не интересуют реальные размеры в пространстве, а только относительные координаты на листе бумаги, мы можем принять любые координаты, лежащие в трехмерной плоскости. Я выбрал указанные, чтобы получать на выходе координаты X и Y в диапазоне [0..1].

Из курса трехмерной графики мы знаем, что для создания двумерного изображения из трехмерной модели, координаты трехмерных точек умножаются на локальную матрицу объекта и на матрицу камеры:

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

, где f – фокусное расстояние.

Подставляем (1) в (2), и расписываем умножение матрицы на вектор:

, где — элементы суммарной матрицы .gif

Опять же, поскольку нас интересуют только соотношения, фокусное расстояние можно опустить и считать, что оно включено в элементы матрицы , находящиеся в числителе.
Перемножим и распишем (3):

Выразим X,Y (координаты на листе бумаги):

Имея формулы (4), мы может получать координаты на листе бумаги (X,Y) из координат на картинке (x,y). Координаты на листе бумаги будут в диапазоне [0..1] , и останется просто помножить их на разрешение экрана, чтобы получить требуемое положение курсора.

Как найти элементы матрицы для формулы (4)? Нам известны трехмерные координаты углов бумаги ( — приняты ранее) и их координаты на картинке ( — получены при калибровке). Нужно подставить их в формулы (4) и решить полученную систему уравнений.

Мы получаем систему линейных уравнений, которую можно расписать в матричном виде как:

Я дополнил матрицу A нулями снизу, чтобы она получилась квадратной.
Мы получили 8 уравнений и 9 неизвестных. Для нахождения 9 неизвестных недостаточно 8 уравнений. Но мы знаем, что точки (X,Y,Z) лежат в плоскости, и потому линейно зависимы. То есть на самом деле уравнений больше, чем неизвестных, и значит, система имеет решение. Просто скажу, что такие системы уравнений решаются с помощью сингулярного разложения матрицы, которое рассматривать здесь не буду, т.к. наверняка уже и так утомил :).

Усложняем аппаратную часть

Итак, мы уже можем рисовать с помощью нашего планшета! Однако, стабильность распознавания сильно зависит от условий освещения, да и пользоваться клавишей Ctrl для нажатия не очень удобно. Давайте соберем «продвинутый стилус» для нашего планшета.
Чтобы повысить стабильность, я решил поместить на кончик ручки зеленый светодиод. Теперь стабильность распознавания практически не зависит от освещения. В качестве датчика нажатия я взял микропереключатель из старой мышки.

Берем старую шариковую ручку диаметром 1см.

Берем старую COM-мышку.

Из мышки нам понадобится провод с разъемом и микропереключатель.

Микропереключатель вставляем в ручку так, чтобы при надавливании, стержень ручки его включал.

Берем зеленый светодиод. Я немного подпилил его с краев, чтобы сделать меньше.

Приклеиваем светодиод на кончик ручки. Я обернул светодиод фольгой с боков. Теперь в темноте вокруг светодиода не создается ореол, и стабильность распознавания улучшается.

Паяем все по приведенной схеме. Смысл состоит в следующем: светодиод запитывается от сигнальных линий СОМ-порта и постоянно горит. Микропереключатель замыкает цепь приема-передачи, и, таким образом, в нажатом состоянии программа получает «эхо» от посланных данных. Это можно проверить, запустив HyperTerminal и набрав несколько символов на консоли. Когда выключатель отжат — символы не отображаются. Когда нажат — введенные символы передаются терминалом, принимаются обратно и отображаются на консоли.

После сборки у вас должно получиться что-то подобное.

О настройке программного обеспечения

Я постарался сделать ПО с максимально понятным интерфейсом в форме Мастера.
Сразу после запуска, ПО пытается соединиться с веб-камерой и требует калибровки. Остановлюсь отдельно на некоторых страницах Мастера.

На экране выбора веб-камеры необходимо выбрать камеру (Кнопка «Источник…») и формат изображения («Формат…»). Если у вас в системе два устройства видеоввода, например — на видеокарте есть видеовход, то нужно правильно выбрать источник. В настройках формата необходимо выбрать один из следующих форматов: I420, IYUV, UYVY. С другими форматами ПО не работает. Здесь следует также отметить, что при более высоком разрешении веб-камеры часто дают в 2-3 раза ниже FPS, так что, возможно, придется пожертвовать разрешением в пользу скорости реакции. При правильной настройке, в левое окно должно поступать изображение с камеры.

На экране настройки цвета слежения необходимо подобрать параметры «Разброс», «Чувствительность» и цвет слежения такие, чтобы в левой картинке за кончиком ручки четко следовал красный крестик.

Нужно начать с параметра «Чувствительность». Установите его таким, чтобы в правом окне отчетливо выделятся цветом наш маркер. Кликните курсором мыши на изображении маркера в правом или левом окне. Программа запомнила требуемый цвет, и начинает собирать похожие точки. Количество похожих точек отображается под меткой «Samples count:». В левом окне похожие точки помечаются розовым цветом. Необходимо подобрать параметр «Разброс» таким образом, чтобы количество похожих точек примерно равнялось пятидесяти. Возможно, придется отрегулировать размер цветного маркера на кончике ручки и убрать посторонние предметы из поля зрения камеры.

Надеюсь, что остальные экраны Мастера не вызовут вопросов. После завершения Мастера, наш «драйвер» сидит в трее. Включать/выключать планшет также можно клавишей «Scroll lock» клавиатуры.

Думаю, что если у вас когда-нибудь возникало желание купить себе какой-нибудь дешевенький планшет «для поиграться», то для этих целей вам вполне хватит виртуального. Ведь все, что нужно — это закрепить камеру, наклеить маркер на кончик ручки, установить ПО — и планшет готов.

Как вариант, можно рисовать лазерной указкой (или брелком) на стене. Веб-камеру также можно заменить цифровым фотоаппаратом, подключенным к видеовходу видеокарты. Лично я пробовал с Canon A70 + видеовход на GeForce 4 TI4200, а также фотоаппарат Agfa CL20 в режиме веб-камеры.

Я не зря назвал этот планшет «игрушкой». Ему никогда не сравниться с профессиональными планшетами типа Wacom из-за низкого разрешения (а оно примерно на 50% меньше разрешения веб-камеры), а также задержки, возникающей из-за задержки видеосигнала при оцифровке. Для сравнения скажу, что планшет Wacom Intuos работает в разрешении не меньше 1024×768, распознает 512 степеней нажатия и наклон ручки. Кроме того, многие камеры меняют баланс белого при изменении условий освещения, из-за чего цвет слежения изменяется и вызывает проблемы со стабильностью распознавания.

Источник

Adblock
detector