23 сентября в 23-59 GMT закончился прием приложений на конкурс Intel Perceptual Computing Challenge. Теперь мы, участники конкурса (в том числе несколько читательов, например еще ithabr), ждем результатов. А результаты будут видимо не скоро — в лучшем случае в середине октября. И чтобы не сойти с ума в процессе ожидания, я решил написать вот этот пост про то, как проходил конкурс и велась разработка с точки зрения нашего конкурсного проекта. Ведь, как известно, если не знаешь что делать — грызи палочку.
Надеюсь другие участники конкурса дополнят мой рассказ своими впечатлениями в комментариях, а то и, чем черт не шутит, в своих постах.
По возможности я постараюсь воздержаться от рекламы/пиара нашего проекта, но поскольку так уж сложилось что я участвовал в разработке именно своего проекта, а в чужих не участвовал, именно про его эволюцию я смогу рассказать больше всего. Надеюсь кому-нибудь будет интересно, а может и полезно.
На всякий случай уточню — это не история успеха. Никто не знает (думаю еще даже судьи не знают) что займет наш проект и займет ли вообще. Вполне возможно, что наше приложение у них просто не запустится из за какой-нибудь мелочи, которую мы не предусмотрели. Не запустится, и оно просто перейдут к следующему кандидату. И, по моему, именно поэтому лучше всего написать статью сейчас, чем потом писать очередную горделивую историю успеха, либо молчаливо не писать историю провала.
Начало
После хакатона мы знали что будет еще и большой конкурс Intel'a на тему того же PerC SDK, и мы уже знали что будем там участвовать. И вот наконец шестого мая объявили о начале конкурса. До 26 июня нужно было подать заявку с описанием идеи. Из списка всех идей организаторы должны были отобрать 750 лучших, и только они допускались к дальнейшему участию в конкурсе.
Идея, как таковая, у нас была в общем то готова. Сформулирована она была еще на хакатоне — это наш проект Virtualens (виртуальный объектив, в переводе с бусурманского). Идея была в том, чтобы решить одну простую проблему возникающую во время видеозвонков (по тому же скайпу например) — иногда на заднем фоне у нас есть что-то (или кто-то) что не очень удобно показывать собеседнику. Ну, там носки на диване разбросаны, или гора немытой посуды, или просто кто-то из домочадцев, например девушка, не хочет чтобы её непричесанную случайно увидели на заднем плане во всех подробностях, или наоборот, если вы девушка, это может быть парень в семейниках, которого маме во время видеозвонка лучше не показывать в мелких частностях.
Поскольку камера работающая с PerC SDK (Creative senz3d, но обещают и другие модели) выдает не только картинку, но и информацию по глубине (depth map), то решение напрашивалось само собой — будем эмулировать эффект малой глубины резкости камеры, то есть четким остается только то, что находится на заданном расстоянии от камеры, а все что дальше от нее — размывается (в реальности и то что ближе — размывается тоже, и мы даже реализовали это, но потом отказались — это лишь создает дополнительные неудобства для пользователя).
Алгоритмы
У нас была даже какая-то реализация-прототип, что мы накодили на хакатоне. И было понимание что там еще море работы. Так что я взял на весь июнь отпуск, и весь отпуск занимался алгоритмами. А заняться было чем. Например дырками в depth map после отображения его на rgb-картинку (см. стартовую картинку поста — эта зелень там не просто так, это все точки информация о глубине которых отсутствует).
Появление точек, с неизвестной глубиной, имеет несколько причин:
- Расстояние до некоторых точек столь далеко, что камера просто до них не просвечивает своим «ИК-фонариком»
- До некоторых точек наоборот либо слишком близко, либо материал там блестящий, либо вообще солнышко с той стороны, так что тут мы имеем засветку, и информацию о точке опять не знаем
- На картинке видна тень на шторе от руки. Она возникает из за того, что «ИК-фонарик» и объектив камеры находятся не в одной и той же точке. В точности такой же эффект можно наблюдать при съемке с мобильника со встроенной вспышкой
- Ну и наконец главное и самое злобное — артефакты натягивания depth map на rgb — угол поля зрения у rgb-камеры и depth-камеры разный. Соответственно при попытки совместить картинки получаем примерно то же, что и если попробовать обернуть шар плоским листком бумаги — не обернется, придется его резать на кусочки и склеивать потом. Вот картинка и «растрескалась». (можно конечно это делать аккуратней, с интерполяцией и так далее, но штука в том, что это все нужно делать очень быстро, если в PerC SDK будет вместо текущего какой-то другой замечательный алгоритм который будет это делать идеально, но грузить процессор и выдавать 10 fps, это будет никому не нужно)
Я читал всевозможные исследования по тематике, смотрел классические inpaint алгоритмы. Скажем алгоритм Telea для данной задачи не годился совершенно из за производительности. В результате удалось написать эвристический алгоритм, который неплохо подходит под нашу задачу (но не является решением в общем случае).
Подача заявки
Организаторы конкурса в последний момент преподнесли сюрприз. Приятный. Срок подачи заявки отодвинули на неделю (1 июля). Так что не только я успел алгоритмы причесать, но и мы успели все это реализовать до состояния технодемо, отснять и «смонтировать» даже ролик с демонстрацией, но без звука. Получилось такое:
Тут у нас еще реализация с размытием и того, что слишком близко к камере.
Начали появляться на ютубе и видео заявок других участников. Вот например, по моему, классная идея/демка:
Финалисты
Результаты отбора заявок стали известны только 12 июля. То есть через 12 дней после подачи. Финалистам должны были выслать камеры. У нас камера одна уже был (по результатам хакатона), но еще одна камера была все же нужна — нас было двое, а камера одна. Кроме того, второй экземпляр камеры был важен еще потому, что нужно было оценить каков разброс калибровки камер. Дело в том, что на имевшейся у нас камеры была проблема — после отображения depth на rgb результат был смещен (см. картинку — зеленые точки, это depth-данные соответствующие руке). И было не понятно — это у всех камер так, или же у всех будет по разному? Для нашей задачи это было критично, хотя для многих других — нет.
Пока ждали камеру, мы решали еще две задачи.
Во-первых нужно было таки не только уметь размывать изображение где надо и не размывать где не надо, нужно было еще этот видеопоток как-то доставить в приложение (скажем Skype). То есть нужно было прикинуться камерой. После экспериментов, было решено остановиться на создании DirectShow source фильтра. Увы, Microsoft выпилила в Metro-приложениях доступ к DirectShow, теперь там MediaFoundation, а в Media Foundation прикинуться камерой для чужого приложения уже нельзя. Для поддержки Metro нужно создавать уже полноценный драйвер, что сложнее. Поэтому мы решили отказаться от поддержки Metro в версии программы для конкурса — больше шансов успеть довести приложение до ума к сроку.
Во-вторых мы искали кого-то кто был бы не программистом, а наоборот. То есть дизайнером/креативщиком, кто-то, кто понимал бы в человеческом а не в программинговом. Ибо нам нужны были иконки, нужен был минимальный, но аккуратный интерфейс, нужно было снимать видео и так далее. Ах, да, нужно было еще говорить вменяемо по английски, чтобы озвучить оное видео. И после десяти дней поиска такого человека найти таки удалось!
Таким образом теперь у нас команда доросла до трех человек:
- Надя — программист GUI, знаток шарпа, и вообще умница-красавица
- Творец Алексей — это он помог с дизайном UI, это он нарисовал картинки и иконки, снял и смонтировал видео, и это его голос вы услышите во всех англоязычных наших роликах
- Ваш покорный слуга, valexey — алгоритмы и всякое системное, а также проектно-идеалогическое
Одновременно с этим приехала и долгожданная камера.
Разработка
На радостях что у нас наконец то появился человек, который знает каким концом держать фотошоп, мы начали придумывать варианты иконок для нашего приложения (самое важное в программе, ага, особенно когда до дедлайна остается месяц а еще ничего не готово, хотя это мне сейчас понятно что тогда было ничего не готово, а тогда то казалось что все уже почти готово! ). Было опробовано штук наверно 10 вариантов, и потрачено что-то около недели. А потом мы её засунули в system tray (где она и должна находиться — при использовании нашей виртуальной камеры в system tray'e живет приложение через которое можно что-то там быстро настроить, если не хочется пользоваться жестами) и поняли что оно ну никак не смотрится. Так что пришлось переделывать еще раз.
Затем мы начали придумывать интерфейс для программы. Понятно что в основном пользователь интерфейса видеть не будет — он работает со Skype, или там еще каким Google Hangouts, настраивает параметры Virtualens в основном жестами, но иногда… например в первый раз, он зайдет таки в диалог настроек, где можно включить и выключить жесты, ну и настроить расстояние начиная с которого нужно размывать, и силу размытия (хотя эти два параметра как раз удобней жестами настраивать). Кроме настроек этот диалог должен был также играть обучающую роль — подсказывать какие именно жесты работают, как их выполнять. Жесты простые, но люди пока к ним не привыкли, и хотя бы первый раз пользователю неплохо бы увидеть как кто-то это делает правильно.
Еще была идея о том, как же показать что такое сила размытия и чем она от расстояния отличается. Был придуман и даже реализован GUI-компонент для этого, изображавший одновременно и зависимость размера ядра свертки (сила размытия) от расстояния от камеры, и пример того, как именно картинка будет размыта вот в этой комбинации. Но после того как несколько человек совершенно по разному интерпретировали то, что этот компонент показывал, было решено от него отказаться. Слишком… хм… математично получилось.
В итоге было решено максимально GUI упростить, сделать его вид максимально нативным (для GUI использовались WinForms, по умолчанию они смотрятся не нативно, пришлось слегка повозиться) и легковесным. А для обучения пользователя позаимствовать идею у apple, из диалога настроек Trackpad'a — с проигрыванием видеодемонстраций жестов при наведении на соответствующий пункт:
А вот что получилось у нас:
Кнопки «play» добавлены не просто так — они для тех, кто пользуется тачскрином, ведь в этом случае мышкой елозить человек не будет и скорее всего просто не догадается, что туда можно ткнуть чтобы проигрался ролик. А по умолчанию в этом видеоокошке, показывается превью с камеры (уже размытое как надо и где надо).
Калибровка камеры
Приехавшая камера сделала нам грустно. У нее не было (или почти не было) смещений. Это означало что либо ей так повезло, либо в новых камерах все хорошо, но в любом случае это означало, что мы не знаем что будет у пользователя (судьи) — какая камера и с какими смещениями depth относительно rgb. Нужно было думать про калибровку. Причем, видимо, такую, которая бы была максимально простой и дружественной к пользователю. Это было сложно. Это было очень сложно, и грозило похоронить весь проект целиком. То есть сложно не калибровку сделать как таковую, а сделать её так, чтобы любой далекий от техники человек смог её произвести.
К счастью 9 августа состоялась «Сессия Вопросов и Ответов Perceptual Computing Challenge». Да, на русском. С русскими разработчиками из Intel (до того был еще англоязычный вебинар, мне показался он довольно бесполезным). На этой сессии я и задал вопрос про калибровку, и про проблемы. И мне ответили, что да, проблема известна, что это плохо закрепленная матрица старых камер при транспортировке может смещаться, и что скоро они выпустят тулзу для калибровки. То есть эту проблему они берут на себя. Ффух! Мы выдохнули. Спасибо, Intel!
Съемка видео
Дедлайн приближался и нужно было снимать видео про проект и про нас. Для этого мы вооружились Человеком с Камерой и пошли в какую-то студию, которая совсем за недорого, согласна была потерпеть один вечер наше присутствие.
Я никогда не думал что говорить на камеру так сложно. Нет, я давал интервью (в т.ч. на камеру) — это не то. Это вовсе совсем не то. Чтобы записать ролик с внятным рассказом нужно делать много-много дублей. Очень сложно сниматься вдвоем — пока один говорит, другой наверняка посмотрит куда-то не туда.
Но мы отсняли. А потом выкинули и пересняли в другое время и в другом месте и в другом формате, и уже полностью самостоятельно. И уже в сентябре.
Перенос сроков
10 августа, за 16 дней до Окончательного Великого Дедлайна, организаторы сказали что все опять переносится. На 23 сентября. Фактически нам подарили еще один месяц, но не сказал бы что нам этот месяц пошел сильно впрок. Мы немного расслабились. Чуть отдохнули. А потом резко похолодало и немного поболели. Я например безуспешно пытался порваться между основной работой и проектом — и на то и на другое не хватало сил. Полностью забить на то и на другое — тоже было нельзя. В результате и там и там успехи были более чем скромные. Увы.
Но кое-что таки получилось сделать за вторую половину августа и начало сентября. В основном это были не столько программерские свершения, сколько взгляд вокруг, что же аналогичного вообще в мире есть. И было на что посмотреть. Например в Google Hangouts уже есть встроенное размытие или замена фона. Только есть нюанс — когда уходишь из кадра, остается твой прозрачный контур, через который все видно что в комнате творится.
А был обнаружен конкурент еще страшнее — мы обнаружили Personify for Skype. Который убирает задний фон (не размывает), и который идет сразу с камерой. И с которым дружит Intel. Они уже там где мы только мечтаем быть! Он оформлен в виде плагина к скайпу (то-то в беседах Intel'овцы постоянно думали что наш проект это тоже плагин к скайпу! а я то все удивлялся, ибо делать это плагином, ну очень как-то странно, ну и вообще, по идее знание тонкостей плагинной организации у Skype вне компетенции сотрудников Intel'a занимающихся PerC SDK). Однако установка этого приложения показало странное — оно не слишком качественно было оформлено. Причем там в том числе был баг (как они этого добились — я не понял), из за которого во время работы их плагина (а он стратовал сразу после того как стартует скайп, захватывал камеру и грузил процессор моего ноутбука на 70%, то есть это без звонка) невозможно использовать другие PerC SDK приложения использующие depth&rgb одновременно.
В общем. в результате мы не расстроились, а скорее наоборот — получили заряд оптимизма — мы можем быть лучше!
Но основная работа конечно, как всегда, пришлась на последнюю неделю (кто бы сомневался!).
Последняя неделя
Внезапно до дедлайна осталась неделя. А нам нужно было еще переснять видео, нужно было наладить взаимодействие различных компонент, которые крутятся в разных адресных пространствах, нужно было сделать диалог быстрых настроек, сделать установщик и еще тысячу жизненно необходимых мелочей. Главный функционал работает, но без мелочей оно все не взлетит! Впрочем были и не мелочи, например обнаружилась в GUI не маленькая такая утечка памяти…
Мы в эту неделю работали по 20 часов в сутки.
Мы отработали и переработали жесты. Изначально предполагалось что входить в режим настроек камеры пользователь будет хлопком в ладоши перед объективом камеры. Оказалось что это очень неприятно для собеседника. Поэтому мы перешли на комбинацию жестов — теперь пользователь должен вначале сделать жест V (например он на картинке в начале поста), на превью появляется значок Virtualens, подтверждающий что жест распознался, после этого нужно просто помахать ему рукой. Получилось очень интуитивно — вначале обращаемся к Virtualens, показывая первую букву названия на пальцах, затем машем ему рукой. Выход из настроек — все тот же V, только рукой махать не надо уже.
Сделали отключение изображения камеры если пользователь закрыл её рукой — вместо того, чтобы искать где же там у скайпа кнопка отключения видео, просто закрываем объектив рукой и идем решать свои проблемы.
Мы сняли видео сами, на этот раз на улице, и смонтировали. Мы выловили и придавили жуткую тучу багов (сколько же мы их добавили кодя в таком темпе?!). Мы сняли видео для демонстрации жестов. Надя от съемок на улице заболела — простудилась. За сутки до дедлайна в ночь она сказала — «все равно от кашля я не засну до утра, зато проект доделаю!», и таки доделала — решила за эту ночь две очень злобные проблемы, которые внезапно вылезли. А на следующий день её положили в больницу.
Мне очень помогла моя сестра с инсталлятором — она сделала основную работу, мне осталось лишь подправить в инсталляторе некоторые детали.
За 2 часа до дедлайна у меня было вроде бы все готово (на самом деле потом оказалось, что не все). Ждали лишь когда финал видео будет смонтирован с английской озвучкой, и отрендерен. Жду. Остается час до дедлайна. Жду. Остается 30 минут — начинаю лихорадочно самостоятельно накладывать англоязычные сабы на видео. Без 15ти дедлайн звоню Алексею, спрашиваю что там. А там, оказывается, он поставил на рендер, рендерится оно минут 20… и его вырубило на месте — он заснул! У людей есть предел прочности. Но мы успели. Без 4 минут дедлайн все было отправлено.
Успели.
Итоги
По итогам я забыл в ридмишку, в описание проекта, написать что нужно перезапустить скайп после установки. Добавили в описание видео на ютубе, но не факт что это кто-то заметит. Теперь меня мучает кошмар — установщик судьи запустили, пункта Virtualens среди камер в скайпе не появилось, удалили, перешли к следующему проекту.
Я не знаю, мы не знаем какие будут результаты конкурса. Даже предположить не можем. Но знаем что он уже окупился — окупился опытом. Я не знал что могу настолько продуктивно работать (пусть и всего несколько дней). Этот конкурс послужил эдаким бенчмарком наших способностей. Впрочем, на конкурсе наш проект не закончится. Мы сейчас раздали свои камеры нескольким людям, чтобы они потестили нашу программу, ну и Personify for Skype. Нам нужно понять что у нас так, а что не так, и что нужно еще исправить.
Видео проектов
Наше основное видео:
Думаю видео про то как установить что-то, а потом перезапустить скайп тут никому не интересно. А вот диалог настроек посмотреть живьем думаю будет интересно:
Ну и как настраивать Virtualens если у вашего клиента нет webcam options кнопочки:
Другие проекты: вообще, можно зайти сюда, и смотреть все видео, которые не старее одного месяца — это будут финальные заявки на конкурс.
Также один участник уже прошелся по ютубу и собрал в кучу все найденные проекты (получилось что-то около 110 штук): software.intel.com/en-us/forums/topic/474069
Ну и то, что понравилось конкретно мне:
Мне понравился проект ithabr, но он просил ссылку на его видео не распространять. Так что не буду.
Это вот тоже из России, точнее из Самары:
А вот это — просто магия. В прямом смысле — через PerC SDK создаются заклинания в игре. Можно почувствовать себя магом в полной мере. Прокачивать не абстрактные цифры, а собственную ловкость и плавность рук:
Спасибо всем, кто дочитал эту простыню до конца.
Автор: valexey