Quantcast
Channel: Статьи Intel Developer Zone
Viewing all 156 articles
Browse latest View live

WebAssembly *: первый взгляд

$
0
0

Download WebAssembly article PDF  [PDF 263 KB]

Введение

Эта публикация — первая в серии статей, в которых дается общее представление о WebAssembly (wasm). Этот язык еще не полностью доработан, ожидается немало изменений, но в этой статье вы получите общее представление о текущем состоянии wasm. Мы будем выпускать дальнейшие статьи с описанием изменений по мере их появления.

Цель wasm состоит в повышении производительности JavaScript *. Этот язык определяет новый портативный формат файлов, высокоэффективный с точки зрения размера и времени загрузки, пригодный для компиляции данных для веб-страниц. Он будет использовать существующие веб-API и должен стать составной частью набора веб-технологий. Хотя название WebAssembly содержит приставку веб-, этот язык предназначен не только для браузеров, он должен предоставлять такие же возможности и для использования в других целях. За счет этого wasm может получить более широкое распространение.

Как и во всех языках с динамической типизацией, в JavaScript крайне трудно добиться оптимальной производительности работы, поэтому в течение многих лет на веб-страницах применялась возможность использовать машинный код (C/C++). Альтернативные языки, такие как NaCl и PNaCl, работают на веб-страницах вместе с JavaScript. Наибольшую практическую отдачу обеспечивает asm.js — это подмножество JavaScript с компонентами, при компиляции которых достигается производительность почти на уровне машинного кода.  Но ни одно из этих альтернативных решений не получило повсеместного распространения на веб-страницах для повышения производительности и использования кода. Эту проблему и призван решить язык wasm.

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

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

При использовании wasm эти стандартные API могут стать намного проще и работать на более низком уровне. При этом библиотеки динамической компоновки wasm, поддерживающие кэширование, многопоточность и обработку множества данных одной инструкцией (SIMD), обеспечат функциональность, недостижимую сегодня. Например, вместо сложных стандартных API для распознавания лиц или построения трехмерного изображения для использования с трехмерными камерами упрощенный стандартизованный API сможет просто предоставлять доступ к потоку необработанных трехмерных данных. Модуль wasm при этом будет осуществлять обработку, которая сейчас осуществляется библиотекой SDK. Это даст возможность загружать и кэшировать распространенные библиотеки динамической компоновки и быстро получать доступ к новым возможностям из Интернета, намного раньше возможного завершения процесса стандартизации.

В данной статье предлагается введение в эту стремительно развивающуюся технологию. В статье приводится общее описание, поскольку многое в спецификации wasm пока еще находится на уровне разработки.

Дополнительные сведения об общих целях и задачах wasm см. здесь:

https://github.com/WebAssembly/design/blob/master/HighLevelGoals.md5.

Общее описание

Проект и спецификация

Первоначальные документы проекта wasm находятся в следующем хранилище, в котором, в частности, есть следующие файлы.

  • AstSemantics.md— содержит описание самого формата.
  • MVP.md— определение «минимального жизнеспособного продукта» — требования для первой итерации wasm.
  • HighLevelGoals.md— общие цели wasm и сценарии, для которых предназначен этот язык.

Для точного определения и проверки решений, записанных в проектный документ, в хранилище specнаходится интерпретатор OCaml языка wasm. Также содержится папка тестового пакета с несколькими начальным тестами wasm. Набор тестов включает различные тесты — от общих вычислений с целыми числами и числами с плавающей запятой до операций с памятью.

Еще несколько инструментов в основном хранилище wasm в github используют этот же набор тестов для регрессивного тестирования. Например, это wasm-to-llvm-prototypeи wasmint.

Прототипы

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

Многие ресурсы в этих хранилищах являются проверочными, т. е. их цель — опробовать что-либо в действии и набрать опыт, они далеко не всегда представляют конечный результат. Инженеры, работающие с хранилищами, часто экспериментируют с wasm, чтобы понять, как все работает. Например, это касается различных тестируемых двоичных форматов, таких как polyfill-prototype-2или двоичный формат v8format.

WebAssembly: первый взгляд

Модули, более крупные составные части

В wasm модули являются наиболее крупными компонентами. Внутри модулей находятся функции и запросы выделения памяти. Модуль wasm — это совокупность распространяемого исполняемого кода. Каждый модуль обладает собственным линейным пространством памяти, функциями импорта и экспорта, а также кодом. Модуль может быть исполняемым файлом, библиотекой динамической компоновки (в будущих версиях wasm) или кодом для выполнения на веб-странице (используется в случаях, когда можно использовать модули ECMAScript 6 *).

Действующие тестовые файлы в тестовом пакете позволяют определять несколько модулей в одном файле, но считается, что в итоговой версии это будет не так. Напротив, чаще всего целая программа будет образовывать один большой модуль. Поэтому большинство программ C/C++ будут преобразованы в одиночные модули wasm.

Функции

В wasm применяется статическая типизация с возвратом; все параметры типизируются. Например, в этой строке из файла i32.wast в хранилище тестового пакетапоказано добавление двух параметров.

(func $add (param $x i32) (param $y i32) (result i32) (i32.add (get_local $x)
    (get_local $y)))

Все они являются 32-разрядными целочисленными значениями. Строка выглядит следующим образом.

  1. Объявление функции с именем $add.
  2. Она содержит два параметра, $x и $y, оба — 32-разрядные целочисленные значения.
  3. Результат — 32-разрядное целочисленное значение.
  4. Тело функции — 32-разрядное сложение.
    • Левая сторона — значение в локальной переменной или параметре $x.
    • Правая сторона — значение в локальной переменной или параметре $y.
  5. Поскольку нет явного узла возврата, возвращается последняя инструкция функции, то есть сложение.

Более подробные сведения о функциях и коде wasm см. ниже в этой статье.

Сходство с AST

Согласно общему определению wasm классифицируется как дерево абстрактного синтаксиса (AST), но также обладает некоторыми механизмами управления потоком и определением локальных переменных, что позволяет обрабатывать временные расчеты. Текущим текстовым форматом в wasm являются С-выражения (символьные выражения), хотя принято решение о том, что в итоговой версии wasm текст будет представлен иначе.

Тем не менее для пояснения работы wasm в этом документе они вполне пригодны. За исключением общих конструкций потока управления, таких как условия if, циклы и блоки, вычисления в wasm имеют формат AST. При этом для следующего вычисления:

(3 * x + x) * (3 * x + x)

используется следующий код wasm.

You could see the following wasm code:

(i32.mul
       (i32.add (i32.mul (i32.const 3) (get_local 0)) (get_local 0))
       (i32.add (i32.mul (i32.const 3) (get_local 0)) (get_local 0))
 )

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

Наш пример превращается в следующий код.

(set_local 1
       (i32.add (i32.mul (i32.const 3) (get_local 0)) (get_local 0))
)
 (i32.mul
       (get_local 1)
       (get_local 1)
 )

Ведутся обсуждения того, где следует производить оптимизацию:

  • между исходным кодом, например C/C++, и wasm;
  • между wasm и двоичным кодом, используемым для целевой архитектуры в браузере или в других приложениях.

 

 

Память

Подсистема памяти для wasm называется линейной памятью, где модуль может запросить заданный объем памяти, начиная с адреса 0. Для загрузки в память и для сохранения из памяти можно использовать либо константы для простых примеров кода, либо также переменные с адресами.

Например, следующий код сохраняет целое число 42 по адресу 0.

(i32.store (i32.const 0) (i32.const 42))

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

Прототип wasmLLVM

Прототип wasm — LLVM, инструмент, который я разрабатываю для wasm, предоставляет возможность компилировать код wasm непосредственно в код x86 посредством компилятора LLVM. Изначально предполагалось использовать wasm в веб-браузерах, но есть планы использовать wasm и в других сценариях, не связанных с браузерами.

Общая структура прототипа wasm — LLVM состоит в разборе тестового файла wasm с помощью программ с открытым исходным кодом flex и bison и в построении промежуточного представления. В этом промежуточном представлении есть этап (а в будущем, вероятно, их будет несколько), на котором производится промежуточная обработка перед формированием кода с помощью компилятора LLVM.

 wasm-to-LLVM prototype.

Рисунок 1.Прототип wasmLLVM

На рис. 1 показана базовая структура этой программы: в качестве начальных входных данных используется временный текстовый формат wasm. Такой формат называется С-выражениями. С-выражение проходит анализ лексическим и синтаксическим анализаторами, реализованными с помощью средств flex и bison. После анализа С-выражения создается внутреннее промежуточное представление, затем осуществляется промежуточная обработка перед получением внутреннего представления LLVM. В промежуточном представлении LLVM код отправляется в оптимизатор LLVM, после чего создается код Intel®  x86.

Первый пример на wasm

Здесь приводится простой пример: суммирование всех значений массива. Этот пример показывает, что освоить wasm довольно просто, следует лишь помнить о нескольких особенностях.

Предполагается, что код wasm будет создаваться компилятором, а исходным языком для этого будет C/C++. Не существует отдельного компилятора, который преобразует код C/C++ в wasm, хотя в LLVM уже ведутся работы, связанные с wasm. По всей видимости, и другие компиляторы, такие как GCC и MSVC, будут поддерживать язык и среду wasm. Написание непосредственно кода wasm вряд ли будет распространено, но интересно посмотреть на такой код и понять, как будет устроено взаимодействие языка с браузером/ОС и с архитектурой системы.

Сумма массива

;; Initialization of the two local variables is done as before:
;;   local 1 is the sum variable initialized to 0
;;   local 2 is the induction variable and is set to the
;;   max element and is decremented per iteration
 (loop
        (if_else
          (i32.eq (get_local 2) (i32.const 0))
           (br 1)
            (block
              (set_local 1 (i32.add (get_local 1) (i32.load (get_local 2))))
              (set_local 2 (i32.sub (get_local 2) (i32.const 4)))
            )
        )
        (br 0)
      )

Примечание. Описываемый подход не всегда является оптимальным. Он используется здесь для демонстрации основных компонентов языка wasmи его логики. В другой статье будут описаны различные конструкции, способные лучше имитировать инструкции используемого оборудования.

В приведенном выше примере цикл определяется узлом цикла. Узлы циклов могут определять имена блоков начала и выхода или могут быть анонимными, как здесь. Для лучшего понимания кода в цикле используются две локальные переменные. Local 1 — переменная суммы при обходе массива, а local 2 — обновляемая индукционная переменная. Local 2 фактически представляет указатель на текущую суммируемую ячейку.

 

 

Вот аналогичный код на C.

// Initialization is done before
//   local_1 is the sum variable initialized to 0
//   local_2 is the induction variable and is set to
//   the max element and is decremented per iteration
do {
   if (local_2 == start) {
     break;
   }
   local_1 = local_1 + *local_2;
   local_2--;
} while(1);

Циклы в wasm работают как конструкции do-while в C. Но неявное замыкание цикла отсутствует: в конце цикла wasm необходимо определить явную ветвь. После этого узел «br 0» в конце дает команду на возврат к верхнему узлу цикла: 0 представляет уровень вложенности цикла, на который нужно перейти.

Цикл начинает работу с проверки того, нужна ли дополнительная итерация. Если да, то выполняется «br 1», т. е. выход из начала цикла на один уровень. В этом случае, поскольку существует только один уровень, мы выходим из цикла.

В цикле код использует постепенно уменьшающийся указатель для достижения начала массива. В версии на C существует удобная переменная, названная start. Она представляет массив, суммирование которого выполняет код.

В wasm, поскольку разметка памяти начинается с адреса 0, а данный массив является единственным в этом до крайности упрощенном примере, произвольным образом определено, что начальным адресом массива будет 0. Если поместить массив в какое-нибудь другое место, то это сравнение будет больше похоже на версию на языке С; локальная переменная 2 будет сравниваться со смещением, переданным с помощью параметра.

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

Наконец, как мы показали, (get_local 2) является счетчиком цикла, а (get_local 1) — фактической суммой вектора. Поскольку мы суммируем 32-разрядные значения, в операции используются коды операций i32.add и i32.load. В этом примере вектор, который мы суммируем, находится в начале линейной области памяти.

Создание кода wasmLLVM

The wasm-to-llvm-prototype generates the following loop code quite easily:

.LBB4_2:
  movl  %edi, %edx
  addl  (%rdx,%rcx), %eax
  addl  $-4, %edi
  jne .LBB4_2

Это весьма компактный цикл, если учесть первоначальный код wasm в текстовом формате. А вот эквивалентная версия на С.

for (i = 0; i < n; i++) {
    sum += tab[i];
}

Компилятор GNU * Compiler Collection (GCC) версии 4.7.3 выдает при уровне оптимизации -O2 следующий код с аналогичной логикой.

.L11:
  addl  (%rdi,%rdx,4), %eax
  addq  $1, %rdx
  cmpl  %edx, %esi
  jg  .L11

В случае с wasm мы получили цикл с обратным отсчетом и используем результат вычитания напрямую в качестве условия для перехода цикла. В случае с GCC требуется инструкция сравнения. Но в версии GCC не используется дополнительная инструкция перемещения, которая используется в wasm с LLVM.

При уровне оптимизации O3 компилятор GCC применил векторизацию цикла. Видно, что прототип wasm — LLVM необходимо доработать, чтобы он начал создавать оптимальный код (как с векторизацией, так и без нее). Этому будет посвящена другая статья в этой серии.

Заключение

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

Wasm — новый язык, поэтому разрабатывается множество инструментов, чтобы помочь определить его потенциал, поддерживать его и понять, что этот язык может делать, а что — нет. Еще многие элементы, относящиеся к wasm, нуждаются в проработке, пояснении и изучении.

Об авторе

Жан-Кристоф Бейлер (Jean Christophe Beyler) — инженер по программному обеспечению в отделах Software and Solutions Group (SSG), Systems Technologies & Optimizations (STO) и Client Software Optimization (CSO) корпорации Intel. Он занимается компиляторами для Android и экосистемой Android в целом, а также другими технологиями, связанными с производительностью и компиляторами.


Использование устройств: возможности для разработчиков в 2016 году и далее

$
0
0

Автор: Карен Маркус

Недавно специалист по пользовательским интерфейсам корпорации Intel доктор Дария Лои и ее команда провели исследование, чтобы определить, как пользователи в разных странах мира относятся к своим компьютерным устройствам. В ходе исследования, которое получило название "Использование устройств: глобальная перспектива", было установлено, какие устройства являются предпочитаемыми у пользователей, какими устройствами люди пользуются чаще всего, какие устройства используют для определенных задач (и почему) и в чем можно было бы улучшить устройства. В ходе исследования было опрошено 1200 человек из 6 стран мира. Возраст респондентов различался в пределах нескольких десятков лет.

Исследование показало, что хотя такие устройства, как смартфоны, ноутбуки, настольные ПК и планшеты дают пользователям возможность выполнять многие важнейшие задачи как по работе, так и в личной жизни, и у большинства пользователей есть любимое или предпочитаемое устройство (см. рис. 1), все равно еще есть немало областей, где требуются улучшения. В этой статье подробно рассматриваются полученные в ходе исследования факты, а также обсуждаются возможности создания программного обеспечения, которое смогло бы повысить удобство пользователей.

Figure 1. Study responses for favorite device

Рисунок 1.Ответы на вопрос исследования о предпочитаемом устройстве.

Нет единого универсального устройства

Результаты исследования используемых устройств: глобальное исследование показало, что у большинства респондентов (39 %) предпочитаемым устройством является смартфон. За смартфонами следуют ноутбуки (30 %) и настольные ПК (21 %). Но ни одно из этих устройств не обладает интерфейсом, помогающим пользователям выполнять все действия, связанные с работой, личными задачами и развлечениями. Например, смартфоны очень удобны для фотосъемки, прослушивания музыки, участия в социальных сетях и общения с другими, но из-за небольшого размера экрана и низкого (на самом деле или по ощущениям) уровня безопасности они не столь полезны для покупок, управления банковскими счетами, редактирования изображений и электронной почты.

"Смартфон — портативное устройство, поэтому чаще всего люди пользуются именно этими устройствами, — говорит доктор Лои. — Поскольку это предпочитаемое устройство, хотелось бы, чтобы оно было идеальным, но в настоящее время не существует идеального устройства, поэтому люди владеют несколькими разными устройствами. Тем не менее, далеко не все существующие и новые пользователи, особенно молодые или в развивающихся странах, могут позволить себе приобрести несколько устройств, да и не желают носить с собой не одно устройство, а несколько. Поэтому перед нами, разработчиками технологий, встает вопрос: как создать будущее, в котором люди смогут удобно делать все что захотят, не обременяя себя несколькими устройствами? Как помочь пользователям решать все задачи на одном устройстве?"

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

Figure 2. Study responses for most important features

Рисунок 2. Ответы на вопрос исследования о наиболее важных характеристиках

Разнообразие устройств

Согласно результатам исследования, для разных функций люди предпочитают использовать разные устройства. Среди этих функций — чтение локально хранящихся книг, журналов и текста; просмотр фотографий, хранящихся как локально, так и в сети; интерактивный чат; интерактивные текстовые платформы; видеочат и видеоконференции; казуальные игры. Для определенного круга задач используются определенные устройства в зависимости от их возможностей.

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

В поездках смартфоны являются предпочитаемым устройством для поиска нужных мест, навигации, фото- и видеосъемки, прослушивания музыки. "Ожидания людей зависят от того, где они находятся, — поясняет Лои. — В зависимости от места люди могут принимать некоторое снижение скорости работы устройств. Ожидания пользователей меняются при изменении контекста. Цель разработчиков — создать приложения, хорошо работающие в любом контексте или способные изменяться таким образом, чтобы предоставлять пользователям нужные возможности всегда, вне зависимости от ситуации".

Смартфоны становятся умнее

Некоторые задачи можно выполнять на разных устройствах, но есть и задачи, которые чаще всего выполняются на одном определенном устройстве. Среди опрошенных 43 % назвали смартфоны в качестве предпочитаемого устройства для повседневных задач, таких как просмотр прогноза погоды, сохранение контактов и использование календаря; 47 % респондентов заявили, что смартфоны лучше всего подходят для поиска нужных мест и навигации; по мнению 62 % пользователей смартфоны — наилучшее устройство для фото- и видеосъемки (см. рис. 3).

Figure 3. Study responses for favorite device for locate and check functions

Рисунок 3.Ответы на вопрос исследования о предпочитаемом устройстве для навигации, поиска и получения новостей

Тем не менее, люди не слишком охотно совершают покупки в интернет-магазинах со своих смартфонов, поскольку чувствуют, что это менее безопасно. Некоторые участники опроса особо упомянули о том, что на смартфоне им не всегда удается увидеть весь экран, а по этой причине они обеспокоены тем, что могут не увидеть кнопку или какой-нибудь другой элемент, о котором им хотелось бы знать, чтобы не сомневаться, что покупка в полной мере соответствует их пожеланиям. "И все же людям хотелось бы выполнять эти задачи на любых устройствах, — отмечает Лои, — и здесь у разработчиков есть возможность создания программного обеспечения и инфраструктуры, позволяющей делать это с полной надежностью и безопасностью. Этот аспект станет особенно важным с учетом того, что корпорации Google и Apple стремятся продвигать свои решения по использованию смартфонов в качестве платежного средства, наподобие банковских карт".

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

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

Производительность ПК — фактор победы

Многие люди всерьез влюблены в свои телефоны, но, несмотря на это, для определенных задач предпочитаемыми устройствами являются все же ноутбуки или моноблоки (см. рис. 4). В частности, 38 % пользователей используют ноутбуки для редактирования мультимедиа, 47 % — для создания и редактирования документов, 36 % — для публикаций в блогах и на веб-сайтах, 41 % — для пользования банковскими услугами и оплаты счетов; 44 % — для просмотра товаров с целью возможной покупки, а 41 % пользователей — для покупки товаров в интернет-магазинах. Лои отмечает, что для всех этих предпочтений важнейшую роль играет размер экрана. "Гораздо удобнее работать с информацией на большом экране, — говорит она. — Кроме того, многие программные продукты либо недоступны для смартфонов, либо стоят недопустимо дорого. Мощная экосистема программного обеспечения, а также преимущества ноутбуков по практичности, физическому размеру и производительности — вот факторы, в силу которых ноутбуки являются предпочитаемым устройством для этих задач".

Figure 4. Study responses for favorite device for online purchasing

Рисунок 4.Ответы на вопрос исследования о предпочитаемом устройстве для покупок в интернет-магазинах

Участники опроса также назвали ноутбуки предпочитаемым устройством для связи и развлечений, в частности: для просмотра видео в Интернете (36 %); для просмотра видео, хранящегося локально (37 %); для отправки, загрузки или передачи мультимедиа (38 %); для работы с электронной почтой (42 %); для голосовой связи через Интернет (VoIP) и других голосовых платформ (35 %, см. рис. 5). "Это области применения, требующие высокой производительности, которой смартфоны пока не обладают. В будущем возможности ПК могут появиться и у более компактных устройств. И вновь, для реализации этой возможности нужна подходящая экосистема, программное обеспечение, промежуточные средства, интерфейсы и инфраструктура — в дополнение к удобным средствам для передачи мультимедиа".

Figure 5. Study responses for favorite device for writing and talking

Рисунок 5. Ответы на вопрос исследования о предпочитаемом устройстве для ввода текста и разговора

Прочие области, в которых респонденты предпочитали мощь и крупные экраны своих ноутбуков: демонстрация презентаций и отчетов (59 %), ресурсоемкие игры (24 % — ноутбуки, 25 % — настольные ПК), просмотр и изучение информации в Интернете 38 %), обучение (47 %), чтение новостей и текста в Интернете (39 %, см. рис. 6). "Некоторые из этих функций, казалось бы, доступны и на смартфонах, но смартфоны обычно гораздо сложнее подключать к другим устройствам (таким как проекторы), чем компьютеры, — замечает Лои, — производительность смартфонов не позволяет запускать на них хоть сколько-нибудь сложные игры; ограниченный размер экрана делает смартфоны непригодными для продолжительной, сосредоточенной многозадачной работы, характерной для изучения информации или обучения".

Figure 6. Study responses for favorite device for reading, learning, and research

Рисунок 6.Ответы на вопрос исследования о предпочитаемом устройстве для чтения и обучения

Мнения о технологиях

Чтобы лучше понять, какие ощущения устройства вызывают у участников опроса, Лои и ее команда поговорили с несколькими респондентами, чтобы получить качественную информацию, способную дополнить количественные данные глобального опроса. Один из важнейших выявленных фактов состоит в том, что люди все сильнее одновременно любят и ненавидят новые технологии. "Люди понимают, что не могут жить без своих устройств, но при этом чувствуют себя рабами своих устройств, — говорит Лои. — Очень часто ощущения описываются таким образом: "я хочу иметь возможность постоянно пользоваться устройствами, чтобы выполнять важные для меня дела, но при этом я хочу, чтобы устройства не маячили перед глазами, когда они не нужны". Например, если пользователь находится на собрании, его смартфон должен учитывать это и отключать входящие звонки. Существует немалый потенциал в области создания машин, способных обучаться поведению пользователей и отключаться, чтобы не мешать в неподходящее время".

"Я жалею, что те времена, когда мы не были круглосуточно на связи, в сети, остались в прошлом". — Арон, возрастная группа старше 20 лет

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

"Мне хотелось бы больше общаться с родными, а сейчас мы, кажется, больше разглядываем экраны телефонов, чем разговариваем друг с другом".
— Кэрол, возрастная группа старше 40 лет

Новые технологии вызывают не только одобрение и признание, но и разочарование, и раздражение. Вот некоторые из основных недостатков устройств, на которые жалуются пользователи: слишком быстро расходуется заряд аккумуляторов; устройства работают слишком медленно или "зависают"; устройства подвержены вирусам и утечке конфиденциальных данных; они слишком крупные, чтобы их было действительно удобно с собой носить; они слишком маленькие, чтобы хранить на них всю информацию; устройствами сложно пользоваться. Основная причина раздражения опрошенных — малая мобильность устройств, обусловленная недостаточным временем их автономной работы. "Общество, в котором мы живем, становится все более мобильным, — утверждает Лои. — Это общество полностью опирается на использование мобильных устройств. Но для того, чтобы эти устройства превратились в действительно полезные инструменты, они должны долго работать от аккумулятора. Для большинства респондентов, с которыми я поговорила, необходимость поиска розетки электросети, чтобы зарядить устройство, превратилась уже в навязчивую идею. Это серьезнейшее препятствие, мешающее устройствам быть действительно мобильными и эффективными. В этой области неплохие перспективы есть, помимо прочего, у беспроводной зарядки, но для ее использования должна быть эффективная, надежная и интуитивная экосистема". По словам Лои, пароли — еще одна проблема, требующая решения. В числе других проблем — слишком быстрое изменение технологий; эту проблему можно решить, помогая людям переходить со старых операционных систем и приложений на новые.

"Технологии постоянно меняются, и следовать за ними очень непросто". — Рауль, возрастная группа старше 20 лет

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

"Мне нужно, чтобы у меня был выбор. Не хочу, чтобы мне указывали, что мне делать". — Фрэнсис, возрастная группа старше 30 лет

Несмотря на раздражение постоянными изменениями, люди с интересом ожидают новых возможностей. Многие участники исследования описывали футуристические функции, которыми могли бы обладать их устройства — как в фильме "Железный человек", по словам некоторых опрошенных. Среди таких возможностей — ввод сообщений не с клавиатуры и не голосом, а с помощью мысли; интерактивные голографические изображения во время чата; сверхчувствительные микрофоны, способные распознавать голосовые команды из любой точки дома. "Идеи и ожидания в отношении будущих технических идей формируются у людей главным образом по социальным сетям и голливудским фильмам, — говорит Лои. — Некоторые просто не понимают, почему эти технологии, относящиеся к области научной (и не очень научной) фантастики, до сих пор не получили широкого распространения. Несмотря на сложность таких технологий, многие ожидают их скорого появления на рынке, во многих случаях — намного раньше, чем это фактически возможно.

"Возможность показывать другим в точности то, что я себе представляю,  скажем, в виде трехмерной голограммы”. — Шила, возрастная группа старше 20 лет

Заключение

За последние годы в области компьютерных технологий пройдено несколько важных этапов, и современные устройства вполне заслуженно нравятся своим пользователям. Тем не менее, есть еще немало областей, в которых удобство устройств можно и нужно повышать. Доктор Лои, специалист корпорации Intel, провела исследование, озаглавленное "Использование устройств: глобальная перспектива". Цель этого исследования состояла в том, чтобы узнать, как люди в разных странах используют свои устройства сейчас, и как они хотели бы использовать их в будущем. В ходе исследования были обозначены следующие области, в которых разработчики могут усовершенствовать свои решения:

  • Упорядочение функциональности, чтобы люди могли выполнять полный круг необходимых задач, нося с собой (и приобретая) меньше устройств.
  • Непрерывное повышение удобства использования.
  • Укрепление безопасности, повышение наглядности работы на смартфонах для покупок в интернет-магазинах.
  • Усовершенствование функций смартфонов (камеры, доступ к музыке) с тем, чтобы можно было использовать смартфоны вместо нескольких специализированных устройств.
  • Реализация возможностей, делающих смартфоны более полезными для обучения.
  • Повышение производительности смартфонов, необходимое для запуска более ресурсоемких приложений; программные пакеты, предназначенные для ПК, должны стать более удобными и доступными для смартфонов.
  • Предоставление пользователям приложений, работающих с учетом контекста.
  • Усовершенствование технологий связи, чтобы люди ощущали себя ближе к своим собеседникам.
  • Продление времени работы устройств от аккумулятора, изобретение новых способов зарядки устройств.
  • Помощь пользователям в переходе со старых приложений и систем на новые.

Самое главное, по мнению доктора Лои, заключается в формировании более продуманной концепции будущего. "Для этого нужно, чтобы все новые разработки опирались на четкое понимание того, что люди делают, чего они хотят, в чем нуждаются, — говорит она. — Работа нашей отрасли должна основываться на четком, подтвержденном данными понимании того, что важно для пользователей".

Об авторе

Карен Маркус (Karen Marcus) — высококлассный маркетинговый и технический писатель с 18-летним стажем. Она создавала описания примеров, брошюры, информационные документы, статьи, тексты для веб-сайтов, сценарии видео и другие материалы для таких компаний, как Intel, IBM, Samsung, HP, Amazon Web Services и Microsoft. Карен прекрасно осведомлена о множестве современных технологий и решений, среди которых: облачные вычисления, корпоративные вычислительные системы, персональные компьютеры, ИТ-аутсорсинг, операционные системы и разработка приложений.

Дополнительные сведения об оптимизации компиляторов см. в нашем уведомлении об оптимизации.

Камера Intel® RealSense™, плата Intel® Edison и JavaScript*

$
0
0

Введение

Компьютеры встраиваются в самые разные устройства, включая весьма компактные. Такие устройства могут собирать данные и обмениваться ими: эта технология называется «Интернет вещей».

Корпорация Intel разработала технологию Intel® RealSense™, которая включает камеру Intel® RealSense™и пакет Intel® RealSense™ SDK. С помощью этой технологии можно создавать применения, способные распознавать жесты и движение головы, анализировать выражение лица, отделять фон изображения, измерять уровень глубины, распознавать и синтезировать речь и т. д. Представьте, что вы разрабатываете супердатчик, способный обнаруживать и распознавать множество данных. В сочетании с универсальностью комплекта Intel® Edison, используя возможности вывода данных этого комплекта, можно создавать самые разные решения, полезные и развлекательные.

Пакет Intel® RealSense™ SDK поддерживает популярные языки программирования и платформы, такие как C++, C#, Java*, JavaScript*, Processing и Unity*. Это означает, что разработчики могут быстро приступать к работе, используя хорошо знакомую среду программирования.

В статье Питера Ма (Peter Ma) «Использование камеры Intel® RealSense™ 3D с платформой разработки Intel® Edison» приведены два примера приложений на C#. В первом камера Intel® RealSense™ получает входные данные, а для вывода используется плата Intel® Edison. В результате, если сделать определенный жест перед камерой Intel® RealSense™, камера отправит сигнал на плату Intel® Edison, а на плате загорится светодиод.

Во втором примере Питер Ма действует в обратном направлении: плата Intel® Edison используется в качестве входного устройства, а камера Intel® RealSense™ является выходным устройством. Плата Intel® Edison предоставляет данные, поступающие с датчика. Мы получаем эти данные с камеры Intel® RealSense™ в виде синтезированного голоса.

Мне захотелось создать что-то близкое к проекту Питера Ма, но с использованием JavaScript* вместо C#. Я использовала Intel® RealSense™ SDK для чтения и отправки данных жестов руки на сервер node.js, который затем отправляет эти данные на плату Intel® Edison для включения динамика и светодиода, подключенных к этой плате.

О проекте

Этот проект написан на JavaScript*. Если вас интересует использование только простейших жестов, то модуль с нужным алгоритмом уже есть в составе Intel® RealSense™ SDK. В нем вы найдете все необходимое.

Оборудование

Требования:

Плата Intel®Edisonс коммутационной платой Arduino*

Плата Intel® Edison — это недорогая универсальная компьютерная платформа. На ней используется «система на кристалле» с двухъядерным процессором Intel® Atom™, выполненным по 22-микронной технологии и работающим с частотой 500 МГц. Эта плата отличается компактным размером, она поддерживает 40 регистров ввода-вывода GPIO и включает 1 ГБ оперативной памяти LPDDR3, 4 ГБ флеш-памяти EMMC для хранения данных, двухдиапазонный адаптер Wi-Fi и адаптер Bluetooth.

На плате используется ядро Linux*, она совместима с Arduino, поэтому можно запускать Arduino в качестве программ Linux*.


Рисунок 1. Плата Intel®Edisonв комплекте с коммутационной платой

Комплект Grove Starter Kit Plus — Intel® XDK IoT Edition

Комплект Grove Starter Kit Plus — Intel® XDK IoT Edition Intel®разработан для плат Intel® Galileo 2-го поколения, но при использовании коммутационной платы он полностью совместим с платой Intel® Edison.

Комплект содержит датчики, приводы и экраны, например сенсорный датчик, датчик света и датчик звука, а также ЖК-экран, как показано на рис. 2. Это недорогое удобное решение для разработки проектов из области «Интернета вещей».

Приобрести комплект Grove Starter Kit Plus можно здесь: 

 


Рисунок 2. Комплект Grove* Starter Kit Plus — Intel® XDK IoT Edition

Камера Intel®RealSense

Камера Intel® RealSense™ предназначена для взаимодействия с играми, для развлечений, фотосъемки и создания содержимого. Такие камеры встраиваются в устройства или выпускаются в виде отдельных периферийных устройств. Для использования камеры требуется порт USB 3.0, процессор Intel Core 4-го поколения и 8 ГБ места на жестком диске.

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

Рисунок 3. Камера Intel®RealSense

Здесьможно приобрести полный комплект разработки, в состав которого входит и камера.

Сервер GNU/Linux*

Использование сервера GNU/Linux* не представляет затруднений. Можно использовать старый настольный компьютер или ноутбук или разместить сервер в облаке. Я использовала облачный сервер с сервером Ubuntu*. Если у вас есть разные дистрибутивы Linux*, используйте наиболее удобный для вас.

Программное обеспечение

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

Настройка камеры Intel® RealSense™

Чтобы настроить камеру Intel® RealSense™ (F200), подключите ее к порту USB 3.0 и установите драйвер камеры. Перейдите в папку установки Intel® RealSense™ SDK и откройте образец JavaScript* в браузере:

Install_Location\RSSDK\framework\JavaScript\FF_HandsViewer\FF_HandsViewer.html

После открытия файла сценарий определяет используемую вами платформу. Пока сценарий занимается определением платформы, щелкните ссылку в веб-браузере, чтобы установить среду выполнения веб-приложений Intel® RealSense™ SDK.

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

Настройка жестов

Первая строка кода, включающая жесты, выглядит так: 

{"timeStamp":130840014702794340 ,"handId": 4,"state": 0,"frameNumber":1986 ,"name":"spreadfinger"
}

Этот код отправляет "name":"spreadfingers"на сервер для обработки.

Теперь мы напишем код JavaScript*, чтобы передавать данные жестов от камеры Intel® RealSense™ на плату Intel® Edison через сервер node.js.

Работа с JavaScript*

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

Скопируйте папку FF_HandsViewerиз этого расположения в какое-нибудь другое место. Расположение папки:

\install_Location\RSSDK\framework\JavaScript\FF_HandsViewer\

Позже вы сможете создать собственную папку проекта, чтобы все было под контролем.

Теперь скопируйте файл realsense.jsиз указанного ниже пути и вставьте его в папку FF_HandsViewer:

Install_Location\RSSDK\framework\common\JavaScript

Чтобы все упростить, создадим файл с именем edisonconnect.js. Этот файл будет принимать данные жестов от камеры Intel® RealSense™ и отправлять их на сервер node.js. Помните, что нужно изменить IP для переменной socket, используя IP-адрес сервера node.js:

// var socket = io ('change this to IP node.js server');

var socket = io('http://192.168.1.9:1337');

function edisonconnect(data){
  console.log(date.name);
  socket.emit('realsense_signal',data);
}

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

// retrieve the fired gestures
for (g = 0; g < data.firedGestureData.length; g++){
  $('#gestures_status').text('Gesture: ' + JSON.stringify(data.firedGestureData[g]));

  // add script start - passing gesture data to edisonconnect.js
	edisonconnect(data.firedGestureData[g]);
  // add script end
}

После запуска приведенной выше функции и ее вызова для создания данных жестов показанный ниже код завершает основную задачу программы JavaScript*.  После этого нужно заменить путь к файлу realsense.js.

Необходимо сделать следующее: укажите ссылки на файлы socket.ioи edisonconnect.js

<!DOCTYPE html><html><head><title> Intel&reg; RealSense&trade; SDK JavaScript* Sample</title><script src=”https://aubahn.s3.amazonaws.com/autobahnjs/latest/autobahn.min.jgz” </script><script src=”https://promisejs.org/polyfills/promise-6.1.0.js” </script><script src=”https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js” </script><script src=”https://common/JavaScript/realsense.js” </script><script src=”sample.js” </script><script src=”three.js” </script><!-- add script start --><script src=”https://cdn.socket.io/socket.io-1.3.5.js” </script><script src=”edisonconnect.js” </script><!-- add script end → <link rel=”stylesheet” type=”text/css” href=”style.css”></head><body>

Этот код взят из образца в SDK. Он немного переработан для упрощения и удобочитаемости. Этот код отправил данные жестов на сервер. В результате пакет Intel® RealSense™ SDK успешно распознает жест и готов отправить его на сервер.

Настройка сервера

Мы используем сервер GNU/Linux*. Я использую сервер Ubuntu* в качестве ОС, но можно использовать и любой другой дистрибутив GNU/Linux*. Установку сервера мы описывать не будем, поскольку в Интернете можно с легкостью найти все необходимые инструкции.

Войдите через SSH от имени пользователя root, чтобы настроить сервер.

Поскольку сервер только что установлен, нужно обновить список хранилищ и обновить сам сервер. Для этого я использую стандартную команду дистрибутива Ubuntu. Вы можете использовать схожую команду в зависимости от используемого дистрибутива GNU/Linux*.

# apt-get update && apt-get upgrade

После обновления списка хранилищ нужно установить node.js.

# apt-getinstallnodejs

Также нужно установить диспетчер пакетов npm.

# apt-getinstallnpm

И наконец, нужно установить socket.ioexpressиз диспетчера пакетов npm.

# npminstallsocket.ioexpress

Не забудьте создать файлы server.jsи index.html.

# touchserver.jsindex.html

Отредактируйте файл server.js, используя любой текстовый редактор, например vim или nano #.

vimserver.js

Запишите этот код:

var express   = require("express");
var app   	= express();
var port  	= 1337;

app.use(express.static(__dirname + '/'));
var io = require('socket.io').listen(app.listen(port));
console.log("Listening on port " + port);

io.on('connection', function(socket){'use strict';
  console.log('a user connected from ' + socket.request.connection.remoteAddress);

	// Check realsense signal
	socket.on('realsense_signal', function(data){
  	socket.broadcast.emit('realsense_signal',data);
  	console.log('Hand Signal: ' + data.name);
	});
  socket.on('disconnect',function(){
	console.log('user disconnected');
  });
});

varport = 1337; означает, что доступный порт назначен порту 1337. console.log("Listeningonport" + port) ; указывает, были ли получены данные из JavaScript*. Основной код — socket.broadcast.emit('realsense_signal',data);это означает, что данные получены и готовы к вещанию на все прослушивающие порты и клиенты.

Осталось лишь запустить файл server.jsс узлом. Если отображается надпись listeningatport 1337, как показано на приведенном ниже снимке экрана, то все работает правильно.
# node server.js

root@edison:~# node server.js
Listening on port 1337
events.js:85

Настройка платы Intel® Edison

Развернуть комплект The Intel® Edison SDK очень просто. См следующую документацию:

Пора передать код на плату the Intel® Edison. Этот код подключается к серверу и прослушивает вещание с сервера. Он аналогичен коду другого этапа, на котором мы прослушиваем вещание данных с сервера. При получении каких-либо данных жестов на плате Intel® Edison включаются и выключаются цифровые контакты.

Откройте Intel® XDK IoT Edition и создайте новый проект на основе шаблона DigitalWrite, как показано на приведенном ниже снимке экрана.

Отредактируйте строку 9 в файле package.json, добавив зависимости socket.io-client. Если этот файл пуст, найдите папку, в которую он был установлен. Добавление зависимостей приведет к установке клиента socketioclient, если на плате Intel® Edison не было клиента.

"dependencies": {"socket.io-client":"latest" // add this script
}

Найдите файл main.js. Нужно установить подключение к серверу, чтобы убедиться, что сервер готов к прослушиванию. Затем нужно проверить, существуют ли данные жестов с именем spreadfingersв этом файле. В этом случае цифровые контакты 2 и 8 будут переключены в состояние 1 (включено) и обратно.
Измените IP-адрес сервера. Если вы хотите изменить контакты, то не забудьте изменить и mraa.Gpio(selectedpins).

var mraa  = require("mraa");

var pins2 = new mraa.Gpio(2);
	pins2.dir(mraa.DIR_OUT);

var pins8 = new mraa.Gpio(8);
	pins8.dir(mraa.DIR_OUT);

var socket = require('socket.io-client')('http://192.168.1.9:1337');

socket.on('connect', function(){
  console.log('i am connected');
});

socket.on('realsense_signal', function(data){
  console.log('Hand Signal: ' + data.name);
  if(data.name=='spreadfingers'){
	pins2.write(1);
	pins8.write(1);
  } else {
	pins2.write(0);
	pins8.write(0);
  }
});

socket.on('disconnect', function(){
  console.log('i am not connected');
});

Выберите Install/Build, затем выберите Run, убедившись, что плата Intel® Edison подключена к компьютеру.

Теперь убедитесь, что сервер запущен, а компьютер с камерой Intel® Realsense и платой Intel® Edison подключены к Интернету.

Заключение

В этом проекте используется технология Intel® RealSense™. Пример сценария JavaScript* был изменен, чтобы отправлять полученные данные жестов на сервер Node.js. Но этот проект — лишь начало.

Он очень прост в реализации. Сервер передает данные жестов на любые прослушивающие клиенты. Плата Intel® Edison, на которую установлен клиент socket.io-client, прослушивает вещание с сервера. Поэтому при получении данных жестов с именем spreadfingersцифровые контакты будут переключены из состояния 0 в состояние 1 и обратно.

Возможности поистине безграничны. Камера Intel RealSense отличается небольшим весом, удобством установки и использования. Intel® Edison — это мощный встраиваемый ПК. Объединение платы Intel® Edison и камеры Intel® RealSense™ с JavaScript* позволяет получить очень компактное, простое с точки зрения написания кода и удобное в использовании устройство «Интернета вещей». Можно создать что-нибудь полезное и приятное.

Об авторе

Аулиа Факих (Aulia Faqih) — специалист c квалификацией Intel® Software Innovator

Intel® RealSense Innovator, работает в индонезийском городе Джокьякарта и читает лекции в UIN Sunan Kalijaga. Аулиа обожает ставить различные эксперименты с Galileo/Edison, веб-решениями и гаджетами.

Управление роботизированной рукой с помощью камер Intel® RealSense™

$
0
0

Аннотация

Роботизированная рука Roy компании Roemotion*была создана в результате успешно профинансированного проекта на портале Kickstarter, начатого в 2012 году. Описание гласило: «Проект создания движущегося персонажа размером с человека с использованием только механических деталей, полученных способом лазерной резки, и сервоприводов, доступных в широкой продаже в магазинах товаров для хобби и моделирования». В этом эксперименте с помощью пакета Intel® RealSense™ SDK для Windows*было разработано программное обеспечение для управления рукой Roy. Для управления используются API-интерфейсы отслеживания рук, доступные в составе SDK (рис. 1).

Figure 1. Robotic hand control software.

Рисунок 1.Программа для управления роботизированной рукой

Код для этого проекта был разработан на C#/XAML с помощью Microsoft Visual Studio* Community 2015. Программное обеспечение может использовать камеры Intel RealSense F200и SR300 (скоро будет доступна). Чтобы увидеть роботизированную руку, управляемую программным обеспечением, в действии, посмотрите следующее видео на сайте YouTube*: https://youtu.be/VQ93jw4Aocg

О руке Roy

Набор для сборки руки Roy в настоящее время можно приобрести на веб-сайтекомпании Roemotion, Inc. в виде комплекта для сборки. Комплект включает:

  • детали, изготовленные методом лазерной резки;
  • все необходимые крепежные элементы;
  • 8 сервоприводов (таких же, какие используются в управляемых моделях);
  • 6 удлинительных кабелей для сервоприводов.

Как указано на веб-сайте Roemotion, этот комплект не включает электронику для управления. Это обусловлено тем, что изначально смысл проекта заключался в предоставлении людям интересных механических систем для использования с любыми контроллерами. В самом эксперименте используется сторонний сервоконтроллер для управления моторами в роботизированной руке (рис. 2).

Figure 2. Roy robotic arm.

Рисунок 2. Роботизированная рука Roy

В руке установлено 6 сервомоторов: по одному для указательного пальца, среднего пальца, безымянного пальца и мизинца и два для большого пальца. (Примечание. Еще два сервомотора установлены в основании руки для управления движением запястья, но в этом эксперименте мы ими не управляем.)

API-интерфейсы отслеживания рук в Intel® RealSense™ SDK

Как указано в документациик Intel RealSense SDK, модуль отслеживания рук предоставляет трехмерное отслеживание движения рук в реальном времени и может отслеживать одну или две руки, предоставляя данные о точном расположении всех суставов. В рамках этого эксперимента по управлению устройством в реальном времени особый интерес для нас представляют значения сгиба пальцев, полученные с помощью вызовов метода QueryFingerData().

Электроника для управления

В этом эксперименте мы использовали 6-канальный USB-сервоконтроллер Pololu Micro Maestro* (рис. 3) для управления шестью моторами, установленными в руку Roy. Это устройство включает достаточно сложный SDK для разработки управляющих приложений, предназначенных для разных платформ, с использованием разных языков программирования.

Figure 3. Pololu Micro Maestro* servo controller.

Рисунок 3.Сервоконтроллер Pololu Micro Maestro*

Настройка сервоконтроллера

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

К счастью, в состав пакета Pololu Micro Maestro SDK входит приложение Control Center, с помощью которого пользователь может настраивать параметры на уровне микропрограммы и сохранять их во флеш-память на плате контроллера. Параметры, определенные опытным путем для этого приложения, показаны на рис. 4.

Figure 4. Pololu Maestro Control Center app.

Рисунок 4.Приложение Pololu Maestro Control Center

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

Еще один важный параметр в данном случае называется On startup or error. Благодаря ему все пальцы по умолчанию (и в случае ошибок) занимают выпрямленное положение, чем исключается возможность зацепления большого и указательного пальцев, если они были согнуты.

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

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

Собственная программа для управления

В этом эксперименте мы разработали собственную программу (рис. 5), исполь­зующую множество функций отслеживания рук, доступных в образцах кода в SDK.

Figure 5. Custom Control Software.

Рисунок 5.Собственная программа для управления

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

  • Данные оповещений.
  • Данные о сгибании.
  • Данные масштаба.

Данные оповещений

Оповещения — самая важная информация для отслеживания в приложении, управляющем устройством (таким как в данном случае роботизированная рука) в реальном времени. Очень важно понимать (и контролировать!), как поведет себя устройство, когда заданные значения окажутся недоступными или недостоверными.

В этом эксперименте приложение отслеживает следующие данные оповещений:

  • Рука обнаружена.
  • Рука откалибрована.
  • Рука находится внутри границ.

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

Как показано в приведенном ниже фрагменте кода, приложение циклически получает количество сработавших оповещений и задает три логические переменные: detectionStatusOk, calibrationStatusOkи borderStatusOk (обратите внимание, что handOutput является экземпляром PXCMHandData).

for (int i = 0; i < handOutput.QueryFiredAlertsNumber(); i++)
{
  PXCMHandData.AlertData alertData;
  if (handOutput.QueryFiredAlertData(i, out alertData) != 
         pxcmStatus.PXCM_STATUS_NO_ERROR) { continue; }
 
  switch (alertData.label)
  {
         case PXCMHandData.AlertType.ALERT_HAND_DETECTED:
               detectionAlert = "Hand Detected";
               detectionStatusOk = true;
               break;
         case PXCMHandData.AlertType.ALERT_HAND_NOT_DETECTED:
               detectionAlert = "Hand Not Detected";
               detectionStatusOk = false;
               break;
         case PXCMHandData.AlertType.ALERT_HAND_CALIBRATED:
               calibrationAlert = "Hand Calibrated";
               calibrationStatusOk = true;
               break;
         case PXCMHandData.AlertType.ALERT_HAND_NOT_CALIBRATED:
               calibrationAlert = "Hand Not Calibrated";
               calibrationStatusOk = false;
               break;
         case PXCMHandData.AlertType.ALERT_HAND_INSIDE_BORDERS:
               bordersAlert = "Hand Inside Borders";
               borderStatusOk = true;
               break;
         case PXCMHandData.AlertType.ALERT_HAND_OUT_OF_BORDERS:
               bordersAlert = "Hand Out Of Borders";
               borderStatusOk = false;
               break;
  }
}

Перед любой попыткой программы управлять сервомеханизмами руки проводится проверка: все три переменные, то есть detectionStatusOk, calibrationStatusOkи borderStatusOk, должны иметь значение True. Если в любой момент времени какой-либо из этих трех флагов получает значение False, то все пальцы переводятся в положение Open по умолчанию для безопасности.

Данные о сгибании

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

Приложение получает данные о сгибании каждого пальца в цикле получения и высвобождения кадра, как показано в следующем фрагменте кода (где handData является экземпляром PXCMHandData.IHand).

PXCMHandData.FingerData fingerData;
 
handData.QueryFingerData(PXCMHandData.FingerType.FINGER_THUMB, out fingerData);
thumbFoldeness = fingerData.foldedness;
lblThumbFold.Content = string.Format("Thumb Fold: {0}", thumbFoldeness);
 
handData.QueryFingerData(PXCMHandData.FingerType.FINGER_INDEX, out fingerData);
indexFoldeness = fingerData.foldedness;
lblIndexFold.Content = string.Format("Index Fold: {0}", indexFoldeness);
 
handData.QueryFingerData(PXCMHandData.FingerType.FINGER_MIDDLE, out fingerData);
middleFoldeness = fingerData.foldedness;
lblMiddleFold.Content = string.Format("Middle Fold: {0}", middleFoldeness);
 
handData.QueryFingerData(PXCMHandData.FingerType.FINGER_RING, out fingerData);
ringFoldeness = fingerData.foldedness;
lblRingFold.Content = string.Format("Ring Fold: {0}", ringFoldeness);
 
handData.QueryFingerData(PXCMHandData.FingerType.FINGER_PINKY, out fingerData);
pinkyFoldeness = fingerData.foldedness;
lblPinkyFold.Content = string.Format("Pinky Fold: {0}", pinkyFoldeness);

 

 

Данные масштаба

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

// Index finger
public const int INDEX_OPEN = 1808;
public const int INDEX_CLOSED = 800;
public const int INDEX_DEFAULT = 1750;
.
.
.

Индивидуальные константы определяются для каждого пальца роботизированной руки, они сопоставляются с параметрами положений Min и Max сервопривода, которые были записаны во флеш-память платы контроллера Micro Maestro (рис. 4). Аналогичным образом в программе определяется и полномасштабное значение для диапазона данных сгиба пальцев.

int fingerMin = 0;
int fingerMax = 100;

Поскольку диапазон сгиба пальцев одинаков для всех пальцев (т. е. от 0 до 100), достаточно задать диапазон только один раз, после чего его можно использовать для операций масштабирования данных для всех пальцев, как показано ниже.

// Index finger
int indexScaled = Convert.ToInt32((Servo.INDEX_OPEN - Servo.INDEX_CLOSED) * 
   (index - fingerMin) / (fingerMax - fingerMin) + Servo.INDEX_CLOSED);
                
lblIndexScaled.Content = string.Format("Index Scaled: {0}", indexScaled);
Hand.MoveFinger(Servo.HandJoint.Index, Convert.ToUInt16(indexScaled));
.
.
.

Видео

Чтобы увидеть роботизированную руку в действии, посмотрите следующее видео на сайте YouTube*: https://youtu.be/VQ93jw4Aocg

Заключение

Для реализации этого программного эксперимента потребовалось лишь несколько часов после того, как мы протестировали сервомоторы и поняли принцип управления ими. Классическое приложение для Windows 10 было разработано на C#/XAML. В нем используются многие функции, доступные в API-интерфейсах и в образцах кода Intel RealSense SDK.

О технологии Intel® RealSense™

Дополнительные сведения о пакете Intel RealSense SDK для Windows см. по адресу https://software.intel.com/ru-ru/intel-realsense-sdk.

Об авторе

Брайан Браун (Bryan Brown) — инженер по разработке программных приложений в подразделении Developer Relations корпорации Intel.

Привязка ресурсов в Microsoft DirectX* 12. Вопросы производительности

$
0
0

Автор: Вольфганг Энгель (WolfgangEngel), директор компании Confetti

Давайте подробнее рассмотрим привязку ресурсов на платформах Intel®. Сейчас это особенно актуально в связи с выпуском 6-го поколения процессоров семейства Intel® Core™ (Skylake) и с выпуском операционной системы Windows 10, который состоялся 29 июля.

В предыдущей статье Введение в привязку ресурсов в Microsoft DirectX* 12были описаны новые способы привязки ресурсов в DirectX 12. Вывод из этой статьи был таким: при наличии настолько широкого выбора основная задача заключается в том, чтобы выбрать наилучший механизм привязки для целевого GPU, оптимальные типы ресурсов и частоту их обновления.

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

Инструменты

Для разработки игр на основе DirectX 12 требуется следующее:

  • Windows 10.
  • Visual Studio* 2013 или более поздней версии.
  • Пакет DirectX 12 SDK, входящий в состав Visual Studio.
  • GPU и драйверы, поддерживающие DirectX 12.

Обзор

Дескриптор — это блок данных, описывающий объект для GPU, в «непрозрачном» формате, предназначенном для GPU. В DirectX 12 поддерживаются следующие дескрипторы, которые ранее назывались «представлениями ресурсов» в DirectX 11:

  • Представление буфера констант (CBV).
  • Представление ресурсов шейдера (SRV).
  • Представление неупорядоченного доступа (UAV).
  • Представление семплера (SV).
  • Представление цели рендеринга (RTV).
  • Представление шаблона глубины (DSV).
  • И другие.

Эти дескрипторы или представления ресурсов можно считать структурой (блоком), которая потребляется front end графического процессора. Размер дескрипторов составляет приблизительно 32–64 байта. Дескрипторы содержат информацию о размерах текстур, их формате и разметке.

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

Таблица дескрипторов указывает на дескрипторы в куче с помощью значений смещения. Таблица сопоставляет непрерывный диапазон дескрипторов с ячейками шейдера, делая их доступными с помощью рутовой подписи (root signature). Рутовая подпись также может содержать рутовые константы (root constants), рутовые дескрипторы (root descriptors) и статические семплеры.

Descriptors, descriptor heap, descriptor tables, root signature

Рисунок 1. Дескрипторы, куча дескрипторов, таблицы дескрипторов, рутовая подпись

На рисунке 1 показана взаимосвязь между дескрипторами, кучей дескрипторов, таблицами дескрипторов и рутовой подписью.

Код, описываемый на рисунке 1, выглядит так.

// the init function sets the shader registers
// parameters: type of descriptor, num of descriptors, base shader register
// the first descriptor table entry in the root signature in
// image 1 sets shader registers t1, b1, t4, t5
// performance: order from most frequent to least frequent used
D3D12_DESCRIPTOR_RANGE Param0Ranges[3]; 
Param0Ranges[0].Init(D3D12_DESCRIPTOR_RANGE_SRV, 1, 1); // t1 Param0Ranges[1].Init(D3D12_DESCRIPTOR_RANGE_CBV, 1, 1); // b1 Param0Ranges[2].Init(D3D12_DESCRIPTOR_RANGE_SRV, 2, 4); // t4-t5 
 
// the second descriptor table entry in the root signature
// in image 1 sets shader registers u0 and b2
D3D12_DESCRIPTOR_RANGE Param1Ranges[2]; Param1Ranges[0].Init(D3D12_DESCRIPTOR_RANGE_UAV, 1, 0); // u0 Param1Ranges[1].Init(D3D12_DESCRIPTOR_RANGE_CBV, 1, 2); // b2 
 
// set the descriptor tables in the root signature
// parameters: number of descriptor ranges, descriptor ranges, visibility
// visibility to all stages allows sharing binding tables
// with all types of shaders
D3D12_ROOT_PARAMETER Param[4]; 
Param[0].InitAsDescriptorTable(3, Param0Ranges, D3D12_SHADER_VISIBILITY_ALL); 
Param[1].InitAsDescriptorTable(2, Param1Ranges, D3D12_SHADER_VISIBILITY_ALL); // root descriptor
Param[2].InitAsShaderResourceView(1, 0); // t0
// root constants
Param[3].InitAsConstants(4, 0); // b0 (4x32-bit constants)
 
// writing into the command list
cmdList->SetGraphicsRootDescriptorTable(0, [srvGPUHandle]); 
cmdList->SetGraphicsRootDescriptorTable(1, [uavGPUHandle]);
cmdList->SetGraphicsRootConstantBufferView(2, [srvCPUHandle]);
cmdList->SetGraphicsRoot32BitConstants(3, {1,3,3,7}, 0, 4);

Показанный выше исходный код настраивает рутовую подпись таким образом, чтобы у нее было две таблицы дескрипторов, один рутовый дескриптор и одна рутовая константа. Код также показывает, что у рутовых констант нет косвенного обращения, они предоставляются напрямую вызовом SetGraphicsRoot32bitConstants. Они связаны напрямую с регистрами шейдера; нет ни самого буфера констант, ни дескриптора буфера констант, ни привязки. Рутовые дескрипторы имеют только один уровень косвенного обращения, поскольку они хранят указатель на память (дескриптор -> память), а таблицы дескрипторов имеют два уровня косвенного обращения (таблица дескрипторов -> дескриптор -> память).

Дескрипторы находятся в разных кучах в зависимости от их типов, например SV и CBV/SRV/UAV. Это обусловлено очень большими различиями между размерами дескрипторов разных типов на разных аппаратных платформах. Для каждого типа кучи дескрипторов должна быть выделена только одна куча, поскольку изменение кучи может быть крайне ресурсоемкой операцией.

В целом в DirectX 12 поддерживается заблаговременное выделение более одного миллиона дескрипторов, что вполне достаточно для целого игрового уровня. В прежних версиях DirectX выделение ресурсов происходило при работе драйвера на его собственных «условиях», а в DirectX 12 можно вообще избежать выделения ресурсов при выполнении. Это означает, что выделение дескрипторов больше не влияет на производительность.

Примечание. В процессорах Intel® Core™ 3-го поколения (Ivy Bridge) и 4-го поколения (Haswell) при использовании DirectX 11 и архитектуры драйверов WDDM (Windows Display Driver Model) версии 1.x ресурсы динамически сопоставлялись с памятью на основе ссылок на ресурсы в буфере команд с операцией сопоставления таблицы страниц. За счет этого удавалось избежать копирования данных. Динамическое сопоставление имело большое значение, поскольку эти архитектуры выделяли графическому процессору только 2 ГБ памяти (в семействе процессоров Intel® Xeon® E3-1200 v4 (Broadwell) выделялось больше).
В DirectX 12 и WDDM версии 2.x теперь невозможно переназначать ресурсы в виртуальное адресное пространство GPU по мере необходимости, поскольку ресурсам при создании необходимо назначать статический виртуальный адрес и этот виртуальный адрес невозможно изменить после создания. Даже если ресурс вытеснен из памяти GPU, он сохраняет свой виртуальный адрес для более позднего срока, когда он снова становится резидентным.
Поэтому ограничивающим фактором может стать общий объем памяти в 2 ГБ, выделяемый графическому процессору в семействах Ivy Bridge/Haswell.

Как сказано в предыдущей статье, идеально сбалансированное приложение может использовать сочетание всех типов привязок: рутовые константы, рутовые дескрипторы, таблицы дескрипторов для дескрипторов, получаемых на лету по мере выдачи вызовов отрисовки, а также динамическое индексирование крупных таблиц дескрипторов.

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

Предполагаемые изменения

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

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

Если постоянные данные предоставляются с помощью SetGraphicsRoot32BitConstants() в качестве рутовой константы, запись в рутовом дескрипторе не изменяется, но данные могут изменяться. Если они предоставляются с помощью дескриптора CBV == и таблицы дескрипторов, то дескриптор не изменяется, но данные могут изменяться.

В случае если нам нужно несколько представлений буфера констант (например, для двойной или тройной буферизации при рендеринге), CBV или дескриптор могут изменяться для каждого кадра в рутовой подписи.

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

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

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

В дальнейшем обсуждении изменение считается важным для привязки ресурсов, если оно связано со следующим:

  • Изменение или замена дескриптора в таблице дескрипторов, например CBV, RTV или UAV.
  • Изменение записи в рутовой подписи.

Дескрипторы в таблицах дескрипторов в семействах процессоров Haswell/Broadwell

На платформах Haswell/Broadwell при изменении одной таблицы дескрипторов в рутовой подписи затрачивается столько же ресурсов, сколько при изменении всех таблиц дескрипторов. Изменение одного аргумента приводит к тому, что оборудованию приходится создавать копию (версию) всех текущих аргументов. Количество рутовых параметров в рутовой подписи — это количество данных, для которых оборудованию приходится создавать новую версию (т. е. полную копию) при изменении любого подмножества.

Примечание.Для всех остальных типов памяти в DirectX 12, таких как кучи дескрипторов, ресурсы буферов и т. п., оборудование не создает новые версии.

Другими словами, на изменение всех параметров затрачивается примерно столько же ресурсов, сколько на изменение одного (см. [Лоритцен] и [MSDN]). Меньше всего ресурсов тратится, разумеется, если ничего не изменять, но это бесполезно.

Примечание.На другом оборудовании, где память разделяется на быструю и медленную, хранилище рутовых аргументов (root arguments) будет создавать новую версию только той области памяти, где изменился аргумент, то есть либо быстрой области, либо медленной области.

На платформах Haswell/Broadwell дополнительные затраты на изменение таблиц дескрипторов могут быть обусловлены ограниченным размером таблицы привязки в оборудовании.

Таблицы дескрипторов на этих аппаратных платформах используют аппаратные «таблицы привязки». Каждая запись таблицы привязки является одиночным значением DWORD, которое можно считать смещением в куче дескрипторов. В кольце размером 64 КБ может храниться 16 384 записи таблиц привязки.

Другими словами, объем памяти, потребляемый каждым вызовом отрисовки, зависит от суммарного количества дескрипторов, которые проиндексированы в таблице дескрипторов и на которые указывают ссылки в рутовой подписи.

Если мы исчерпаем 64 КБ памяти для записей таблицы привязки, драйвер выделит еще одну таблицу привязки размером 64 КБ. Переключение между этими таблицами приводит к остановке конвейера, как показано на рисунке 2.

Pipeline stall (courtesy of Andrew Lauritzen)

Рисунок 2. Остановка конвейера (рисунок Эндрю Лоритцена)

Предположим, что рутовая подпись ссылается на 64 дескриптора в таблице дескрипторов. Остановка будет происходить через каждые 16 384/64 = 256 вызовов отрисовки.

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

Следовательно, на платформах Haswell/Broadwell желательно, чтобы в таблицах дескрипторов было как можно меньше ссылок на дескрипторы.

Что это означает с точки зрения рендеринга? При использовании большего количества таблиц дескрипторов с меньшим числом дескрипторов в каждой таблице (и, следовательно, при большем количестве рутовых подписей) увеличивается количество объектов состояния конвейера (PSO), поскольку между такими объектами и рутовыми подписями поддерживаются отношения «один к одному».

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

 

 

 

Рутовые константы и дескрипторы в семействах процессоров Haswell/Broadwell

Как было сказано выше, с точки зрения затрачиваемых ресурсов изменение одной таблицы дескрипторов равноценно изменению всех таблиц дескрипторов. Аналогичным образом изменение одной рутовой константы или рутового дескриптора равноценно изменению всех (см. [Лоритцен]).

Рутовые константы реализованы с помощью «вещательных констант», которые представляют собой буфер, используемый оборудованием для заблаговременного заполнения регистров операционных блоков (EU). Поскольку значения доступны сразу же после запуска потока EU, можно добиться повышения производительности, храня постоянные данные в качестве рутовых констант, а не в таблицах дескрипторов.

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

Таблицы дескрипторов и рутовые константы/дескрипторы в семействах процессоров Haswell/Broadwell

Мы рассмотрели реализацию таблиц дескрипторов, рутовых констант и дескрипторов. Теперь можно ответить на основной вопрос этой статьи: «Что предпочтительнее использовать?». В силу ограниченного размера аппаратной таблицы привязки и возможных остановок, связанных с превышением этого ограничения, изменение рутовых констант и рутовых дескрипторов представляется менее ресурсоемкой операцией на платформах Haswell/Broadwell, поскольку им не требуется аппаратная таблица привязки. Наибольший выигрыш при следовании этому принципу достигается в случае, если данные изменяются при каждом вызове отрисовки.

Статические семплеры в семействах процессоров Haswell/Broadwell

Как было описано в предыдущей статье, можно определить семплеры в рутовой подписи или непосредственно в шейдере с помощью языка рутовой подписи HLSL. Такие семплеры называются статическими.

На платформах Haswell/Broadwell драйвер помещает статические семплеры в обычную кучу семплеров. Это равноценно помещению их в дескрипторы вручную. На других аппаратных платформах семплеры помещаются в регистры шейдера, поэтому статические семплеры можно компилировать непосредственно в шейдер.

В целом статические семплеры обеспечивают высокую производительность на любых платформах, поэтому можно их использовать без каких-либо оговорок. Тем не менее на платформах Haswell/Broadwell существует вероятность, что при увеличении количества дескрипторов в таблице дескрипторов мы будем чаще сталкиваться с остановкой конвейера, поскольку аппаратная таблица дескрипторов содержит только 16 384 ячейки.

Вот синтаксис статического семплера в HLSL.

StaticSampler( sReg,
        [ filter = FILTER_ANISOTROPIC, 
        addressU = TEXTURE_ADDRESS_WRAP,
        addressV = TEXTURE_ADDRESS_WRAP,
        addressW = TEXTURE_ADDRESS_WRAP,
        mipLODBias = 0.f,   maxAnisotropy = 16,
        comparisonFunc = COMPARISON_LESS_EQUAL,
        borderColor = STATIC_BORDER_COLOR_OPAQUE_WHITE,
        minLOD = 0.f, maxLOD = 3.402823466e+38f,
        space = 0, visibility = SHADER_VISIBILITY_ALL ])

Большая часть параметров не нуждается в пояснении, поскольку они аналогичны используемым на уровне C++. Основное различие заключается в цвете границ: на уровне C++ поддерживается полный цветовой диапазон, тогда как на уровне HLSL доступен только непрозрачный белый, непрозрачный черный и прозрачный черный. Пример статического шейдера.

StaticSampler(s4, filter=FILTER_MIN_MAG_MIP_LINEAR)

Skylake

В Skylake поддерживается динамическое индексирование всей кучи дескрипторов (около 1 миллиона ресурсов) в одной таблице дескрипторов. Это означает, что одной таблицы дескрипторов может быть достаточно для индексирования всей доступной памяти кучи дескрипторов.

По сравнению с прежними архитектурами нет необходимости настолько часто изменять записи таблиц дескрипторов в рутовой подписи. Кроме того, можно также уменьшить количество рутовых подписей. Разумеется, для разных материалов потребуются разные шейдеры и, следовательно, разные объекты состояния конвейера (PSO). Но эти объекты PSO могут ссылаться на одни и те же рутовые подписи.

Современные графические движки используют меньше шейдеров, чем предыдущие версии в DirectX 9 и DirectX 11, поэтому можно избежать расходования ресурсов на смену шейдеров и связанных состояний, уменьшить количество рутовых подписей и (соответственным образом) объектов PSO, что обеспечит прирост производительности на любой аппаратной платформе.

Заключение

Если говорить о платформах Haswell/Broadwell и Skylake, то рекомендации по повышению производительности приложений DirectX 12 зависят от используемой платформы. Для Haswell/Broadwell желательно, чтобы количество дескрипторов в таблице дескрипторов было небольшим, тогда как для Skylake рекомендуется, чтобы таблицы дескрипторов содержали как можно больше дескрипторов, но самих таблиц было меньше.

Для достижения оптимальной производительности разработчик приложений может проверять тип аппаратной платформы при запуске, а затем соответственным образом выбирать способ привязки ресурсов. (Пример определения GPU, показывающий, как обнаруживать различную архитектуру оборудования Intel®, доступен по адресу https://software.intel.com/ru-ru/articles/gpu-detect-sample/.) Выбор способа привязки ресурсов определяет, каким образом будут записаны шейдеры системы.

Об авторе

Вольфганг Энгель — директор компании Confetti. Компания Confetti занимается исследованиями в области графики реального времени и является поставщиком услуг для кинематографии и отрасли компьютерных игр. До организации компании Confetti Вольфганг более 4 лет работал в должности ведущего графического программиста в студии RAGE — основной технологической группе компании Rockstar. Вольфганг — основатель и редактор серий книг ShaderXи GPUPro, обладатель звания Microsoft MVP, автор нескольких книг и статей, посвященных рендерингу в реальном времени. Он регулярно публикует свои материалы на веб-сайтах и проводит выступления на конференциях. Одна из книг, редактором которой он является (ShaderX4), получила в 2006 году премию Game developer Front line. Вольфганг входит в состав нескольких отраслевых консультативных советов, в частности в консультативный совет Майкрософт по графическим решениям DirectX 12. Вольфганг активно участвует в разработке ряда перспективных стандартов для игровой отрасли. Следите за его публикациями в Twitter: wolfgangengel. Веб-сайт Confetti: www.conffx.com.

Благодарности

Благодарю редакторов этой статьи!

  • Эндрю Лоритцен (Andrew Lauritzen)
  • Робин Грин (Robin Green)
  • Михал Валиент (Michal Valient)
  • Дин Калвер (Dean Calver)
  • Юул Йостен (Juul Joosten)
  • Михал Дробот (Michal Drobot)

Ссылки и полезные материалы

** Программное обеспечение и нагрузки, использованные в тестах производительности, могли быть оптимизированы для достижения высокой производительности на микропроцессорах Intel. Тесты производительности, такие как SYSmark* и MobileMark*, проводятся на определенных компьютерных системах, компонентах, программах, операциях и функциях. Любые изменения любого из этих элементов могут привести к изменению результатов. При выборе приобретаемых продуктов следует обращаться к другой информации и тестам производительности, в том числе к тестам производительности определенного продукта в сочетании с другими продуктами.

Дополнительные сведения об оптимизации компиляторов см. в нашем уведомлении об оптимизации.

Передача цветного изображения с помощью Intel® RealSense™ SDK

$
0
0

Загрузить пример кода  [Zip: 19 KB]

Содержание

Введение

Вы задумали создать простое приложение с потоком цветного изображения, использующее камеру Intel® RealSense™и Intel® RealSense™ SDK, или просто собираетесь использовать поток цветного изображения в одном из приложений? Вам нужно понятное приложение, простое в отслеживании его работы, действующее напрямую, без огромного объема дополнительного кода, отвлекающего от того, чему вы хотите научиться? В этом случае вам повезло, поскольку именно такого результата я попытался добиться здесь: я старался создать простой, но эффективный пример приложения и документ, описывающий использование камеры и SDK Intel RealSense. 

Этот пример был написан с помощью Intel RealSense SDK R4 и Visual Studio* на языке C#, он был протестирован в выпуске R5.  Для него требуется камера Intel RealSense F200.

Структура проекта

В этом простом приложении я попытался отделить функциональность Intel RealSense SDK от кода уровня графического пользовательского интерфейса Windows* Form, чтобы разработчикам было удобнее сосредоточиться на функциональности SDK, относящейся к поточной передаче изображения.  Для этого я создал на C# класс-оболочку (RSStreaming), заключив в него несколько классов Intel RealSense SDK. 

Приложение Windows Form содержит лишь несколько кнопок и элемент управления PictureBox, в котором отображается поток цветного изображения.

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

Структура проекта опирается на использование событий для передачи данных, вследствие чего можно обойтись без тесных связей. Был создан вспомогательный класс событий RSNewImageArg, наследующий от EventArg. Он используется для публикации текущего кадра из камеры в клиентское приложение.

Начало работы

Для работы потребуется камера Intel RealSense F200. Также требуется Intel RealSense SDK версии R4 или более поздней версии. Помимо этого, на компьютер необходимо установить соответствующий пакет Depth Camera Manager (DCM). SDK и F200 DCM можно загрузить здесь

Требования

Требования к оборудованию

  • Процессор Intel® Core™ 4-го поколения (на основе микроархитектуры Haswell).
  • 8 ГБ свободного места на жестком диске.
  • Камера Intel RealSense F200 (ее необходимо подключить к порту USB 3).

Требования к программному обеспечению

  • 64-разрядная версия операционной системы Microsoft Windows 8.1 или Windows 10.
  • Microsoft Visual Studio* 2010–2015 с последней версией пакета обновления.
  • Microsoft .NET* 4.0 Framework для разработки на C#.
  • Unity* 5.x или более поздней версии для разработки игр на движке Unity.

RSNewImageArg.CS

RSNewImageArg является производным от класса C# EventArgs. Как видите, это небольшой класс-оболочка, к которому добавлен один частный элемент данных. Этот частный элемент данных Bitmap _bitMap содержит текущее растровое изображение, извлеченное из потока камеры.

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

RSStreaming.CS

RSStreaming — это класс-оболочка (своего рода «движок») с данными потока цветного изображения из камеры Intel RealSense. Я написал этот класс, преследуя следующие цели.

  • Ясно и четко выделить как можно больше функций Intel RealSense SDK и как можно дальше отделить их от клиентского приложения.
  • Попытаться предоставить в коде комментарии, чтобы помочь читателю разобраться в том, что именно делает код.

Ниже описываются все функции, входящие в класс RSSpeechEngine.

public event EventHandler<RSNewImageArg> OnStreamingImage

Событие OnStreamingImage служит для переключения сообщения обратно к клиентскому приложению, сообщая ему о том, что новое цветное растровое изображение готово к показу. Клиент создает обработки событий для обработки объекта RSNewImageArg.

public bool Initialized

Свойство метода получения используется в качестве флага, указывая, что класс RSStreaming инициализирован.

public bool IsStreaming

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

public void StartStreaming()

Проверяет, инициализирован ли класс. Если нет, вызывает InitCamera, чтобы убедиться в том, что класс запущен и работает. Затем эта функция вызывает функцию _senseManager.StreamFrames( … ). 

Если вы успели ознакомиться с достаточным количеством материалов о разработке приложений для Intel RealSense, то, вероятно, вы обратили внимание, что получение данных с камеры зачастую осуществляется в циклах while. Например, приблизительно так.

while (!Stop)
{
   /* Wait until a frame is ready: Synchronized or Asynchronous */
   if (sm.AcquireFrame(Synced).IsError())
      break;
 
  /* Display images */
   PXCMCapture.Sample sample = sm.QuerySample();
 
   /* Render streams */
   EventHandler<RenderFrameEventArgs> render = RenderFrame;
   PXCMImage image = null;
   if (MainPanel != PXCMCapture.StreamType.STREAM_TYPE_ANY && render != null)
   {
      image = sample[MainPanel];
      render(this, new RenderFrameEventArgs(0, image));
   }
 
   if (PIPPanel != PXCMCapture.StreamType.STREAM_TYPE_ANY && render != null)
     render(this, new RenderFrameEventArgs(1, sample[PIPPanel]));
 
   /* Optional: Set Mirror State */
   mirror = Mirror ? PXCMCapture.Device.MirrorMode.MIRROR_MODE_HORIZONTAL : 
 
PXCMCapture.Device.MirrorMode.MIRROR_MODE_DISABLED;
   if (mirror != sm.captureManager.device.QueryMirrorMode())
      sm.captureManager.device.SetMirrorMode(mirror);
 
   sm.ReleaseFrame();
 
   /* Optional: Show performance tick */
   if (image!=null)
      timer.Tick(PXCMImage.PixelFormatToString(image.info.format)+""+image.info.width+"x"+image.info.height);
}

Да, это солидная порция кода.  Этот код, возможно, делает гораздо больше, чем мой пример приложения, но я всего лишь хочу сказать, что у меня цикл while не используется таким образом. В моем приложении используется функция StreamFrames(…). Эта функция обрабатывает цикл while внутри себя, а для каждого кадра она включает событие, на которое подписывается RSStreamingRGB. Работает это так.

  1. Запускаем поток PXCMSenseManager.StreamFrames(…).
  2. Ловим событие обработчиком событий.
  3. По окончании поточной передачи вызываем PXCMSenseManager.Close( ).

Мне нравится этот подход, потому что не хочется вручную возиться с циклом while, зная, когда и как останавливать цикл. Лучше пусть SDK позаботится об этом вместо меня. Вы увидите, как устроена эта методика, когда я буду рассказывать о функции InitCamera(), поэтому я не стану рассказывать про нее здесь. Просто убедитесь в том, что вы поняли, как можно передавать поток данных и разрешить SDK управлять циклом над необработанными данными, поступающими из камеры.

После вызова StreamFrames я задаю для логического флага _isStreaming значение true, чтобы уведомить класс и клиентское приложение о начале передачи потока.

public void StopStreaming ( )

Остановка передачи потока — действие, противоположное StartStreaming. Эта функция дает команду SDK для остановки передачи потока данных из камеры и вызывает Dispose() для уничтожения объектов данных.   

private void InitCamera ( )

InitCamera() создает экземпляр PXCMSenseManager и включает нужный нам тип потока. Как видите, я указываю поток цветного изображения с разрешением 320 x 240 при скорости 30 кадров в секунду.  

Если помните, я говорил о возможности использовать событие из PXCMSenseManger, чтобы сообщить классу о доступности нового кадра данных цветного изображения available. Для этого используется класс событий PXCMSenseMananger.Handler. Процесс достаточно прост: создаем экземпляр класса Handler, назначаем его обработчику событий через onNewSample, затем инициализируем объект PXCMSenseManager; _senseMananger с классом обработчика.

Затем задаем флагу _initialized значение true. Как было сказано выше, с помощью этого флага мы сообщаем либо этому классу, либо клиентскому приложению о том, что класс RSStreaming инициализирован.

private pxcmStatus OnNewSample( )

Это обработчик событий для объекта PXCMSenseMananger.Handler(). Если помните, в функции InitCamera() я задаю обработчик событий объектов для этой функции.

Обработчик событий должен соответствовать заданной подписи функции.  Функция должна возвращать значение pxcmStatus и принимать два параметра.

  • Mid.Идентификатор потока. Если посредством функции EnableVideoStreams запрошено несколько потоков, то это может быть PXCMCapture.CUID+0, PXCMCapture.CUID+1 и т. д.
  • Sample. Доступное изображение.

Нужно преобразовать объект PXCMCapture.Sample в пригодное к использованию растровое изображение, которое может быть показано клиентским приложением.

Сначала я проверяю, что объект sample.color не является пустым и что внутреннее растровое изображение класса _colorImageData также не является пустым.  Нужно убедиться в том, что _colorImageData не содержит никаких данных, а если содержит, то их нужно высвободить.

Затем нужно использовать объект sample.colors для заполнения _colorImagedata. Это, по сути, объект метаданных для объекта цветного изображения PXCMCapture.Sample. После этого можно перейти к созданию растрового изображения, указав его размер.

Получив растровое изображение и убедившись в том, что оно не пустое, я включаю событие OnStreamingImage, указывая источник события и новый объект RSNewImageArg.

Наконец, нам НЕОБХОДИМОвысвободить текущий кадр из объекта PXCMSenseMananger, а также, поскольку это требуется подписью функции, возвратить pxcmStatus. В этом месте можно было добавить код для обработки исключений, но я предпочел этого не делать ради простоты. Если бы я написал такой код, то мог бы возвращать другое состояние pxcmStatus, но я просто возвращаю состояние успеха.

private void Dispose ( )

Dispose() выполняет очистку. Я проверяю, что диспетчер не является пустым и что он был инициализирован. Если оба условия выполнены, то я взываю его метод очистки. Я проверяю, что растровое изображение RSStreaming не является пустым, и очищаю его. Затем я везде устанавливаю значение null.

MainForm.CS

Главная форма — это графический пользовательский интерфейс, в котором отображается поток цветного изображения. В нем можно управлять объектом RSStreaming. У него две глобальных переменных: экземпляр RSStreamingRGB и растровое изображение. Растровое изображение будет содержать текущее изображение из текущего кадра, который отправлен классом RSStreamingRGB.

public MainForm( )

Конструктор форм. Он создает новый объект RSSTreamingRGB и предоставляет событию OnStreamingImage обработчик событий.

private void btnStream_Click( )

Обработчик событий при нажатии кнопки Start Streaming. Дает команду объекту _rsStreaming на начало передачи потока путем вызова функции StartStreaming() этого объекта.

private void btnStopStream_Click( )

Обработчик событий при нажатии кнопки Stop Streaming. Дает команду объекту _rsStreaming на остановку передачи потока путем вызова функции StopStreaming() этого объекта.

private void UpdateColorImageBox( object source, RSNewImageArg e )

UpdateColorImageBox — обработчик событий для события _rsStream.OnStreamingImage.  Проверяет, что аргумент newImage не пуст и присваивает в этом случае _currentBitMap новому растровому изображению, используя newImage в качестве источника растрового изображения.

Если не создать новое растровое изображение, то _currentBitMap формы будет указывать на первоначальное растровое изображение, созданное пакетом SDK. Из-за этого могут возникнуть проблемы при вызове метода RSStreaming.Dispose. В клиентской программе имеется рамка рисунка, а в этой рамке отображается изображение, которое берется из SDK. Если при активной форме и рамке рисунка я попробую вызвать RSStreaming.Dispose, высвобождающий ресурсы SDK, то получится аварийный сбой, поскольку удаляется исходное изображение для рамки рисунка.

После назначения нового изображения для _currentBitMap я вызываю pictureBox.Invalidate() и тем самым запускаю событие Paint рамки рисунка.

private void pictureBox_Paint( object sender, PaintEventArgs e )

Это обработчик события Paint рамки рисунка, он переключается вызовом pictureBox.Invalidate(). Он дает команду на перерисовку рамки рисунка с использованием текущего исходного изображения.

Сначала проверяем, что _currentBitMap не пуст, а затем задаем для него наиболее позднее растровое изображение, которое сохраняется в _currentBitMap.

private void btnExit_Click( )

Здесь все элементарно. Просто вызываем Close(). Нет необходимости обрабатывать очистку, поскольку все это происходит в методе MainForm_FormClosing.

private void bMainForm_FormClosing( )

Это событие форм, закрывающее обработчик событий. При вызове метода Close() в любой заданной функции вызывается событие FormClosing. Чтобы не дублировать код, я разместил здесь весь код очистки. Проверяем, что _rsStream не пуст и что идет передача потока. Если эти условия выполнены, то вызываем _rsStream.StopStreaming(). Нет необходимости вызывать метод очистки для _rsStreaming, поскольку все необходимое уже сделано в StopStreaming.

Заключение

Надеюсь, с помощью этой статьи и примера кода вы лучше поняли, как применять Intel RealSense SDK для создания простых приложений с передачей цветного изображения.  Я стремился продемонстрировать, что это можно сделать в простом и понятном приложении: в нем реализованы все элементы, необходимые для успешного создания вашего собственного приложения для передачи цветного изображения.

Если вы считаете, что я что-то упустил или привел недостаточно понятные пояснения в какой-то области, ЛИБО если вы считаете, что можно было добиться нужной цели иным, более правильным способом, то напишите мне по адресу rick.blacker@intel.comили оставьте комментарий к этой статье.

Об авторе

Рик Блэкер (Rick Blacker) — опытный инженер по программному обеспечению, он уже много лет занимается созданием решений для приложений на основе баз данных.  Недавно Рик перешел в команду, занимающуюся технологией Intel RealSense, и помогает пользователям осваивать эту технологию. 

Параллельные функции шума и случайных чисел для ядер OpenCL™

$
0
0

Download Now  Noise.zip

Об образце кода

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

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

Введение и мотивация

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

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

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

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

В функциях уровня ядра OpenCL в образце кода Noise применяется подход, более подходящий к задействованному в OpenCL алгоритму разделения работы на параллельные операции.

Создание шума и случайных чисел для OpenCL

В OpenCL глобальное рабочее пространство (массив рабочих элементов) определяется с помощью одного, двух или трех измерений. Каждый рабочий элемент в этом глобальном пространстве обладает уникальным набором идентифицирующих целочисленных значений, соответствующих координатам по осям X, Y и Z в глобальном пространстве.

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

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

kernel void genRand()
{
               uint          x = get_global_id(0);
               uint          y = get_global_id(1);
 
               uint          rand_num = ParallelRNG2( x, y );
 
               ...

Рисунок 1. Пример использования случайных чисел (два измерения)

 

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

kernel void multi2dNoise( float fScale, float offset )
{
float         fX = fScale * get_global_id(0);
float         fY = fScale * get_global_id(1);
float         fZ = offset;
 
float         randResult = Noise_3d(  fX,  fY,  fZ );
...

Рисунок 2. Пример использования алгоритма шума Перлина (три измерения)

 

Ограничения

В функциях Noise_2d и Noise_3d используется один и тот же базовый алгоритм шума Перлина, но различается реализация на основе рекомендаций Перлина. (См. первую ссылку в списке справочных материалов.) В образце Noise только Noise_3d используется в примере noise, а тестовое ядро Noise_2d включено в файл Noise.cl для читателей, желающих изменить этот пример и поэкспериментировать с ним.

Функции Noise_2d и Noise_3d следует вызывать со входными значениями с плавающей запятой. Значения должны охватывать какой-либо диапазон, например (0.0, 128.0), чтобы задать размер «таблицы» (см. рисунок 3) случайных значений. Читателям следует рассмотреть пример с облаками, чтобы понять, как можно преобразовать шум Перлина в разнообразные изображения «естественного вида».

Функция ParallelRNG по умолчанию, используемая в тесте random, предоставляет случайные (и выглядящие таковыми) результаты, но не является самым быстрым алгоритмом генератора случайных чисел. Эта функция построена на основе «хеша Вонга», который изначально не предназначался для использования в качестве генератора случайных чисел. Тем не менее некоторые распространенные функции генераторов случайных чисел (закомментированный пример в файле Noise.cl) показывали видимую повторяемость при заполнении двухмерных изображений, особенно в битах младшего разряда результатов. Читатели могут поэкспериментировать и с другими (более быстрыми) функциями генераторов случайных чисел.

Используемая по умолчанию функция ParallelRNG создает в качестве результатов только 32-битные целые числа без знака. Если требуются значения с плавающей запятой для диапазона, такого как (0.0, 1.0), то приложение должно применить сопоставление для этого диапазона. Образец randomсопоставляет случайный целочисленный результат без знака с диапазоном (0, 255) для создания значений пикселей в оттенках серого. Для этого просто применяется двоичная операция AND, чтобы выбрать 8 бит.

Используемая по умолчанию функция ParallelRNG не будет создавать все 4 294 967 296 (2^32) целочисленных значений без знака для последовательных вызовов на основе созданного ранее значения. Для каждого отдельного начального значения величина псевдослучайных последовательностей (циклов) может составлять от всего 7000 уникальных значений до приблизительно 2 миллиардов значений. Функция ParallelRNG создает около 20 различных циклов. Автор считает маловероятным, что какому-либо рабочему элементу ядра OpenCL может потребоваться больше последовательно созданных случайных чисел, чем образуется в самом маленьком цикле.

Двухмерные и трехмерные версии этой функции —ParallelRNG2 и ParallelRNG3 — используют «смешение» циклов путем применения двоичной операции XOR между результатом предыдущего вызова ParallelRNG и следующим входным значением, из-за чего изменяются длины циклов. Тем не менее такое измененное поведение не подвергалось подробному анализу, поэтому читателю рекомендуется внимательно убедиться в том, что функции ParallelRNG отвечают потребностям приложения.

Структура проекта

В этом разделе приводятся только основные элементы исходного кода образца приложения.

NoiseMain.cpp:

main()
основная входная функция. После разбора параметров командной строки она инициализирует OpenCL, собирает программу OpenCL из файла Noise.cl, подготавливает одно из ядер к запуску и вызывает ExecuteNoiseKernel(), а затем ExecuteNoiseReference(). Проверив, что эти две реализации выдают одинаковые результаты, main()выдает информацию о времени работы каждой из этих функций и сохраняет изображения, получившиеся в результате их работы.

ExecuteNoiseKernel()
Настройка и запуск выбранного ядра Noise в OpenCL.

ExecuteNoiseReference()
Настройка и запуск выбранного эталонного кода Noise на языке C.

Noise.cl:

defaut_perm[256]
Таблица случайных значений 0–255 для ядра трехмерного шума Перлина. Для дополнительного повышения случайности эту таблицу можно сформировать и передать в ядро шума Перлина.

grads2d[16]
16 однородно распределенных единичных векторов, градиенты для ядра двухмерного шума Перлина.

grads3d[16]
16 векторных градиентов для ядра трехмерного шума Перлина.

ParallelRNG()
Генератор псевдослучайных чисел, один проход для одного входного значения. Альтернативная функция генератора случайных чисел закомментирована, но добавлена в файл на случай, если у читателей возникнет желание протестировать функцию, которая работает быстрее, но выдает худшие результаты.

ParallelRNG2()
Генератор случайных чисел, делающий 2 прохода для 2 входных значений.

ParallelRNG3()
Генератор случайных чисел, делающий 3 прохода для 3 входных значений.

weight_poly3(), weight_poly5() и WEIGHT()
Это альтернативные функции веса, используемые алгоритмом шума Перлина для обеспечения непрерывности градиентов. Вторая (предпочитаемая) функция также обеспечивает непрерывность второй производной. Макрос WEIGHTвыбирает, какая функция используется.

NORM256()
Макрос, преобразующий диапазон (0, 255) в (-1.0, 1.0).

interp()
Билинейная интерполяция, использующая OpenCL.

hash_grad_dot2()
Выбирает градиент и вычисляет скалярное произведение со входными значениями XY в составе функции шума Перлина Noise_2d.

Noise_2d()
Генератор шума Перлина с двумя входными значениями.

hash_grad_dot3()
Выбирает градиент и вычисляет скалярное произведение со входными значениями XYZ в составе функции шума Перлина Noise_3d.

Noise_3d()
Генератор шума Перлина с тремя входными значениями.

cloud()
Создает один пиксель «облачного» выходного изображения для CloudTestс помощью Noise_3d.

map256()
Преобразует выходной диапазон шума Перлина (-1.0, 1.0) в диапазон (0, 255), необходимый для получения пикселей в оттенках серого.

CloudTest()
Тест с созданием изображения облака. Параметр sliceпередается в функцию cloud, чтобы код системы мог создавать другие изображения облаков.

Noise2dTest()
Тест Noise_2dне используется по умолчанию.

Noise3dTest()
Тест Noise_3d — функции шума Перлина по умолчанию. Использует map256для получения значений пикселей изображения в оттенках серого.

RandomTest()
Тест ParallelRNG3использует байт младшего разряда целочисленного результата без знака для получения изображения в оттенках серого.

Предоставляются два файла решений Microsoft Visual Studio для Visual Studio версий 2012 и 2013.  Это файлы Noise_2012.sln и Noise_2013.sln.   Если читатель использует более новую версию Visual Studio, должно быть возможно использовать функцию обновления решений и проектов Visual Studio для создания нового решения на основе этих файлов.

В обоих решениях предполагается, что в системе установлен компонент Intel® OpenCL™ Code Builder.

Управление образцом

Образец можно запустить из командной строки Microsoft Windows* из папки, в которой находится EXE-файл.

Noise.exe<параметры>

Параметры

-hили --help
Отображение справки в командной строке. Демонстрации при этом не запускаются.

-tили --type [ all | cpu | gpu | acc | default |
<константа типа устройства OpenCL>
Выбор типа устройства, для которого запускается ядро OpenCL. Значение по умолчанию: all.

<константа типа устройства OpenCL>

CL_DEVICE_TYPE_ALL | CL_DEVICE_TYPE_CPU | CL_DEVICE_TYPE_GPU |
CL_DEVICE_TYPE_ACCELERATOR | CL_DEVICE_TYPE_DEFAULT

-pили --platform<число или строка> 
Выбор используемой платформы. При запуске демонстрации выводится список всех номеров и названий платформ. Справа от используемой платформы будет указано [Selected]. При использовании строки укажите достаточно букв для уникального распознавания названия платформы. Значение по умолчанию: Intel.

-dили --device<число или строка>
Выбор устройства, на котором выполняются ядра OpenCL, по номеру или имени. При запуске демонстрации выводится список всех номеров и названий устройств на используемой платформе. Справа от текущего устройства будет указано [Selected]. Значение по умолчанию: 0.

-rили --run [ random | perlin | clouds ]
Выбор демонстрации функции для запуска. У генератора случайных чисел, алгоритма шума Перлина и генератора изображения облака есть демонстрационные ядра. Значение по умолчанию: random.

-sили --seed<целое число>
Целочисленное входное значение, в зависимости от которого изменяется результат работы алгоритма. Значение по умолчанию: 1.

Noise.exeвыводит время работы ядра OpenCL и эталонного эквивалентного кода C, а также имена выходных файлов обоих алгоритмов. По завершении вывода информации программа ожидает нажатия пользователем клавиши ВВОД перед выходом. Обратите внимание, что функции эталонного кода на C не были оптимизированы, их цель состоит лишь в проверке правильности кода ядра OpenCL.

Анализ результатов

После завершения работы Noise.exeпросмотрите файлы изображений в формате BMP OutputOpenCL.bmpи OutputReference.bmpв рабочей папке, чтобы сравнить результаты кода OpenCL и C++. Эти два изображения должны быть одинаковыми, хотя возможны весьма незначительные различия между двумя изображениями шума Перлина или между двумя изображениями облаков.

Результат работы алгоритма noise (шум Перлина) должен выглядеть, как показано на рисунке 3.

Рисунок 3. Результат работы алгоритма шума Перлина

Результат работы алгоритма random (генератор случайных чисел) должен выглядеть, как показано на рисунке 4.

Рисунок 4. Результат работы генератора случайных чисел

Результат работы алгоритма cloud (облака) должен выглядеть, как показано на рисунке 5.

Рисунок 5. Результат работы алгоритма создания облаков

Справочные материалы

  1. К. Перлин (Perlin, K.) «Улучшение шума». http://mrl.nyu.edu/~perlin/paper445.pdf
  2. «Хеширование 4-байтовых целых чисел». http://burtleburtle.net/bob/hash/integer.html
  3. М. Овертон (Overton, M. A.), «Быстрые высококачественные параллельные генераторы случайных чисел», веб-сайт Dr. Dobb’s (2011 г.). http://www.drdobbs.com/tools/fast-high-quality-parallel-random-number/229625477
  4. Реализация и использование библиотеки цифрового генератора случайных чисел (DRNG) Intel®https://software.intel.com/ru-ru/articles/intel-digital-random-number-generator-drng-library-implementation-and-uses?utm_source=Email&utm_medium=IDZ
  5. Лицензионное соглашение корпорации Intel на использование образцов исходного кода. https://software.intel.com/ru-ru/articles/intel-sample-source-code-license-agreement/
  6. Intel® OpenCL™ Code Builder.https://software.intel.com/ru-ru/opencl-code-builder

 

Наложение изображения отсканированного лица на трехмерную модель в Intel® RealSense™ SDK

$
0
0

В этом примере используется Intel® RealSense™ SDK для сканирования лица пользователя и наложения изображения лица на существующую трехмерную модель персонажа. Код написан на C++ и использует DirectX *. Для этого образца требуется пакет Intel® RealSense™ SDK R5 или более поздней версии, который можно загрузить здесь.

Пример доступен по адресу https://github.com/GameTechDev/FaceMapping.

Сканирование

В SDK WM5 модуль сканирования лиц значительно улучшен. В частности, усовершенствовано следующее.

  • Улучшенные данные цвета.
  • Повышена однородность сканирования за счет предоставления подсказок, помогающих идеально сориентировать лицо пользователя в начальном положении.
  • Данные реперных точек на лице, указывающие на расположение основных черт лица.

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

Реализация сканирования в этом образце помогает пользователю сориентировать лицо в правильное положение с помощью подсказок Intel® RealSense™ SDK. После выполнения требований по правильному расположению лица в программе становится активной кнопка запуска сканирования.

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

Выходные данные сканирования — это OBJ-файл модели и связанная с ним текстура, которая будет использована на этапе наложения лица в этой программе.


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

Рисунок 2. Трехмерное изображение, полученное при сканировании. На изображении справа показаны реперные точки. Обратите внимание, что сканируется только лицо, а не вся голова. Данные цвета берутся из первого кадра сканирования и затем проецируются на трехмерную модель лица. При таком подходе обеспечивается высокое качество цветопередачи, но текстура растягивается по боковым сторонам головы

Наложение изображения лица на трехмерную модель

Вторая часть программы использует данные цвета отсканированного лица пользователя и данные геометрии и накладывает их на существующую модель головы. Задача состоит в том, чтобы создать полную модель головы, используя отсканированное изображение лица. При этом вместо «склейки» отсканированной модели лица с моделью головы выполняется изменение (смещение) геометрии существующей модели головы. Шейдер выполняет смещение вертексов и смешение цветов между моделями головы и лица. Такое смешение можно выполнять либо каждый раз при рендеринге модели головы, либо однократно, с кэшированием результатов. В этом примере программы поддерживаются оба этих подхода.

Описываемая процедура наложения модели лица на модель головы включает следующие основные этапы.

  1. Рендеринг отсканированной модели лица с помощью матрицы ортогональной проекции для создания карты смещения и цветовой карты.
  2. Создание матрицы для проецирования определенной модели головы на полученные карты смещения и цветов. Эта проекционная матрица учитывает масштабирование и преобразования, заданные с помощью данных реперных точек на лице.
  3. Рендеринг модели головы с помощью проекционной матрицы для сопоставления положений вертексов с координатами текстуры на картах смещения и цветов.
  4. Применение полученных карт для деформации вершин и раскрашивания пикселей. Смешение между цветовой картой и изначальной текстурой контролируется с помощью карты управления, создаваемой пользователем.
  5. (Необязательно.) Можно использовать эти же алгоритмы смещения и смешения для создания модели со смещением и единой полной цветовой текстуры, содержащей все эффекты смешения.

Ресурсы

В этом примере используются следующие графические ресурсы.

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

Карта черт лица.Текстура, наложенная на двухмерную UV-развертку модели головы, влияющую на яркость головы.

Карта деталей.Повторяющаяся текстура, накладывающая дополнительную детализацию на карту черт лица.

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

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

  • Канал красного цвета — величина смещения вертексов по оси Z. Если это значение равно нулю, вертекс располагается на модели головы. Если это значение равно единице, то положение вертекса по оси Z изменяется на основе полученной карты смещения. При промежуточных значениях положение изменяется на промежуточную величину.
  • Канал зеленого цвета — величина смешения между цветом общей текстуры головы и цветом на полученной цветовой карте. Значение 0 — используется только цвет общей текстуры головы, значение 1 — только цвет лица.
  • Канал синего цвета — дополнительный канал для челюстной кости. Его можно использовать вместе с каналом зеленого цвета, чтобы применять к челюстной области лица отдельный цвет вместо цвета общей текстуры головы. Это может быть полезно, если пользователь носит бороду.

Все карты создаются в двухмерном UV-пространстве модели головы.


Рисунок 3. Модель головы, лицо с высокой плотностью мозаичной сетки («тесселяции»). Отсканированное лицо будет извлечено из области высокого разрешения.


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


Рисунок 5. Карта передачи цветов (слева) и карта передачи цветов, наложенная на модель головы (справа). Эта карта определяет интенсивность двух выбранных пользователем цветов кожи

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

Карты смещения и цветов

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

Рисунок 7. Карты смещения и цветов, созданные из отсканированной модели лица

Матрица проецирования карт

Теперь мы используем данные реперных точек с отсканированной модели лица и модели головы для создания матрицы преобразования. Цель этого шага — преобразование координат вертексов модели головы (в пространстве модели) в координаты текстуры (в пространстве карты смещения и цветовой карты). Этот шаг мы называем матрицей проецирования карт, поскольку здесь, по сути, карты смещения проецируются на модель головы.

Матрица проецирования карт включает перенос и масштабирование.

  • Масштабирование.Коэффициент масштабирования вычисляется на основе соотношения расстояния между глазами на отсканированной модели лица (по координатам на проецируемой карте) и на модели головы.
  • Перенос.Перенос вертексов вычисляется с помощью данных реперных точек на модели лица и на отсканированной модели лица. При переносе точка, находящаяся ровно посередине между глазами на модели головы, выравнивается с соответствующей точкой на карте смещения. Для вычисления этой средней точки мы используем реперные точки глаз, получаем среднюю точку между ними, а затем преобразуем ее с помощью матрицы ортогональной проекции, которую мы использовали при получении карты смещения и цветовой карты.
  • Поворот.В этом примере предполагается, что отсканированная модель лица уже выровнена по осям, ее не требуется поворачивать. Тем не менее в графическом пользовательском интерфейсе предусмотрены элементы управления поворотом для удобства пользователей.
  •  

Рисунок 8. Полученная цветовая карта (слева) ортогонально проецируется на модель головы. Карта преобразуется и масштабируется таким образом, чтобы совпали желтые точки привязки между глазами

Рендеринг

В этом примере карта смещения и цветовая карта применяются во время рендеринга в вертексном шейдере и в пиксельном шейдере.

Вертексный шейдер

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

Этапы работы вертексного шейдера

  1. Преобразование положения вертексов матрицей проецирования карт для получения координат текстур на цветовой карте и карте смещения.
  2. Получение текстуры карты смещения по вычисленным координатам.
  3. Преобразование значения на карте смещения в значение по оси Z в пространстве модели. Диапазон и масштаб карты смещения проходят через постоянный буфер.
  4. Смешение между значением смещения по оси Z и исходным значением по оси Z на основе канала красного цвета в карте управления. Карта управления позволяет пользователю выбирать, какие вершины будут смещены, и позволяет применять постепенный плавный переход к смещенному положению.
  5. Передача двухмерных UV-координат карты смещения в пиксельный шейдер, где они используются для получения цветовой карты.

Пиксельный шейдер

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


Рисунок 9. Демонстрация смешения на модели головы без применения карты смещения и цветовой карты

Рисунок 10. Конечный результат, полученный в реальном времени с помощью описываемого примера

Экспорт

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

Весь процесс получения текстуры и деформации модели по-прежнему происходит в ГП с использованием разновидности исходных шейдеров. Новый вертексный шейдер использует поддержку поточного вывода в Direct3D * для записи вершин после деформации. Вертексный шейдер также использует входные координаты текстуры в качестве выходного положения. Благодаря этому отрисовывается новая наложенная двухмерная текстура.

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


 

Рисунок 11. Экспортированная модель в формате OBJ (слева), составная двухмерная UV-текстура лица, наложенная на двухмерную UV-развертку модели головы

Дополнительные сведения об оптимизации компиляторов см. в уведомлении об оптимизации.


Platform Analyzer: анализ правильно и неправильно работающих приложений

$
0
0

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

В этой статье мы будем действовать по схожему принципу: будем анализировать и сравнивать работу хорошо работающего приложения и не очень хорошо работающего.

Тук-тук-тук.

Врач говорит: «Войдите!»

В кабинет заходит наш пациент — игра WarriorWave*, где ваша рука прокладывает путь, по которому должны пройти воины. Играть в нее очень интересно и необычно. В игре используется технология Intel® RealSense. 

Но в процессе игры что-то было не так.  Что-то, чего не ощущалось в других играх на основе технологии Intel® RealSense™.  Проблема может быть вызвана разными причинами, но что не так в этомслучае?  

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

Используя средство Platform Analyzer в составе Intel® Graphics Performance Analyzer (Intel® GPA)мы получаем временное представление нагрузки на ЦП, времени создания каждого кадра, кадровой скорости и вызовов отрисовки:

Давайте посмотрим.

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

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

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

Но в нашем случае явно наблюдаются регулярные скачки. Они происходят примерно 4 раза в секунду.  Давайте изучим проблему подробнее, увеличив один из таких скачков, и посмотрим, что при этом происходит в потоках:

Мы видим, что рабочий поток 2780 тратит большую часть времени на синхронизацию. Этот поток практически ничего не делает, только дожидается следующего кадра из Intel® RealSense™ SDK:

При этом мы видим, что отрисовка происходит в другом рабочем потоке. Если прокрутить вниз, мы найдем поток 2372.

Вместо того, чтобы «активно» ждать следующего кадра от Intel RealSense SDK, игра могла бы делать что-нибудь полезное. Отрисовку и ожидание Intel® RealSense™ SDK можно было бы поместить в один рабочий поток вместо двух, что упростило бы обмен данными между потоками.

Избыточный обмен данными между потоками может значительно замедлить выполнение программы и вызвать множество проблем.

Вот пример правильно устроенной игры, в которой работа Intel® RealSense™ SDK и вызовы DirectX* находятся в одном и том же потоке. 

Специалисты по RealSense™ заявляют, что нет смысла ждать кадры из Intel® RealSense™ SDK. От этого они не будут появляться быстрее. 

При этом мы видим, что основная проблема находится в верхней части временной шкалы.

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

Теперь перейдем к конвейеру и попробуем разобраться, как идет выполнение кода.  Посмотрите на количество пакетов в Engine 0: конвейер заполнен до краев, но очередь выполнения почти пуста.

Человеческий мозг может обрабатывать до 10–12 изображений в секунду по отдельности. Это поясняет, почему при съемке самых первых кинофильмов пленка протягивалась со скоростью 16 кадров в секунду: это средний порог, после которого большинство людей перестают воспринимать картинку на экране как отдельные изображения и начинают видеть фильм.

Снова посмотрим на профиль правильно работающей игры: 

Обратите внимание, что кадры ГП следуют за кадрами ЦП с небольшим сдвигом. Для каждого кадра ЦП есть соответствующий кадр ГП, выполнение которого начинается после небольшой задержки.

Давайте попробуем понять, почему в нашей игре это не так.

Сначала рассмотрим вызовы DirectX*. Выделенный вызов со всплывающей подсказкой — это наш вызов Present, отправляющий готовый кадр в ГП. На приведенном выше снимке экрана видно, что он создает пакет Present в конвейере ГП (помеченный крестиками).  На отметке 2215 мс он переместился ближе к выполнению, перескочив через три позиции, но на отметке 2231 мс он просто исчез, не завершив выполнение.

Если рассмотреть все вызовы Present в трассировке, окажется, что ни один из них не достиг успешного выполнения.

Вопрос: каким же образом изображение игры вообще появляется на экране, если все вызовы DirectX* Present пропадают?! Хорошо, что у нас есть удобные инструменты, позволяющие получить ответ на этот вопрос. Давайте посмотрим.

Видите нечто любопытное внутри серого овала? Мы видим, что этот пакет, возникший вне всякой связи с какими-либо вызовами DirectX* в нашем коде, все же добирается до выполнения, быстро и без видимого порядка. Минутку, постойте!

Давайте поподробнее изучим наш пакет. 

А теперь — пакет, который все-таки был выполнен. 

Ага! Он появился из ВНЕШНЕГО потока. Что это может означать? Внешние потоки — это потоки, не принадлежащие к игре.

Итак, наши собственные пакеты пропадают, но зато какой-то внешний поток выводит на экран нашу игру? Как это вообще возможно? Может быть, наша программа Platform Analyzer выдает какую-то чепуху?

Нет, на изображении все верно. А объясняется весь этот цирк следующим образом: в системах Windows* (начиная с Windows Vista*) существует программа под названием «диспетчер окон рабочего стола» (DWM), которая и отвечает за фактический вывод изображения на экран. Это пакеты DWM выполнялись быстро и вне очереди, с высоким приоритетом.  А наши пакеты вовсе не пропадали: диспетчер окон рабочего стола перехватывал их для создания итогового изображения.

Но почему диспетчер окон рабочего стола вмешался в работу полноэкранной игры? Подумав, я понял, что ответ прост: к моему компьютеру подключено два монитора. Достаточно было отключить второй монитор из схемы, и все встало на свои места: игра WarriorWaveзаработала точно так же, как все приличные игры: нормальная кадровая скорость ГП, никаких скачков, никаких пакетов DWM.

Пациент будет жить! Хорошая новость!

Но ведь другие игры вполне хорошо работали и в конфигурации с двумя мониторами, не так ли?

Чтобы изучить проблему подробнее, нужен другой инструмент. Intel® GPA Platform Analyzer позволяет отслеживать работу ЦП и ГП по времени, но не дает возможности подробно изучать каждый кадр.

Следует более внимательно рассмотреть код создания Direct3D* Device. Для этого можно использовать Intel® GPA Frame Analyzer для DirectX*, но это уже материал для другой статьи.

Итак, подведем итоги.

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

Заключение: Intel® GPA Platform Analyzer — очень полезный инструмент для анализа проблем на начальном этапе. Изучите его и используйте его.

Об авторе

Александр Рауд (Alexander Raud) работает в команде Intel® Graphics Performance Analyzers в России, ранее он работал над программой VTune Amplifier. У Александра двойное гражданство России и Евросоюза, он говорит по-русски, по-английски и немного по-французски, а также изучает испанский язык.  Александр женат, у него двое детей, но, несмотря на это, он находит время, чтобы профессионально играть прогрессивный металл в составе рок-группы и руководить международной миссионерской организацией церкви «Дом Божий».

Дополнительные сведения об оптимизации компиляторов см. в нашем уведомлении об оптимизации.

Ускорение обработки мультимедиа: чем пользоваться?

$
0
0

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

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

Ускорение обработки мультимедиа: чем пользоваться?
ИнструментЦелевые платформы и устройства,
режимы использования

Intel® Media SDK

Разработка для следующих платформ

  • Процессоры Intel® Core™ и Core™ M 
  • Определенные модели процессоров Intel® Celeron™, Intel® Pentium™ и Intel® Atom™ с видеоадаптером Intel HD Graphics, поддерживающим Intel® Quick Sync Video
  • Клиентские устройства — приложения для настольных ПК и мобильные приложения
  • ОС — только Windows *

Использование и назначение

  • Быстрое воспроизведение видео, кодирование, обработка, преобразование мультимедиа из одного формата в другой, видеоконференции.
  • Ускоренная обработка необработанных видеоданных и изображений (в формате RAW).
  • Запись изображения с экрана.
  • Поддержка декодирования и кодирования звука.

Intel® Media Server Studio

 

 

 

 

3 Editions are available

  • Community
  • Essentials
  • Professional

Разработка для следующих платформ

Поддержка форматов  HEVC, AVC и MPEG-Audio.

Использование и назначение

  • Быстрое декодирование, кодирование, перекодирование данных мультимедиа высокой плотности.
  • Оптимизация производительности конвейера обработки мультимедиа и ГП (-> VTune).
  • Расширенные возможности программирования графики и анализа вывода изображения (для использования в приложениях OpenCL™).
  • Низкоуровневое управление качеством кодирования.
  • Средства отладки, анализа и оптимизации качества и производительности.
  • Переход на кодеки HEVC с высоким качеством изображения.
  • Необходимость измерения качества изображения (Video Quality Caliper).
  • Потребность в системе обратного преобразования фильмов из формата кино в формат для телевидения (так называемое обратное телекино) с чересстрочной разверткой (Premium Telecine Interlace Reverser).
  • Аудиокодеки.
  • Запись изображения с экрана.

Intel® Video Pro Analyzer

Поддержка форматов — HEVC, VP9, AVC и MPEG-2.

Использование и назначение

  • Разработка для кодирования и декодирования HEVC, AVC, MPEG-2 и VP9, анализ потоков.
  • Необходимость экономить время и ресурсы.
  • Тонкая настройка конвейера кодирования.
  • Анализ всего процесса декодирования и кодирования, отладка и оптимизация кодировщиков.
  • Измерение и повышение наглядного качества изображения (Video Quality Caliper).
  • Доступ к подробным статистическим данным о видеопотоках.
  • Новые возможности для разрешения UHD с поддержкой расширенного динамического диапазона цветов

Intel® Stress Bitstreams & Encoder

  • Требуется:ЦП Intel®, поддерживающий поточные расширения Intel® SIMD 2 (SSE2)
  • Поддержка ОС: Windows, Ubuntu Linux *, Macintosh OS X
  • Поддержка форматов и профилей — HEVC, VP9, AVS 2.0.

    Использование и назначение

  • Всеобъемлющие возможности анализа мультимедиа и отладки корпоративного уровня в производственных масштабах для декодеров, транскодеров, проигрывателей и поточных решений с HEVC и VP9.
  • Разработка декодеров HEVC и VP9, анализ результатов декодирования.
  • Существенное ускорение циклов проверки, снижение затрат, ускорение выпуска решений на рынок.
  • Создание настраиваемых битовых потоков для тестирования, оптимизация базы потоков с точки зрения покрытия и эффективности использования.
  • Доработка декодеров для полного соответствия стандартов, работы с наивысшей производительностью и устойчивости к ошибкам.

Intel® SDK for OpenCL™ Applications

Разработка для

Ускорение ГП общего назначения на определенных процессорах Intel® (см. технические характеристики). OpenCL работает главным образом с исполняемыми блоками. В процессоры Intel добавляются новые расширения, позволяющие приложениям OpenCL воспользоваться преимуществами аппаратных блоков Intel с фиксированными функциями.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

OpenCL и эмблема OpenCL являются товарными знаками Apple Inc. и используются с разрешения Kronos.

Дополнительные сведения об оптимизации компиляторов см. в уведомлении об оптимизации.

Использование камеры Intel® RealSense™ с TouchDesigner*: часть 1

$
0
0

Загрузить демонстрационные файлы ZIP 35KB

TouchDesigner* компании Derivative* — популярная платформа и программа, используемая во всем мире для создания интерактивных решений и анимации реального времени в ходе выступлений, а также для отображения трехмерной анимации, создания карт и схем, а также с недавнего времени в системах виртуальной реальности. Благодаря поддержке камеры Intel® RealSense™ TouchDesigner* становится еще более многоцелевым и мощным средством. Следует отметить и возможность импортировать в TouchDesigner* объекты и анимацию из других трехмерных пакетов с помощью файлов .fbx, а также возможность работать с уже рендеринговыми анимационными роликами и изображениями.

В этой статье, состоящей из двух частей, я расскажу об интеграции камеры Intel® RealSense™ в TouchDesigner* и о возможностях ее использования. В демонстрациях в первой части используется камера Intel® RealSense™ с узлами TOP. В демонстрациях во второй части используются узлы CHOP. Во второй части также поясняется создание последовательностей виртуальной реальности и полукруглых панорам с использованием камеры Intel® RealSense™. Я покажу, как использовать TouchDesigner* Oculus Rift вместе с камерой Intel® RealSense™. Обе части включают анимации и загружаемые файлы TouchDesigner* (.toe), которые можно использовать для просмотра. Для получения файлов TouchDesigner* (.toe) нажмите кнопку в верхней части этой статьи. Кроме того, доступна бесплатная копия TouchDesigner* для некоммерческого использования. Она полностью функциональна (за исключением того, что максимальное разрешение ограничено значением 1280 на 1280).

Примечание.В настоящее время существует два типа камер Intel® RealSense™: камера ближнего обзора F200и камера дальнего обзора R200. Благодаря своему сверхкомпактному размеру камера R200 очень удобна для выступлений и других сценариев использования, когда камера должна быть скрытой. В отличие от более крупной модели F200 камера R200 не поддерживает отслеживание рук и пальцев, а также отслеживание маркеров. TouchDesigner* поддерживает обе модели камер Intel® RealSense™: и F200, и R200.

Цитирую веб-страницу TouchDesigner*: «TouchDesigner* — это революционная программная платформа, дающая возможность художникам и дизайнерам работать с материалами в открытой свободной среде. TouchDesigner* — идеальное решение для интерактивных мультимедиапроектов, использующих видео, звук, трехмерную графику, ввод с помощью контроллеров, Интернет и базы данных, источники света DMX, датчики окружающей среды и вообще все, что только можно вообразить. Это мощная среда для смешения всех названных элементов бесконечным числом способов».

Я попросил Малькольма Бечарда, старшего разработчика Derivative, высказаться по поводу использования камеры Intel® RealSense™ с TouchDesigner*:

«Благодаря процедурной архитектуре TouchDesigner* на основе узлов данные камеры Intel® RealSense™ можно немедленно получать, визуализировать, затем передавать на другие узлы, не тратя времени на написание кода. Можно быстро создавать прототипы идей и вести разработку с мгновенной обратной связью. Камера представлена узлом в TouchDesigner*, а это означает, что нет необходимости закрывать и перекомпилировать приложение на каждой итерации разработки. Камера Intel® RealSense™ дополняет возможности TouchDesigner*, предоставляя пользователям значительное количество готовых модулей, таких как жесты, отслеживание рук, отслеживание лица, данные глубины. Все это можно использовать для взаимодействия. Нет необходимости применять низкоуровневый анализ данных о положении рук для распознавания жестов: это уже сделано».

Использование камеры Intel® RealSense™ в TouchDesigner*

TouchDesigner* — программа и платформа на основе узлов, использующая Python* в качестве основного языка сценариев. Существует пять категорий узлов, выполняющих разные операции и обладающих разными функциями: узлы TOP (текстуры), SOP (геометрия), CHOP (анимация и звук), DAT (таблицы и текст), COMP (трехмерные геометрические узлы, а также узлы для создания двухмерных панелей управления) и MAT (материалы). Программисты компании TouchDesigner*, посоветовавшись с разработчиками Intel®, создали два особых узла, узел камеры Intel® RealSense™ TOP и узел камеры Intel® RealSense™ CHOP для интеграции камеры Intel® RealSense™ в программу.

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

Изучение TouchDesigner*

Примечание.При использовании камеры Intel® RealSense™ для достижения оптимальных результатов следует учитывать дальность. На этой веб-странице Intel®указана дальность всех моделей камер и даны рекомендации по использованию камер.

Узел камеры Intel® RealSense™ TOP

Узлы TOP в TouchDesigner* выполняют множество операций, обычно содержащихся в программах для композиции изображений. Узел камеры Intel® RealSense™ TOP дополняет эти возможности за счет двухмерных и трехмерных данных, поступающих от камеры Intel® RealSense™. Узел камеры Intel® RealSense™ TOP содержит ряд настроекдля получения разных видов данных.

  • Цвет.Видео с датчика цвета камеры Intel® RealSense™.
  • Глубина.Вычисленная глубина каждого пикселя. 0 означает, что пиксель находится на расстоянии 0 метров от камеры, 1 означает, что пиксель находится на максимально возможном расстоянии или дальше.
  • Необработанная глубина.Значения берутся непосредственно из Intel® RealSense™ SDK. И вновь 0 означает 1 метр от камеры, 1 означает, что пиксель находится на максимально возможном расстоянии или дальше.
  • Наглядная глубина. Изображение Intel® RealSense™ SDK в оттенках серого, позволяющее наглядно представить глубину. Его невозможно использовать для фактического вычисления точного расстояния каждого пикселя до камеры.
  • Отображение глубины на цветной UV-карте. Значения UV из 32-разрядной плавающей текстуры RG (обратите внимание, что в ней только два цвета (красный и зеленый), а синего цвета нет), необходимые для выравнивания изображения глубины в соответствии с цветным изображением. Для выравнивания изображений можно использовать узел TOP Remap.
  • Отображение цвета на UV-карте глубины.Значения UV из 32-разрядной плавающей текстуры RG (обратите внимание, что в ней только два цвета (красный и зеленый), а синего цвета нет), необходимые для выравнивания изображения цвета в соответствии с изображением глубины. Для выравнивания изображений можно использовать узел TOP Remap.
  • Инфракрасное изображение.Необработанное видео инфракрасного датчика камеры Intel® RealSense™.
  • Облако точек. Это в буквальном смысле облако точек в трехмерном пространстве (с координатами X, Y, Z) или точек данных, созданных сканером камеры Intel® RealSense™.
  • UV-карта цветов облака точек. Можно использовать для получения цвета каждой точки из потока цветного изображения.

Примечание.Можно загрузить этот файл RealSensePointCloudForArticle.toeдля использования в качестве простого начального шаблона для создания трехмерной анимированной геометрии из данных камеры Intel® RealSense™. Этот файл можно изменять разными способами. Вместе три узла TOP камеры Intel® RealSense™ — Point Cloud, Color и Point Cloud Color UV — позволяют создать трехмерную геометрию из точек (частиц) с наложением цветного изображения. Это открывает множество интересных возможностей.

Геометрия облака точек. Это анимированная геометрия, создаваемая с помощью камеры Intel®RealSense™. Ее очень хорошо использовать при выступлениях на публике. Можно добавить и звук говорящего анимационного персонажа. TouchDesigner* также может использовать звуковые данные для создания анимации в реальном времени.


This short video shows the point cloud geometry animation pictured in the image above.

Узел CHOP камеры Intel RealSense

Примечание.Существует еще один узел CHOP камеры Intel® RealSense™, отвечающий за данные трехмерного отслеживания и положения. Мы обсудим его во второй части этой статьи.

Демонстрация 1. Использование узла камеры Intel® RealSense™ TOP

Для получения первой демонстрации TOP нажмите кнопку в верхней части статьи: settingUpRealNode2b_FINAL.toe.

Демонстрация 1, часть 1. Вы узнаете, как настраивать узел камеры Intel® RealSense™ TOP и соединять его с другими узлами TOP.

  1. Откройте диалоговое окно AddOperator/OPCreate.
  2. В разделе TOP щелкните RealSense.
  3. На странице параметров Setupузла камеры Intel® RealSense™ TOP для параметра Image выберите значение Colorв раскрывающемся меню. В узле камеры Intel® RealSense™ TOP отображается изображение того, на что направлена камера, как при использовании обычной видеокамеры.
  1. Задайте для камеры Intel® RealSense™ разрешение 1920 на 1080.
     

    Настроить узел Intel®RealSenseTOPочень просто.

    Создайте узел Level TOP и соедините его с узлом камеры Intel® RealSense™ TOP. На странице параметров Preузла Level TOP выберите Invertи передвиньте ползунок на значение 1. Соедините узел Level TOP с узлом HSV To RGB TOP, затем соедините последний с узлом Null TOP.

Узел камеры Intel®RealSenseTOPможно соединять с другими узлами TOPдля получения нужного изображения и создания нужных эффектов.

Затем мы передадим созданное изображение в узел Phong MAT (материал), чтобы можно было налагать его на различные геометрические фигуры в качестве текстуры.

Использование данных с камеры Intel® RealSense™ для создания текстур для геометрии

Демонстрация 1, часть 2.В этом упражнении показано, как использовать узел камеры Intel® RealSense™ TOP для создания текстур и как добавлять их в узел MAT, чтобы можно было назначать их геометрии в проекте.

  1. Добавьте узел Geometry (геометрия) COMP в сцену.
  2. Добавьте узел Phong MAT.
  3. Возьмите узел Null TOP и перетащите его на параметр Color Map узла Phong MAT.

 


 

Узел PhongMATиспользует данные с камеры Intel®RealSense™ для своего параметра ColorMap.

4. На странице параметров Render узла Geo COMP добавьте тип phong1к параметру Material, чтобы использовать узел phong1в качестве материала.

  

Узел PhongMATиспользует данные с камеры Intel®RealSense™ для своего параметра ColorMap, добавленного в параметр Render/Materialузла GeoCOMP.

Создание узла Box SOP и текстурирование с помощью только что созданного шейдера Phong

Демонстрация 1, часть 3. Вы узнаете, как назначить шейдер Phong MAT, только что созданный с помощью данных с камеры Intel® RealSense™, узлу Geometry SOP куба.

  1. Перейдите в узле geo1на его дочерний уровень (/project1/geo1).
  2. Создайте узел Box SOP, узел Texture SOP и узел Material SOP.
  3. Удалите узел Torus SOP, который там был, затем соедините узел box1с узлами texture1и material1.
  4. В параметре Material узла material1введите ../phong1. Это узел phong1 MAT, созданный на родительском уровне.
Чтобы поместить текстуру на каждую сторону куба, в параметрах Texture/Texture Type узла texture1поместите faceи задайте для параметра the Texture/Offset put значение .5 .5 .5.
 
  1.  
    На дочернем уровне узла geo1 COMPузлы BoxSOP, TextureSOPи theMaterialSOPбудут соединены. Узел MaterialSOPтеперь получает текстуру из узла phong1 MAT, находящегося на родительском уровне ( …/phong1).
  2.  

 

Анимация и создание экземпляров геометрии узла Box

Демонстрация 1, часть 4.Вы узнаете, как поворачивать узел Geometry SOP с помощью узла Transform SOP и простого выражения. Затем вы узнаете, как создавать экземпляры геометрии узла Box. В результате мы получим экран с множеством вращающихся кубов, на каждом из которых будут текстуры из узла камеры Intel® RealSense™ TOP.

  1. Для анимации вращения куба вокруг оси X вставьте узел Transform SOP после узла Texture SOP.
  1. Поместите выражение в компонент X (первое поле) параметра Rotate в узле transform1 SOP. Это выражение не зависит от кадров, оно будет продолжать работать и не начнет повторяться по окончании кадров на временной шкале. Я умножил значение на 10, чтобы увеличить скорость: absTime.seconds*10
     

    Здесь видно, что куб вращается.

    Для создания кубов перейдите на родительский уровень (/project1) и на странице параметров Instanceузла geo1 COMP установите для параметра Instancing значение On. Добавьте узел Grid SOP и узел SOP–DAT. Задайте параметры сетки: 10 строк и 10 столбцов, размер — 20и 20. В параметрах узла SOP–DAT для SOP задайте grid1и убедитесь, что для параметра Extract задано значение Points. На странице параметров Instanceузла geo1 COMP введите для параметра Instance CHOP/DAT: sopto1.
  2. Заполните параметры TX, TY и TZ, используя соответственно P(0), P(1) и P(2), чтобы указать, какие столбцы из узла sopto1использовать для положений экземпляров.


     

    Нажмите кнопку в верхней части этой статьи, чтобы загрузить TOP_Demo1_forArticle.toeдля просмотра уже выполненной работы в этой первой демонстрации узла камеры Intel®RealSenseTOP.

    Если нужно, чтобы изображение с камеры Intel® RealSense™ передавалось без фильтрации, отключите узлы Level TOP и HSV to RGB TOP либо обойдите эти узлы.
     

Рендеринг и анимация в реальном времени

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

  1. Для рендеринга проекта добавьте узлы Camera COMP, Light COMP и Render TOP. По умолчанию камера выполняет рендеринг всех компонентов геометрии на сцене.
  2. Отведите камеру назад примерно на 20 единиц по оси Z. Для освещения оставьте значения по умолчанию.
  3. Задайте разрешение рендеринга 1920 на 1080. По умолчанию фон рендеринга является прозрачным (значение альфа равно 0).
  4. Чтобы сделать фон непрозрачным черным, добавьте узел Constant TOP и измените значение параметра Color на 0,0,0, чтобы задать черный цвет, указав для параметра Alpha значение 1. Можно выбрать любой другой цвет.
  5. Добавьте узел Over TOP и соедините узел Render TOP с первым подключением, а узел Constant TOP — со вторым. При этом пиксели фона получат значение (0, 0, 0, 1), то есть перестанут быть прозрачными.

Еще один способ изменить значение прозрачности TOP на 1 — использовать узел Reorder TOP и задать для его параметра Output Alpha значения Input 1и One.

Отображение сцены с непрозрачным черным фоном.


Здесь виден полный экран с текстурированными вращающимися кубами.

Если вы предпочитаете выводить анимацию в файл вместо воспроизведения ее в реальном времени при демонстрации, нужно выбрать диалоговое окно Exportmovieв разделе fileна верхней панели программы TouchDesigner. В параметре узла TOP Video введите null2для этого конкретного примера. В противном случае введите любой узел TOP, которому требуется рендеринг.

 

Вот панель ExportMovieс узлом null2. Если бы был еще и звуковой узел CHOP, то я бы разместил CHOPAudioсразу под null2.

Демонстрация 1, часть 6. Одна из полезных особенностей платформы TouchDesigner* — возможность создания анимации в реальном времени. Эта возможность особенно удобна при использовании камеры Intel® RealSense™.

  1. Добавьте узел Window COMP, а в параметре оператора введите узел null2 TOP.
  2. Установите разрешение 1920 на 1080.
Выберите нужный монитор в параметре Location. Узел Window COMP позволяет выводить всю анимацию в реальном времени на выбранный монитор. С помощью узла Window COMP можно указать монитор или проектор, на который следует выводить изображение.
  1.  
    Можно создать сколько угодно узлов WindowCOMPдля вывода изображения на другие мониторы.

Демонстрация 2. Использование данных глубины узла камеры Intel® RealSense™ TOP

Узел камеры Intel® RealSense™ TOP содержит ряд других настроек для создания текстур и анимации.

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

Сначала создайте узел камеры Intel® RealSense™ TOP и задайте для параметра Image значение Depth. Изображение глубины содержит пиксели со значением 0 (черные), если они близко к камере, и со значением 1 (белые), если они далеко от камеры. Диапазон значений пикселей определяется параметром Max Depth, его значение указывается в метрах. По умолчанию этот параметр имеет значение 5. Это означает, что пиксели, находящиеся на расстоянии 5 метров от камеры (или дальше), будут белыми. Пиксели со значением 0,5 находятся на расстоянии 2,5 м от камеры. В зависимости от фактического расстояния между камерой и вами имеет смысл изменить это значение на меньшее. В этом примере мы изменили значение данного параметра на 1,5 м.

Затем нужно обработать глубину, чтобы удалить объекты, находящиеся за пределами интересующей нас дальности. Для этого мы используем узел Threshold TOP.

  1. Создайте узел Threshold TOP и соедините его с узлом realsense1. Нужно убрать все пиксели, находящиеся дальше определенного расстояния от камеры, поэтому задайте для параметра Comparator значение Greater, а для параметра Threshold — значение 0.8.При этом пиксели со значением больше 0,8 (что соответствует расстоянию 1,2 м или более, если для параметра Max Depth в узле камеры Intel® RealSense™ TOP задано значение 1,5) станут равными 0, а все остальные пиксели — равными 1.
     

  2. Создайте узел Multiply TOP, соедините узел realsense1с первым входом, а узел thresh1 — со вторым входом. При умножении пикселей на 1 они останутся в неизменном виде, а при умножении других пикселей на 0 они будут обнулены. Теперь узел multiply1содержит только пиксели больше 0 для той части изображения, на которой нужно сделать размытие, чем мы сейчас и займемся.
  3. Создайте узел Movie File в TOP и выберите новое изображение для параметра File. В этом примере мы выбираем Metter2.jpg из папки TouchDesigner* Samples/Map.
  4. Создайте узел Luma Blur TOP и соедините moviefilein1с первым входом lumablur1, а multiply1 — со вторым входом lumablur1.
  5. В параметрах lumablur1задайте для параметра White Value значение 0.4, для параметра Black Filter Width значение 20, а для параметра White Filter Width — значение 1. Благодаря этому у пикселей со значением первого входа 0будет ширина фильтра размытия 20, а у пикселей со значением 0.4или больше — ширина размытия 1.
     

    Все в целом.

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

 

Фон, выводимый отображением LumaBlurTOP, показывает, насколько размыто изображение.

Демонстрация 3. Использование данных глубины узла камеры Intel® RealSense™ TOP с узлом Remap TOP

Для получения этого файла нажмите кнопку в верхней части статьи: RealSenseRemap.toe.

Примечание. Камеры глубины и цвета узла камер Intel® RealSense™ TOP физически находятся в разных местах, поэтому выдаваемые ими изображения по умолчанию не совпадают друг с другом. Например, если ваша рука находится ровно посередине цветного изображения, то она будет не в середине изображения глубины, а несколько смещена влево или вправо. Сдвиг UV-карты устраняет эту проблему за счет выравнивания и точного наложения пикселей. Обратите внимание на разницу между выровненным и невыровненным узлами TOP.

RemapTOPсовмещает данные глубины, полученные от узла камеры Intel®RealSenseTOP, с данными цвета, полученными от этого же узла, используя UV-данные совмещения глубины с цветом на одном и том же пространстве.

Демонстрация 4. Использование облака точек в узле камеры Intel® RealSense™ TOP

Для получения этого файла нажмите кнопку в верхней части статьи: PointCloudLimitEx.toe.

В этом упражнении вы научитесь создавать анимированную геометрию с помощью облака точек, узла камеры Intel® RealSense™ TOP и узла Limit SOP. Обратите внимание, что этот подход отличается от примера файла Point Cloud, приведенного в начале этой статьи. В предыдущем примере используются шейдеры GLSL, что дает возможность создать гораздо больше точек, но эта задача усложняется и выходит за рамки статьи.

  1. Создайте узел RealSense™ TOP и задайте для параметра Image значение PointCloud.
  2. Создайте узел TOP–CHOP и подключите его к узлу Select CHOP.
  3. Подключите узел Select CHOP к узлу Math CHOP.
  4. В параметре TOP узла CHOP topto1введите: realsense1.
  5. В параметрах Channel Names узла Select CHOP введите rgb, разделив буквы пробелами.
  6. В узле CHOP math1в поле значения параметра Multiplyвведите: 4.2.
  7. На странице параметров Rangeв поле значений параметра ToRangeвведите: 1 и 7.
  8. Создайте узел Limit SOP.

Цитирую вики-страницу на сайте www.derivative.ca: «Limit SOP создает геометрию из данных, передаваемых узлами CHOP. Он создает геометрию в каждой точке выборки. С помощью параметра Output Type на странице Channelsможно создавать геометрию разного типа».

  1. На странице с параметром limit1 CHOP Channelsвведите rдля параметра X Channel, «g» — для параметра Y Channel и «b» — для параметра Z Channel.
     

Примечание. Перемещение значений r, g и b в другие каналы X, Y и Z изменяет образуемую геометрию. Поэтому позднее можете попробовать следующее: На странице параметров Outputдля параметра Output Type выберите SphereatEachPointв раскрывающемся списке. Создайте узел SOP–DAT. На странице параметров для SOP введите limit1или перетащите узел limit1 CHOP в этот параметр. Оставьте значение по умолчанию для Points в параметре Extract. Создайте узлы Render TOP, Camera COMP и Light COMP. Создайте узел Reorder TOP, задайте для Output Alpha значения Input 1и One, соедините его с узлом Render TOP.

  1. При изменении изображения с камеры Intel®RealSense™ изменяется и геометрия. Это итоговый проект.


    Итоговые изображения в узле OverTOPCHOP. Изменяя порядок каналов в параметрах LimitTOP, вы изменяете геометрию на основе облака точек.

    Во второй части этой статьи мы обсудим узел камеры Intel® RealSense™ CHOP и создание содержимого для записи и демонстрации в реальном времени, демонстрации полусферических панорам и систем виртуальной реальности. Кроме того, мы обсудим использование узла Oculus Rift CHOP. Мы поговорим про отслеживание рук, отслеживание лица и маркеров.

    Об авторе

    Одри Филипс (Audri Phillips) — специалист по визуализации и трехмерной анимации из Лос-Анджелеса. Она располагает обширным профессиональным опытом, включая 25 лет стажа работы в отрасли визуальных эффектов и развлечений в таких анимационных студиях, как Sony*, Rhythm and Hues*, Digital Domain*, Disney* и Dreamworks*. Сначала она занималась рисованием, но быстро перешла к созданию анимационных изображений. Она всегда интересовалась новыми инструментами и применяла компьютерные изображения и анимацию в экспериментальных фильмах, включая демонстрации для погружения в виртуальную среду. Сейчас она работает над системами виртуальной реальности. Корпорация Samsung* недавно использовала ее работы в новом канале виртуальной реальности Gear Indie Milk.

    Вот ее последние работы и анимации: мультимедиа анимации для фестиваля Implosion a Dance Festival в 2015 году в театральном центре Лос-Анджелеса, 3 полусферические демонстрации в куполе Vortex Immersion, над созданием одной из которых также работал известный композитор и музыкант Стив Роуч. 7 ноября 2015 г. вышла четвертая полнокупольная демонстрация под названием Relentless Universe. Помимо этого, она создала анимационные материалы для телесериала «Константин»; они были показаны на конференции Comic-Con 2014 года. Некоторые ее полнокупольные демонстрации, в том числе Migrations и Relentless Beauty, получили оценку жюри на международном фестивале Santa Fe International New Media Festival и на фестивале Jena FullDome Festival в Германии. Она выставляет свои работы в галерее Young Projects в Лос-Анджелесе.

    Она публикует материалы в Интернете и ведет блог на портале корпорации Intel®. Одри — адъюнкт-профессор в Университете Вудбери, член-основатель и лидер организации Los Angeles Abstract Film Group, основатель студии Hybrid Reality Studio (занимающейся созданием материалов для виртуальной реальности), член правления Iota Center, а также участник выставок LA Art Lab. В 2011 году Одри стала постоянным художником Vortex Immersion Media и c3: CreateLAB.

Приводим данные и код в порядок: данные и разметка, часть 2

$
0
0

В этой серии из двух статей о производительности и памяти описываются базовые принципы и приводятся советы для разработчиков по повышению производительности программного обеспечения.  Эти статьи затрагивают, в частности, работу памяти и компоновку. В первой частибыло рассказано об использовании регистров и о применении алгоритмов блокирования для повышения многократного использования данных. В этой части статьи сначала описывается компоновка данных для обычного распараллеливания — программирования для общей памяти с потоками, а затем распределенные вычисления по сетям MPI. В статье описываются понятия, связанные с распараллеливанием: векторизация (инструкции SIMD) и работа с общей памятью (многопоточная архитектура), а также вычисления с распределенной памятью. И наконец, в этой статье сравниваются компоновки данных «массив структур» (AOS) и «структура массивов» (SOA).

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

 

Программирование общей памяти с потоками

Давайте начнем с программирования общей памяти с потоками. Все потоки вместе обращаются к одной и той же памяти в пределах процесса. Существует множество моделей управления потоками. Наиболее известные среди них потоки Posix* и потоки Windows*. В работе, связанной с правильным созданием потоков и управлением ими, могут возникать ошибки. В современных программах, состоящих из множества модулей и создаваемых крупными командами разработчиков, часто возникают ошибки в параллельном программировании с использованием многопоточных вычислений. Разработано несколько пакетов для упрощения создания потоков, управления ими и наиболее эффективного использования параллельных потоков. Два самых популярных пакета — это OpenMP* и Intel® Threading Building Blocks. Третья модель управления потоками — Intel® Cilk™ Plus — не получила настолько широкого распространения, как OpenMP и Threading Building blocks. Все эти модели управления потоками создают пул потоков, который многократно используется каждой из параллельных операций и параллельных областей. В OpenMP есть преимущество — ступенчатое распараллеливание с помощью использования директив. При этом директивы OpenMP можно зачастую добавлять к существующим программам в пошаговом процессе и с минимальными изменениями кода. Если позволить библиотеке времени выполнения управлять обслуживанием потоков, это существенно упростит разработку многопоточных программ. Также предоставляется единая модель управления потоками, которой должны придерживаться все разработчики кода, что снижает вероятность возникновения некоторых распространенных ошибок. Оптимизированная библиотека управления потоками используется всеми разработчиками.

Принципы параллельного программирования, упомянутые во вводной части, состоят в том, чтобы размещать данные как можно ближе к месту, где они будут использоваться, и избегать перемещения данных. В многопоточном программировании в модели по умолчанию данные являются общими для всего процесса, к ним могут обращаться все потоки. Во вводных статьях по управлению потоками подчеркивается, насколько просто можно применить OpenMP к циклам do (Fortran*) или циклам for (C). Такие методы обычно значительно ускоряются при выполнении кода на двух или четырех ядрах. Зачастую эти методы наращиваются до 64 потоков или более. Впрочем, не менее часто дополнительные потоки не используются, причем в некоторых таких случаях это обусловлено неподходящей компоновкой данных. Дело в создании архитектуры, пригодной для параллельного кода.

Важно изучать возможности распараллеливания на более высоком уровне в стеке вызовов кода, чем первоначально предполагается разработчиком или средствами разработки. Если разработчик считает, что какие-либо задачи или данные можно обрабатывать параллельно, то попробуйте ответить на следующие вопросы (в свете закона Амдала): «Можно ли начать применять параллельные операции выше в стеке вызовов перед переходом к этому месту?», «Если я это сделаю, то увеличится ли параллельная область кода, что приведет к ускорению работы при задействовании большего числа потоков?».

Следует внимательно обдумать и размещение данных, и то, к каким данным может быть предоставлен общий доступ посредством сообщений. Компоновка данных должна предусматривать размещение данных там, где они используются больше всего, а оттуда их можно отправлять другим системам. Для приложений, представленных в таблице или в физическом домене с заданными разделами, программы MPI часто добавляют строку «фантомных» ячеек вокруг подчиненной таблицы или подчиненного домена. В «фантомных» ячейках сохраняются значения данных, отправленные процессом MPI, обновляющим эти ячейки. В многопоточных программах «фантомные» ячейки обычно не используются, но при снижении длины границы раздела для передачи сообщений желательно уменьшить границы разделов, использующих общую память. При этом снижается необходимость в блокировке потоков (или важных разделов) и вероятность образования конфликтов кэша, связанных с владением кэшем.

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

Рисунок 1. Скорость доступа к памяти, относительные задержки при доступе к данным

Если один поток выделяет и инициализирует данные, то эти данные обычно помещаются в память, ближайшую к процессору, в котором выполняется поток, выделяющий и инициализирующий память (рис. 1). Можно повысить производительность, если заставить каждый поток выделять и давать первую ссылку на память, которая в наибольшей степени будет использоваться этим потоком. Обычно этого достаточно для того, чтобы поток был запущен в области памяти, ближайшей к процессору. Если поток создан и активен, то ОС обычно оставляет его в этом же процессоре. Иногда бывает выгодно явным образом привязать поток к определенному ядру, чтобы избежать переноса потока между ядрами. Если данные имеют определенную компоновку, то может быть выгодно назначить или привязать потоки к определенным ядрам в соответствии с этой компоновкой. Библиотека выполнения Intel OpenMP (в составе Intel® Parallel Studio XE 2016) содержит явные атрибуты сопоставления, эффективно работающие на сопроцессорах Intel® Xeon Phi™.

Это атрибуты Compact, Scatter и Balanced. 

  • Атрибут Compact сопоставляет последовательные или соседние потоки с симметричными многопоточными множествами (SMT) на одном ядре перед назначением потоков другим ядрам. Это идеальное решение для ситуаций, когда потоки обращаются к данным, общим для потоков с последовательной нумерацией (т. е. соседних потоков).
  • Атрибут Scatter назначает по одному потоку каждому ядру, затем возвращается к первоначальному ядру для планирования других потоков в SMT.
  • Атрибут Balanced равномерно назначает потоки с последовательными или соседними идентификаторами одному и тому же ядру. Это рекомендуемый начальный атрибут для оптимизации сопоставления потоков в документации компилятора Intel 16.0 C++. Параметр Balanced доступен только для семейства продуктов Intel® Xeon Phi™. Для обычных ЦП он недействителен. Когда все SMT на платформе Xeon Phi задействованы, атрибуты Balanced и Compact работают одинаково.  Если же на платформе Xeon Phi задействованы лишь некоторые SMT, то метод Compact будет заполнять все SMT на первых ядрах, а некоторые ядра останутся свободными (в идеале).

При работе с десятками потоков важно размещать данные потоков как можно ближе к тому месту, где они будут использоваться. Компоновка данных важна и для программ, использующих сети MPI, и для многопоточных программ.  

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

Представьте ситуацию, когда каждый поток увеличивает значение собственного счетчика, но сам счетчик при этом является одномерным массивом. Каждый поток увеличивает значение своего счетчика. Для увеличения значения счетчика ядро должно владеть строкой кэша. Например, поток A процессора 0 становится владельцем строки кэша и увеличивает значение счетчика iCount[A]. Одновременно поток A+1 процессора 1 увеличивает значение счетчика iCount[A+1]. Для этого ядро процессора 1 становится владельцем строки кэша и поток A+1 обновляет значение счетчика.  Поскольку значение в строке кэша изменяется, эта строка аннулируется для процессора 0. В следующей итерации процессор 0 становится владельцем строки кэша и изменяет значение iCount[A], что, в свою очередь, аннулирует эту строку кэша для процессора 1. Когда поток в процессоре 1 будет готов к записи, цикл повторяется. Значительное количество циклов процессора тратится на поддержку согласованности кэша, поскольку аннулирование строк кэша, восстановление контроля и синхронизация с памятью влияют на производительность.

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

int iCount[nThreads] ;
      .
      .
      .
      for (some interval){
       //some work . . .
       iCount[myThreadId]++ // may result in false sharing
     }

Not invalidating the cache

int iCount[nThreads*16] ;// memory padding to avoid false sharing
      .
      .
      .
      for (some interval){
       //some work . . .
       iCount[myThreadId*16]++ //no false sharing, unused memory
     }

No false sharing, unused memory

int iCount[nThreads] ; // make temporary local copy

      .
      .
      .
      // every thread creates its own local variable local_count
      int local_Count = iCount[myThreadID] ;
      for (some interval){
       //some work . . .
       local_Count++ ; //no false sharing
     }
     iCount[myThreadId] = local_Count ; //preserve values
     // potential false sharing at the end,
     // but outside of inner work loop much improved
     // better just preserve local_Count for each thread

Рисунок 2.

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

int data1, data2 ; // data1 and data2 may be placed in memory
                   //such that false sharing could occur
declspec(align(64)) int data3;  // data3 and data4 will be
declspec(align(64)) int data4;  // on separate cache lines,
                                // no false sharing

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

 

Выравнивание данных

Производительность программ является оптимальной, когда данные, обрабатываемые инструкциями SIMD (AVX512, AVX, SSE4), выравниваются по границам строки кэша. Потеря производительности при доступе к невыровненным данным различается в зависимости от семейства процессоров. Работа сопроцессоров Intel® Xeon Phi™ особенно сильно затрагивается выравниванием данных.    На платформе Intel Xeon Phi выравнивание данных имеет огромное значение. Эта разница не столь велика на других платформах Intel® Xeon®, но производительность все же заметно возрастает, когда данные выровнены по границам строки кэша. Поэтому разработчикам программ рекомендуется всегда выравнивать данные по 64-байтовым границам.  В системах Linux* и Mac OS X* для этого даже не нужно менять код, достаточно лишь использовать соответствующий параметр в командной строке компилятора Intel: /align:rec64byte.    

Для динамически выделяемой памяти в C можно заменить malloc()на _mm_alloc(datasize,64). Если используется _mm_alloc(), то следует использовать _mm_free()вместо free(). Подробная статья, посвященная выравниванию данных, находится здесь:  https://software.intel.com/en-us/articles/data-alignment-to-assist-vectorization

Также ознакомьтесь с документацией к компилятору. Чтобы показать влияние выравнивания данных на две матрицы одинакового размера, мы создали и запустили блочный код умножения матриц, использованный в первой части этой статьи.   В первом случае матрица А была выровнена. Во втором случае матрица А была намеренно смещена на 24 байта (три значения типа Double). При этом производительность (использовался компилятор Intel 16.0) упала на 56–63 % для матриц размером от 1200 х 1200 до 4000 х 4000.  В первой части я привел таблицу с производительностью упорядочения циклов в разных компиляторах. Когда одна матрица была смещена, компилятор Intel перестал давать прирост производительности.  Разработчикам рекомендуется прочесть документацию к компиляторам, чтобы узнать о выравнивании данных и о доступных параметрах, чтобы компилятор мог с наибольшей эффективностью воспользоваться выровненными данными. Код для измерения производительности матрицы, смещенной по отношению к строке кэша, входит в состав кода для первой части статьи:  https://github.com/drmackay/samplematrixcode

Дополнительные сведения вы найдете в документации к компилятору.

Чтобы показать влияние выравнивания данных на две матрицы одинакового размера, мы создали и запустили блочный код умножения матриц, использованный в первой части этой статьи. Первая матрица была выровнена. Вторая матрица была намеренно смещена на 24 байта (три значения типа Double). При этом производительность (использовался компилятор Intel 16.0) упала на 56–63 % для матриц размером от 1200 х 1200 до 4000 х 4000.

 

Массив структур или структура массивов

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

struct {
   uint r, g, b, w ; // a possible 2D color rgb pixel layout
} MyAoS[N] ;

В этой компоновке значения rgb расположены последовательно. Если программа работает с данными цветовой плоскости, то с высокой вероятностью в кэш будет помещена вся структура, но каждый раз будет использовано только одно значение, например g. Если данные хранятся в структуре массивов, компоновка может быть примерно такой:

struct {
   uint r[N] ;
   uint g[N] ;
   uint b[N] ;
   uint w[N] ;
} MySoA ;

Если данные хранятся в структуре массивов и программа работает со всеми значениями g (или r, или b), то весь кэш с высокой вероятностью будет использован в работе при помещении в кэш одной строки кэша.    Данные эффективнее загружаются в регистры SIMD, благодаря чему повышается эффективность и производительность. Во многих случаях разработчики программ временно перемещают данные в структуру массивов для обработки, а затем копируют обратно, когда это становится нужно. Во всех возможных случаях лучше избегать этого дополнительного копирования, поскольку из-за него выполнение занимает больше времени.

Анализ Memory Access Pattern (MAP) в Intel (Vectorization) Advisor 2016 выявляет циклы с последовательным, непоследовательным и нерегулярным доступом:

В столбце Strides Distribution предоставляется совокупная статистика о том, насколько часто используется каждая модель в заданном цикле. На приведенном выше рисунке две трети горизонтальной полосы закрашены синим (это последовательный доступ к памяти), а правая треть закрашена красным (это непоследовательный доступ). Для кода с компоновкой «массив структур» Advisor также может получить «рекомендацию» для преобразования массива структур в структуру массивов.  

Анализы моделей доступа и локальности памяти упрощены в Advisor MAP, они дополнительно предоставляют метрику использования памяти и сопоставляют диагностику каждого «шага» (то есть модель доступа) с определенными именами объектов и массивов C++ или Fortran*. Дополнительные сведения о Intel Advisor см. на сайтах

https://software.intel.com/en-us/get-started-with-advisor и https://software.intel.com/en-us/intel-advisor-xe

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

В компиляторе Intel, начиная с версии 2016 Update 1, преобразование «массив структур» -> «структура массивов» упрощено за счет применения шаблонов компоновки данных Intel® SIMD (Intel® SDLT). С помощью шаблонов SDLT можно просто переопределить контейнер массива структур следующим образом:

SDLT_PRIMITIVE(Point3s, x, y, z)
sdlt::soa1d_container<Point3s> inputDataSet(count);  

Это позволит обращаться к экземплярам Point3s по модели структуры массивов. Подробнее о SDLT см. здесь.

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

https://software.intel.com/en-us/articles/a-case-study-comparing-aos-arrays-of-structures-and-soa-structures-of-arrays-data-layouts

и

https://software.intel.com/en-us/articles/how-to-manipulate-data-structure-to-optimize-memory-use-on-32-bit-intel-architecture
http://stackoverflow.com/questions/17924705/structure-of-arrays-vs-array-of-structures-in-cuda

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

 

Заключение

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

Полный код можно загрузить здесь: https://github.com/drmackay/samplematrixcode

Если вы еще не читали первую часть этой статьи, то она находится здесь.

Примените описанные методики и оцените, насколько повысится производительность кода.

Дополнительные сведения об оптимизации компиляторов см. в нашем уведомлении об оптимизации

Технология Intel® RealSense™ в игре Ombre Fabula* с управлением жестами

$
0
0

Автор: Джон Тиррел (John Tyrrell)

OmbreFabula — прототип приложения, в котором объединены традиции европейских и азиатских театров теней. В этом приложении используется Intel® RealSense™ SDKдля создания интерактивной игры с тенями с управлением при помощи жестов. В процессе разработки команде создателей игры (Тьи Бинь Минь Нгуен (Thi Binh Minh Nguyen)и члены компании Prefrontal Cortex) пришлось преодолеть целый ряд затруднений. В частности, потребовалось добиться, чтобы камера Intel® RealSense™точно распознавала различные жесты руки с помощью собственных алгоритмов обнаружения BLOB. Потребовалось провести обширное тестирование с участием множества пользователей.


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

Проект OmbreFabulaзадумала Тьи Бинь Минь Нгуен (Thi Binh Minh Nguyen) в качестве учебного проекта для получения степени бакалавра. Затем с помощью компании дизайнеров-разработчиков Prefrontal Cortex этот проект был преобразован в интерактивную инсталляцию, работающую на ПК или ноутбуке, оборудованном камерой, направленной на пользователя. Минь объясняет, что возникло желание придать этому проекту новый интерактивный уровень, стереть границы между аудиторией и игроком.

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

Игра OmbreFabulaприняла участие в конкурсе Intel RealSense App Challenge 2014 года и заняла на нем второе место, уступив игре Ambassador.

Решения и проблемы

Разработчики обладали опытом работы с более специализированными HID-устройствами, их привлекли широкие возможности технологии Intel RealSense с точки зрения жестов, отслеживания лица и распознавания голоса, хотя в конечном итоге в интерфейсе OmbreFabulaиспользовались только жесты.

Создание пользовательского интерфейса

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


Проект Ombre Fabulaзадумывался как комнатная интерактивная инсталляция с как можно большим вовлечением участников. Здесь пользователь делает фигуру птицы.

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

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

The UI of Ombre Fabula
Пользователь ведет руку вправо, чтобы вывести главного героя игры из бабушкиного дома.

Реализация отслеживания рук

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

Ombre Fabula Animal Shapes
Простые жесты руки позволяют создать кролика, птицу и дракона.

Впрочем, быстро выяснилось, что алгоритмы Intel RealSense SDK не могли правильно обрабатывать тени из-за неоднородной видимости: пальцы сливались вместе и пересекались в одной плоскости. Камера Intel RealSense распознавала простейшие жесты (растопыренные пять пальцев, знак «V» указательным и средним пальцами, поднятый большой палец и т. д.), но этого было недостаточно для требовавшегося распознавания более сложных фигур животных.

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

Ombre Fabula Recognize Gestures
На этом рисунке жесты птицы, дракона и кролика показаны с маркированными контурами рук, благодаря чему Ombre Fabulaраспознает разные жесты.

Сначала извлечь необходимые данные контуров из Intel RealSense SDK было непросто. Интеграция Unity* отлично подходит для отслеживания ладоней и пальцев, но непригодна для эффективного отслеживания контуров. Впрочем, ознакомившись с документацией и поработав с Intel RealSense SDK, разработчики научились извлекать подробные данные контуров, необходимые для распознавания нестандартных фигур.


Пользователь складывает пальцы в фигуру кролика, чтобы на экране появилась теневая кукла кролика.


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

Использование собственного алгоритма обнаружения BLOB

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

// Code snippet from official Intel "HandContour.cs" script for blob contour extraction

int numOfBlobs = m_blob.QueryNumberOfBlobs();
PXCMImage[] blobImages = new PXCMImage[numOfBlobs];

for(int j = 0; j< numOfBlobs; j++)
{
	blobImages[j] = m_session.CreateImage(info);


	results = m_blob.QueryBlobData(j,  blobImages[j], out blobData[j]);
	if (results == pxcmStatus.PXCM_STATUS_NO_ERROR && blobData[j].pixelCount > 5000)
	{
		results = blobImages[j].AcquireAccess(PXCMImage.Access.ACCESS_WRITE, out new_bdata);
		blobImages[j].ReleaseAccess(new_bdata);
		BlobCenter = blobData[j].centerPoint;
		float contourSmooth = ContourSmoothing;
		m_contour.SetSmoothing(contourSmooth);
		results = m_contour.ProcessImage(blobImages[j]);
		if (results == pxcmStatus.PXCM_STATUS_NO_ERROR && m_contour.QueryNumberOfContours() > 0)
		{
			m_contour.QueryContourData(0, out pointOuter[j]);
			m_contour.QueryContourData(1, out pointInner[j]);
		}
	}
}

Для получения данных контуров из IntelRealSenseSDKиспользуется код извлечения контуров.

После этого упрощенные данные обрабатывали алгоритмом $P Point-Cloud Recognizer*. Это свободно доступный алгоритм, часто использующийся для распознавания символов, таких как рукописные штрихи. Разработчики внесли в этот алгоритм некоторые незначительные доработки и добились его правильной работы в Unity, а затем применили его для определения формы рук в OmbreFabula. Алгоритм определяет (с вероятностью порядка 90 %), фигуру какого животного изображают руки пользователя, после чего распознанная фигура отображается на экране.

// every few frames, we test if and which animal is currently found
void DetectAnimalContour () {
	// is there actually a contour in the image right now?
	if (handContour.points.Count > 0) {
		// ok, find the most probable animal gesture class
		string gesture = DetectGestureClass();
		// are we confident enough that this is one of the predefined animals?
		if (PointCloudRecognizer.Distance < 0.5) {
			// yes, we are: activate the correct animal
			ActivateAnimalByGesture(gesture);
		}
	}
}

// detect gesture on our contour
string DetectGesture() {
	// collect the contour points from the PCSDK
	Point[] contourPoints = handContour.points.Select (x => new Point (x.x, x.y, x.z, 0)).ToArray ();

	// create a new gesture to be detected, we don't know what it is yet
	var gesture = new Gesture(contourPoints, "yet unknown");

	// the classifier returns the gesture class name with the highest probability
	return PointCloudRecognizer.Classify(gesture, trainingSet.ToArray());
}

// This is from the $P algorithm
// match a gesture against a predefined training set
public static string Classify(Gesture candidate, Gesture[] trainingSet) {
	float minDistance = float.MaxValue;
	string gestureClass = "";
	foreach (Gesture template in trainingSet) {
		float dist = GreedyCloudMatch(candidate.Points, template.Points);
		if (dist < minDistance) {
			minDistance = dist;
			gestureClass = template.Name;
			Distance = dist;
		}
	}
	return gestureClass;
}

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

Получение отзывов пользователей на раннем этапе с помощью тестирования и наблюдения

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

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


При движении рук влево или вправо движется камера, а главный герой игры следует за животным по миру теней.

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

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

Игра OmbreFabulaоптимизирована для кратковременных игровых сеансов продолжительностью 6–10 минут. Люди, привлеченные для тестирования, отметили, что не возникает никакой усталости кистей и предплечий, поскольку пользователи естественным образом привыкли держать руки поднятыми в течение определенного времени.

Под капотом: инструменты и ресурсы

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

Intel RealSense SDK

Пакет Intel RealSense SDKиспользовали для сопоставления контуров рук, для чего очень пригодилась документация по отслеживанию контуров, входящая в состав SDK. Разработчики также использовали образцы Unity, предоставленные корпорацией Intel, когда сначала пробовали работать со встроенными возможностями отслеживания рук. Одного лишь отслеживания рук оказалось недостаточно, поэтому перешли к изображениям и реализовали собственный алгоритм отслеживания BLOB-объектов.

Программное обеспечение Unity

И Минь, и члены команды Prefrontal Cortex считают себя в первую очередь дизайнерами, им важно не тратить время на разработку платформ и написание кода, а быстро воплощать замыслы в действующие прототипы. В этом отношении платформа Unity позволила быстро создавать прототипы и переходить к дальнейшим этапам разработки. Кроме того, выяснилось, что набор инструментов Intel RealSense Unity в составе Intel RealSense SDK удобен в использовании и позволяет быстро приступить к работе.

$P Point-Cloud Recognizer

$P Point-Cloud Recognizer — это двухмерный программный алгоритм распознавания жестов, определяющий (с некоторым уровнем вероятности), в какую фигуру складываются штрихи ручки на бумаге или аналогичные графические данные. Этот алгоритм часто используется для быстрого создания прототипов в пользовательских интерфейсах с управлением жестами. Разработчики несколько изменили этот алгоритм и использовали его в Unity для определения фигуры, образованной руками пользователя, в OmbreFabula. Подсчитывая вероятность, алгоритм решает, какое из животных пытается изобразить пользователь, и приложение отображает соответствующее изображение животного.

Ombre Fabula Dragon
Чтобы появился дракон, нужно сложить две руки так, чтобы получились «челюсти», как показано на этом снимке экрана.

Ombre Fabula: что дальше?

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

Intel RealSense SDK: перспективы

Феликс Хербст (Felix Herbst) из команды Prefrontal Cortex твердо уверен в том, что системы управления с помощью жестов необходимо создавать с нуля, а попытки адаптировать существующие приложения к управлению с помощью жестов в большинстве случаев приведут к неудобству пользователей. Он подчеркивает важность анализа соответствующих сильных сторон всех возможных интерфейсов управления (включая и управление жестами) и выбор наиболее подходящей модели при разработке приложения.

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

О разработчиках

Минь Нгуен (Minh Nguyen)родилась во Вьетнаме и выросла в Германии. Она обладает значительным опытом работы и применяет современные технологии для создания интерактивных мультимедиарешений и игр. В настоящее время она учится в магистратуре Университета Бург Гибихенштайн в Германии по специальности «Дизайн мультимедиа и виртуальная реальность». Помимо учебы Минь под псевдонимом Tibimi участвует в работе над такими проектами, как Die besseren Wälder, игровой студии The Good Evil. Эта игра, созданная по мотивам известной театральной пьесы, призвана помочь детям и подросткам лучше узнать, что такое быть «другим».

Компания Prefrontal Cortex — это команда трех дизайнеров и разработчиков: Феликс Хербст (Felix Herbst), Пауль Кирстен (Paul Kirsten) и Кристиан Фрайтаг (Christian Freitag). Они создают самые невероятные решения, удивляющие и привлекающие пользователей. Среди их проектов — инсталляция Metaworlds*, посвященная созданию мира, интерактивная световая проекция [l]ichtbar на конференции Farbfest, инструмент Iterazer* для создания изображений с использованием мультисенсорного вода и игра Fight with Light* — шутер, управляемый движением глаз. Многопользовательская игра Weaver* этих разработчиков вышла в финал на конкурсе Intel App Innovation Contest 2013. Помимо этих экспериментальных проектов они создают интерактивные приложения для клиентов из различных отраслей, используя виртуальную и дополненную реальность.

И Минь, и разработчики Prefrontal Cortex намерены и далее использовать возможности технологий естественных интерфейсов, включая Intel RealSense.

Дополнительные ресурсы

Видео с демонстрацией OmbreFabula cм. здесь.

Для получения дополнительных сведений о создателях OmbreFabulaпосетите веб-сайты Минь Нгуен (Tibimi)и команды Prefrontal Cortex.

На сайте Intel® Developer Zone for Intel® RealSense™ разработчики найдут немало материалов, связанных с решениями Intel RealSense. Разработчики могут загрузить Intel RealSense SDKи Intel RealSense Developer Kit, а также ряд полезных учебных материалов по технологии Intel RealSense.

Версия 2016: новые возможности Intel® Media Server Studio

$
0
0

Кодирование 4K HEVC в реальном времени, стабильность декодирования AVC и MPEG2

Выпущена версия Intel® Media Server Studio 2016! В новой версии можно быстрее перекодировать высококачественное видео. 

В кодировщике HEVC в 1,1 раза повышена производительностьи на 10 % повышено качество. Intel® Media Server Studio помогает поставщикам решений перекодировки добиваться кодирования видео HEVC с разрешением 4K в реальном времени с пригодным для вещания качеством с помощью Intel® Visual Compute Accelerator на базе процессоров Intel® Xeon® E3 и некоторых процессоров Intel® Xeon® E51. Повышение стабильности декодирования AVC и MPEG2 позволяет обрабатывать ошибки в видеоматериалах. Подробные сведения о новых возможностях для перекодирования мультимедиа см. ниже.

Корпорация Intel является лидером в области ускорения обработки мультимедиа и облачных технологий. Благодаря мощи процессоров Intel®и Intel® Media Server Studio мы помогаем поставщикам решений мультимедиа, вещательным компаниям и разработчикам инфраструктуры создавать новые решения и добиваться высокой производительности, эффективности и высокого качества в приложениях для обработки мультимедиа и вещания видеоматериалов через Интернет.

Загрузить Media Server Studio 2016

Для зарегистрированных пользователей (требуется вход)  Для новых пользователей: получить бесплатно выпуск Community, ознакомиться с выпуском Pro или купить


 

Повышение производительности и качества HEVC (H.265) на 10 %, использование расширенного анализа на ГП, снижение объема данных

Professional Edition

  • Благодаря повышению производительности и качества на 10 % (по сравнению с предыдущей версией) поставщики решений мультимедиа могут кодировать видео 4KHEVCв реальном времени с пригодным для вещания качеством на некоторых платформах Intel Xeon E51с помощью программного решения Intel HEVC и Intel® Visual Compute Accelerator (Intel® VCA)1, применяя кодировщик HEVC с ускорением с помощью графического процессора (ГП).

  • Повышение производительности HEVCс ускорением на ГПза счет разгрузки циклических фильтров, таких как антиблочный фильтр (DBF) и адаптивное смещение выборки (SAO) на ГП (в прежних версиях эти фильтры выполнялись на ЦП).

Рисунок 1. В версии 2016 эффективность кодирования видео повышена на 10 % по сравнению с версией 2015 R7. В новой версии поддерживается не только кодирование в реальном времени видео с разрешением 4Kсо скоростью 30 кадров в секунду на некоторых процессорах Intel®Xeon®E5, но и кодирование в реальном времени видео с разрешением 1080pсо скоростью 50 кадров в секунду на платформах с процессорами Intel®Corei7 и XeonE3 предыдущего поколения**. Соотношение качества и производительности программного кодирования HEVCс ускорением на ГП для 8-битных видеоданных 4:2:0, 1080p. Базовый показатель качества соответствует стандарту ISOHM14 (0 %) и вычисляется с помощью кривых Y-PSNRBDRATE. Производительность — усредненная для четырех скоростей потока данных, от низкой (в среднем 3,8 МБ/с) до высокой (в среднем 25 МБ/с). Дополнительные сведения см. в информационном документе Высокое качество и производительность при использовании HEVC.

  • Благодаря усовершенствованиям Intel® VTune™ Amplifierразработчики смогут проще получать и интерпретировать данные об использовании ГП и о производительности приложений, оптимизированных для OpenCL* и Intel®MediaSDK. Поддерживается анализ распараллеливания нагрузки между ЦП и ГП, анализ использования ГП с аппаратными метриками, схема архитектуры ГП и многое другое.

  • Снижение объема данных при использовании кодека HEVC за счет кодирования на основе рабочих областей (ROI). Определенные рабочие области можно упаковывать с наименьшей степенью сжатия для сохранения наибольшей детализации по сравнению с другими областями. Эта функция повышает производительность приложений для видеоконференций. Для ее использования необходимо задать структуру mfxExtEncoderROI в приложении, чтобы указать разные рабочие области при кодировании. Это можно сделать при инициализации или во время выполнения.

  • Видеоконференции — более удобное проведение бизнес-конференций и сеансов видеосвязи с помощью особого режима HEVC с низкими задержками.

  • Новые возможности работы с разрешением 8K: не ограничивайте ваше приложение возможностью кодирования потоков с разрешением 4K. Кодек Intel HEVC в Media Server Studio 2016 поддерживает кодирование с разрешением 8K как программное, так и с ускорением с помощью ГП.

Усовершенствованное декодирование и перекодирование AVC (H.264) и MPEG2

Выпуски Community, Essentials, Pro

  • Усовершенствованная графика 5-го поколения и ускорители обработки мультимедиа вместе с собственными драйверами открывают возможность перекодирования до 16 потоков HDAVCс высоким качеством в реальном временина каждый процессор Intel Xeon E3 v4 (или с помощью Intel VCA)за счет применения аппаратного ускорения. 

  • До 12 потоков HD AVC на процессорах Intel® Core™ 4-го поколения с ГП Intel® Iris™**

  • Используйте повышенное качество кодирования AVC для BRefType MFX_B_REF_PYRAMID.

  • Декодер AVCи MPEG2 работает стабильнее: он способен обрабатывать поврежденные потоки и возвращать ошибки. Повышенная устойчивость декодирования AVC и MPEG2 обеспечивает стабильный вывод и безупречную обработку поврежденных видеоматериалов. Расширенные сообщения об ошибках помогут разработчикам удобнее находить и анализировать ошибки декодирования. 

Рисунок 2. В версии 2016 достигнут прирост производительности на 40 % по сравнению с версией 2015 в сценариях работы с H.264 за счет улучшенных алгоритмов планирования аппаратной нагрузки**. На этом рисунке показаны результаты кодирования нескольких потоков H.264 из одного исходного файла H.264 с ускорением с помощью Intel® Quick Sync Video с образцом кода multi_transcode (доступен в составе образцов кода). Каждая точка соответствует среднему значению для 4 потоков и 6 значений скорости данных; полоски погрешности показывают расхождение производительности для разных потоков и значений скорости данных. Параметр Target Usage со значением 7 (TU7) соответствует работе с наивысшей скоростью (и самым низким качеством). [Видеоматериалы с разрешением 1080p со скоростью 50 кадров в секунду получены из media.xiph.org/video/derf/: crowd_run, park_joy (30mbps input; 5, 7.1, 10.2, 14.6, 20.9, 30 mbps output; in_to_tree, old_town_cross 15 mbps input, 2.5, 3.5, 5.1, 7.3, 10.4, 15 mbps output).] Конфигурация: одновременное перекодирование AVC1→N с разной скоростью данных, 1080p, предустановка TU7, процессор Intel® Core™ i7-4770K с частотой 3,5 ГГц**. Количество каналов 1080p с различной скоростью данных.

Другие новые и улучшенные возможности

  • Усовершенствования в Intel® SDK для приложений OpenCL™для Windows включают новые возможности для разработки ядер.

  • Добавлена поддержка разностной предустановки качества уровня CTB для всех предустановок качества, т. е. для значений параметра Target Usage с 1 по 7 включительно для всех режимов управления скоростью данных (CBR, VBR, AVBR, ConstQP) и всех профилей (MAIN, MAIN10, REXT).

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

  • Кодирование H.264 напрямую работает с поверхностями с цветами ARGB (полученными с экрана или из игр) и YUY2, благодаря чему снижаются издержки на предварительную обработку (т. е. преобразование цветового пространства из RGB4 в NV12 для обработки в Intel® Media SDK), повышается производительность съемки с экрана.

Экономьте время, используя обновленные образцы кода

  • В образец sample_multi_transcode добавлены важные функции: расширенный конвейер включает несколько фильтров VPP, таких как композиция, удаление шума, детализация (обнаружение краев), управление кадровой скоростью (FRC), удаление чересстрочной развертки, преобразование цветового пространства (CSC).

  • В Sample_decode в пакете образцов для Linux поддерживается рендеринг видео с DRM, нужно использовать входной аргумент -rdrm. Образцы sample_decode и sample_decvpp объединены в образец decode с добавленными новыми фильтрами VPP, такими как удаление чересстрочной развертки и преобразование цветового пространства.

Дополнительные сведения

Выше описаны лишь некоторые, наиболее заметные функции и усовершенствования в Media Server Studio 2016. Посетите сайт продуктаи прочтите заметки к выпускам для получения дополнительных сведений.

  •  Заметки к выпускам Essential/Community Windows   Linux
  •  Заметки к выпуску Professional Edition:  Windows   Linux

1 Дополнительные сведения см. в разделе Технические характеристики.

**Базовая конфигурация: Intel® Media Server Studio 2016 Essentials по сравнению с версией 2015 R7, R4 под управлением Microsoft Windows* 2012 R2. Эталонная платформа Intel с процессором Intel® Core i7-4770K (84 Вт, 4 ядра, 3,5 ГГц, ГП Intel® HD Graphics 4600). Плата Intel Z87KL для настольных ПК с Intel Z87LPC, 16 ГБ ОЗУ (4 модуля UDIMM DDR3-1600 МГц по 4 ГБ), жесткий диск 1 ТБ, 7200 об./мин., SATA, включена технология Turbo Boost и гиперпоточность. Источник: внутренние измерения Intel по данным на январь 2016 г.

 

 

 

Введение в автономную навигацию для дополненной реальности

$
0
0

Download PDF
Download Code Sample

Райан Мизел (Ryan Measel) и Ашвин Синха (Ashwin Sinha)

1. Введение

Компьютерные системы с управлением без помощи контроллеров — новый этап во взаимодействии человека и компьютера. К этой области относятся технологии, воспринимающие физическую среду, включая распознавание жестов, распознавание голоса, распознавание лица, отслеживание движения, реконструкцию среды. Камеры Intel® RealSense™ F200 и R200 реализуют ряд возможностей из этой области. Благодаря возможности съемки с определением глубины камеры F200 и R200 позволяют выстраивать трехмерную среду и отслеживать движение устройства по отношению к среде. Реконструкция среды вместе с отслеживанием движения позволяет реализовать возможности виртуальной реальности, в которой виртуальные предметы вписываются в реальный мир. 

Камеры Intel RealSense могут предоставлять данные в приложения дополненной реальности, но создание действительно интересного виртуального мира — дело разработчиков. Один из способов создания живой среды состоит в использовании автономных агентов. Автономные агенты — это объекты, действующие независимо, используя искусственный интеллект. Искусственный интеллект определяет операционные параметры и правила, которым должен подчиняться агент. Агент динамически реагирует на условия среды, в которой он находится, в реальном времени, поэтому даже при простоте принципов действия может обладать сложной моделью поведения.

Автономные агенты могут существовать во множестве видов, однако в этом обсуждении мы остановимся на агентах, способных передвигаться и ориентироваться. К таким агентам относятся игровые персонажи, не управляемые игроком (NPC), и птицы, собирающиеся в стаи в учебных анимационных программах. Цели агентов будут различаться в зависимости от приложения, но принципы передвижения и навигации одинаковы во всех случаях.

Цель этой статьи — ознакомление с автономной навигацией и описание ее применения в приложениях дополненной реальности. Разработанный пример использует камеру Intel RealSense R200 и игровой движок Unity* 3D. Рекомендуется заранее ознакомиться с возможностями Intel® RealSense™ SDKи Unity. Сведения об интеграции Intel RealSense SDK с Unity см. в статьях Разработка игр с Unity* и камерой Intel® RealSense™ 3Dи Первый взгляд: дополненная реальность в Unity с Intel® RealSense™ R200.”

2. Автономная навигация

Навигацию агентов можно осуществить разными способами: как простыми, так и сложными, как с точки зрения реализации, так и с точки зрения ресурсоемкости. Самый простой подход — определить путь, по которому будет двигаться агент. Выбрана путевая точка, затем агент движется к ней по прямой линии. Такой подход несложен в реализации, но его применение сопряжено с несколькими проблемами. Наиболее очевидная из них: что произойдет, если между агентом и путевой точкой нет прямого пути (рис. 1)?

An agent moves along a straight path towards the target

Рисунок 1. Агент движется к цели по прямому пути, но путь прегражден препятствием. Примечание. Описываемые вопросы применимы к навигации и в двухмерном, и в трехмерном пространстве. Здесь для иллюстрации используется двухмерное пространство

Чтобы проложить маршрут в обход препятствий, требуется добавить дополнительные путевые точки (рис. 2).

Additional waypoints are added to allow the agent to navigate around obstacles

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

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

the number of waypoints and possible paths increases

Рисунок 3. По мере увеличения размеров карт увеличивается количество путевых точек и возможных маршрутов.

При большом количестве путевых точек требуется способ построения маршрута между двумя путевыми точками, расположенными не по соседству одна с другой. Эта проблема называется «поиском пути». Поиск пути тесно связан с теорией графов и применяется во множестве областей, не только в навигации. Естественно, в этой области ведется немало исследований, для решения различных проблем поиска пути создано множество алгоритмов. Одним из наиболее известных алгоритмов поиска пути является A*. Этот алгоритм предусматривает движение между соседними путевыми точками в сторону места назначения и построение карты всех посещенных путевых точек и всех путевых точек, соединенных с ними. После достижения места назначения алгоритм вычисляет путь, используя созданную карту. После этого агент может двигаться по этому пути. Алгоритм А* не предусматривает поиск по всему доступному пространству, поэтому построенный путь далеко не всегда является оптимальным. Эффективность такого алгоритма с точки зрения нагрузки на вычислительные ресурсы достаточно высока.

The A* algorithm traverses a map searching for a route to the target

Рисунок 4. Алгоритм A* осуществляет обход карты, пытаясь отыскать маршрут к целиАнимация: Subh83/CC BY 3.0

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

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

  1. Выбор действиясостоит из постановки целей и определения способов достижения этих целей. Например, кролик будет перемещаться по полю в поисках еды, но при появлении рядом хищника кролик будет спасаться бегством. Конечные автоматы (машины конечных состояний) удобно использовать для реализации такого поведения, поскольку они определяют состояния агента и условия, при которых состояния изменяются.
  2. Наведение — это расчет движения на основе текущего состояния агента. Например, если за кроликом гонится хищник, кролик должен убегать от хищника. Наведение вычисляет как величину, так и направление движения.
  3. Передвижение — это механика, посредством которой перемещается агент. Кролик, человек, автомобиль и космический корабль перемещаются разными способами. Передвижение определяет и способ движения (например, с помощью ног, колес, ракетных двигателей), и параметры этого движения (например, массу, максимальную скорость, максимальную силу и т. д.).

Вместе эти уровни образуют искусственный интеллект агента. В разделе 3 мы покажем пример приложения Unity, демонстрирующий реализацию этих трех уровней. В разделе 4 мы встраиваем автономную навигацию в приложение дополненной реальности с помощью камеры R200.

3. Реализация автономной навигации

В этом разделе описывается платформа поведения в сцене Unity для автономной навигации, начиная с движения.

Передвижение

Передвижение агента основывается на законах динамики Ньютона: при применении силы к массе возникает ускорение. Мы используем упрощенную модель с равномерно распределенной массой тела, к которому может быть применена сила с любого направления. Для ограничения движения задается максимальная сила и максимальная скорость (фрагмент кода 1).

public float mass = 1f;            // Mass (kg)
public float maxSpeed = 0.5f;      // Maximum speed (m/s)
public float maxForce = 1f;        // "Maximum force (N)

Фрагмент кода 1. Модель передвижения агента

Агент должен обладать компонентами rigidbody и collider, которые инициализируются при запуске (см. фрагмент кода 2). Для простоты модели гравитация исключена, но ее можно включить.

private void Start () {

	// Initialize the rigidbody
	this.rb = GetComponent<rigidbody> ();
	this.rb.mass = this.mass;
	this.rb.useGravity = false;

	// Initialize the collider
	this.col = GetComponent<collider> ();
}

Фрагмент кода 2. Компоненты rigidbodyи colliderинициализируются при Start()

Агент перемещается путем применения силы к rigidbody на шаге FixedUpdate() (см. фрагмент кода 3). FixedUpdate() работает аналогично Update(), но гарантированно выполняется с одинаковым интервалом в отличие от Update(). Движок Unity проводит расчет физики (операции с твердыми телами) после завершения шага FixedUpdate().

private void FixedUpdate () {

	Vector3 force = Vector3.forward;

	// Upper bound on force
	if (force.magnitude > this.maxForce) {
		force = force.normalized * this.maxForce;
	}

	// Apply the force
	rb.AddForce (force, ForceMode.Force);

	// Upper bound on speed
	if (rb.velocity.magnitude > this.maxSpeed) {
		rb.velocity = rb.velocity.normalized * this.maxSpeed;
	}
}

Фрагмент кода 3. Сила применяется к rigidbodyна шаге FixedUpdate(). В этом примере агент перемещается вдоль оси Z

Если величина силы превышает максимальную силу агента, она корректируется таким образом, чтобы сила величины была равна максимальной силе (направление сохраняется). Функция AddForce () применяет силу путем численного интегрирования.

Уравнение 1. Численное интегрирование скорости. Функция AddForce() осуществляет это вычисление.

Где — новая скорость, — прежняя скорость,  — сила, — масса, и — интервал времени между обновлениями (по умолчанию фиксированный шаг времени в Unity равен 0,02 с). Если величина скорости превышает максимальную скорость агента, она корректируется таким образом, чтобы совпадать с максимальной скоростью.

Наведение

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

Поиск

Поведение «Поиск» пытается как можно быстрее двигать объект к цели. Желаемая скорость этого поведения — движение напрямую к цели с максимальной скоростью. Сила наведения вычисляется как разница между желаемой и текущей скоростями агента (рис. 5).

Рисунок 5. Поведение «Поиск» применяет силу наведения, чтобы изменить текущую скорость до желаемой

Реализация (фрагмент кода 4) сначала вычисляет желаемый вектор путем нормализации смещения между агентом и целью и умножения его на максимальную скорость. Возвращаемая сила наведения — это желаемая скорость минус текущая скорость rigidbody.

private Vector3 Seek () {

	Vector3 desiredVelocity = (this.seekTarget.position - this.transform.position).normalized * this.maxSpeed;
	return desiredVelocity - this.rb.velocity;
}

Фрагмент кода 4. Поведение «Поиск»

Агент использует алгоритм «Поиск», вызывая Seek() при вычислении силы в FixedUpdate() (фрагмент кода 5).

private void FixedUpdate () {

	Vector3 force = Seek ();
	...

Фрагмент кода 5. Вызов Seek () в FixedUpdate ()

Пример алгоритма «Поиск» в действии показан на видео 1. Агент снабжен синей стрелкой, указывающей текущую скорость rigidbody, и красной стрелкой, указывающей, что на данном временном интервале применяется наведение.

Видео 1. Изначально скорость агента направлена перпендикулярно направлению на цель, поэтому агент движется по кривой

Прибытие

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

Поведение «Прибытие» (фрагмент кода 6) сначала вычисляет расстояние между агентом и целью. Приведенная скорость вычисляется как максимальная скорость, приведенная к расстоянию, разделенному на радиус замедления. Желаемая скорость является наименьшей между приведенной скоростью и максимальной скоростью. Таким образом, если расстояние до цели меньше радиуса замедления, то желаемая скорость является приведенной скоростью. В противном случае желаемая скорость является максимальной скоростью. Оставшаяся часть этой функции работает в точности как «Поиск» с желаемой скоростью.

// Arrive deceleration radius (m)
public float decelerationRadius = 1f;

private Vector3 Arrive () {

	// Calculate the desired speed
	Vector3 targetOffset = this.seekTarget.position - this.transform.position;
	float distance = targetOffset.magnitude;
	float scaledSpeed = (distance / this.decelerationRadius) * this.maxSpeed;
	float desiredSpeed = Mathf.Min (scaledSpeed, this.maxSpeed);

	// Compute the steering force
	Vector3 desiredVelocity = targetOffset.normalized * desiredSpeed;
	return desiredVelocity - this.rb.velocity;
}

Фрагмент кода 6. Поведение «Прибытие»

Видео 2. Алгоритм «Прибытие» снижает скорость при достижении цели

Уклонение от препятствий

Алгоритмы «Прибытие» и «Поиск» отлично подходят для прибытия к месту назначения, но не справляются с препятствиями. В динамичной среде агент должен иметь возможность уклоняться от новых появляющихся препятствий. Алгоритм «Уклонение от препятствий» анализирует путь перед агентом по предполагаемому маршруту и определяет, есть ли на этом пути какие-либо препятствия, которых следует избегать. Если препятствия обнаружены, то алгоритм вычисляет силу, изменяющую путь движения агента таким образом, что агент не сталкивается с препятствием (рис. 6).

Рисунок 6. Если на текущей траектории обнаруживается препятствие, возвращается сила, предотвращающая столкновение

Реализация алгоритма «Уклонение от препятствий» (фрагмент кода 7) использует spherecast для обнаружения столкновений. При этом вдоль текущего вектора скорости rigidbody выпускается сфера, а для каждого столкновения возвращается RaycastHit. Сфера движется из центра агента, ее радиус равен сумме радиуса столкновения объекта со значением параметра «Радиус уклонения». С помощью радиуса уклонения пользователь может определить пустое пространство вокруг агента. Дальность движения сферы ограничивается параметром «Переднее обнаружение».

// Avoidance radius (m). The desired amount of space between the agent and obstacles.
public float avoidanceRadius = 0.03f;
// Forward detection radius (m). The distance in front of the agent that is checked for obstacles.
public float forwardDetection = 0.5f;

private Vector3 ObstacleAvoidance () {

	Vector3 steeringForce = Vector3.zero;

	// Cast a sphere, that bounds the avoidance zone of the agent, to detect obstacles
	RaycastHit[] hits = Physics.SphereCastAll(this.transform.position, this.col.bounds.extents.x + this.avoidanceRadius, this.rb.velocity, this.forwardDetection);

	// Compute and sum the forces across all hits
	for(int i = 0; i < hits.Length; i++)    {

		// Ensure that the collidier is on a different object
		if (hits[i].collider.gameObject.GetInstanceID () != this.gameObject.GetInstanceID ()) {

			if (hits[i].distance > 0) {

				// Scale the force inversely proportional to the distance to the target
				float scaledForce = ((this.forwardDetection - hits[i].distance) / this.forwardDetection) * this.maxForce;
				float desiredForce = Mathf.Min (scaledForce, this.maxForce);

				// Compute the steering force
				steeringForce += hits[i].normal * desiredForce;
			}
		}
	}

	return steeringForce;
}

Фрагмент кода 7. Поведение «Уклонение от препятствий»

При использовании spherecast возвращается массив объектов RaycastHit. Объект RaycastHit содержит информацию о столкновении, в том числе расстояние до столкновения и нормаль к плоскости поверхности, с которой произошло столкновение. Нормаль — это вектор, перпендикулярный плоскости. Его можно использовать, чтобы направить агент в сторону от точки столкновения. Величина силы определяется путем приведения максимальной силы обратно пропорционально расстоянию до столкновения. Силы каждого столкновения складываются, а результат является суммарной силой уклонения в один временной интервал.

Для получения более сложного поведения можно использовать сразу несколько алгоритмов одновременно (фрагмент кода 8). Алгоритм «Уклонение от препятствий» полезен только при использовании вместе с другими алгоритмами. В этом примере (видео 3) «Уклонение от препятствий» используется вместе с алгоритмом «Прибытие». Алгоритмы поведения объединяются просто путем сложения их сил. Возможны и более сложные схемы, где для определения весовых коэффициентов приоритета сил используются эвристические механизмы.

private void FixedUpdate () {

	// Calculate the total steering force by summing the active steering behaviors
	Vector3 force = Arrive () + ObstacleAvoidance();
	...

Фрагмент кода 8. Алгоритмы «Прибытие» и «Уклонение от препятствий» используются одновременно путем сложения их сил

Видео 3. Агент использует сразу два типа поведения: «Прибытие» и «Уклонение от препятствий»

Выбор действия

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

4. Интеграция камеры R200

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

Следующий пример создан на основе примера Scene Perception, входящего в состав Intel RealSense SDK. Это приложение создает трехмерную модель с помощью Scene Perception, а пользователь сможет задать и перемещать цель в трехмерном пространстве. После этого агент сможет перемещаться по созданной трехмерной модели для достижения цели.

Scene Manager

Сценарий Scene Manager инициализирует сцену и обрабатывает пользовательское управление. Единственным видом управления является касание (или щелчок мыши, если устройство не поддерживает касания). Трассировка луча из точки касания определяет, происходит ли касание созданной трехмерной модели. Первое касание создает цель на трехмерной модели, второе — создает агента, а каждое последующее касание перемещает положение цели. Логику управления обрабатывает конечный автомат (фрагмент кода 9).

// State machine that controls the scene:
//         Start => SceneInitialized -> TargetInitialized -> AgentInitialized
private enum SceneState {SceneInitialized, TargetInitialized, AgentInitialized};
private SceneState state = SceneState.SceneInitialized;    // Initial scene state.

private void Update () {

	// Trigger when the user "clicks" with either the mouse or a touch up gesture.
	if(Input.GetMouseButtonUp (0)) {
		TouchHandler ();
	}
}

private void TouchHandler () {

	RaycastHit hit;

	// Raycast from the point touched on the screen
	if (Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out hit)) {

	 // Only register if the touch was on the generated mesh
		if (hit.collider.gameObject.name == "meshPrefab(Clone)") {

			switch (this.state) {
			case SceneState.SceneInitialized:
				SpawnTarget (hit);
				this.state = SceneState.TargetInitialized;
				break;
			case SceneState.TargetInitialized:
				SpawnAgent (hit);
				this.state = SceneState.AgentInitialized;
				break;
			case SceneState.AgentInitialized:
				MoveTarget (hit);
				break;
			default:
				Debug.LogError("Invalid scene state.");
				break;
			}
		}
	}
}

Фрагмент кода 9. Обработчик касаний и конечный автомат для примера приложения.

Компонент Scene Perception формирует множество небольших трехмерных моделей. Такие модели обычно имеют не более 30 вершин. Расположение вершин может изменяться, в результате чего некоторые модели несколько наклонены по отношению к поверхности, на которой они находятся. Если объект находится поверх модели (например, цели или объекта), то объект будет неправильно ориентирован. Чтобы обойти эту проблему, используется средняя нормаль трехмерной модели (фрагмент кода 10).

private Vector3 AverageMeshNormal(Mesh mesh) {

	Vector3 sum = Vector3.zero;

	// Sum all the normals in the mesh
	for (int i = 0; i < mesh.normals.Length; i++){
		sum += mesh.normals[i];
	}

	// Return the average
	return sum / mesh.normals.Length;
}

Фрагмент кода 10. Вычисление средней нормали трехмерной модели

Сборка приложения

Весь код, разработанный для этого примера, доступен на сайте Github.

Следующие инструкции встраивают Scene Manager и реализацию агента в приложение Intel® RealSense™.

  1. Откройте пример RF_ScenePerception в папке Intel RealSense SDK RSSDK\framework\Unity.
  2. Загрузитеи импортируйте пакет AutoNavAR Unity.
  3. Откройте RealSenseExampleScene в папке Assets/AutoNavAR/Scenes/.
  4. Соберите и запустите приложение на любом совместимом устройстве с камерой Intel RealSense R200.

Видео 4. Выполненная интеграция с камерой Intel®RealSenseR200

5. Дальнейшее развитие автономной навигации

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

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

Крейг Рейнольдс (Craig Reynolds) первым подробно описал поведенческие алгоритмы наведения в контексте анимации и игр. Алгоритмы «Поиск», «Прибытие» и «Уклонение от препятствий», продемонстрированные в нашем примере, созданы на основе его работы. Рейнольдс описал и другие алгоритмы поведения, в том числе «Бегство», «Преследование», «Странствие», «Исследование», «Уклонение от препятствий» и «Следование по маршруту». Рассматриваемые групповые алгоритмы поведения включают «Разделение», «Слияние» и «Построение». Еще один полезный ресурс — «Программирование искусственного интеллекта игр на примерах» Мэта Бэкленда (Mat Buckland). Здесь описывается реализация поведенческих алгоритмов и ряд других вопросов, в том числе конечные автоматы и поиск путей.

В этом примере к агенту одновременно применяются алгоритмы наведения «Прибытие» и «Уклонение от препятствий». Так можно сочетать любое количество алгоритмов поведения для получения более сложных моделей. Например, поведенческий алгоритм «Объединение в стаю» создан на основе разделения, слияния и построения. Сочетание различных поведенческих алгоритмов может иногда дать неестественный результат. Рекомендуется поэкспериментировать с разными типами таких алгоритмов для выявления новых возможностей.

Кроме того, некоторые методики поиска путей предназначены для использования в динамических средах. Алгоритм D*близок к A*, но может обновлять путь на основе новых наблюдений (т. е. добавленных и удаленных препятствий). Алгоритм D* Liteработает так же, как D*, и проще в реализации. Поиск путей можно использовать вместе с наведением: можно задать путевые точки, а затем использовать наведение для их обхода.

Выбор действий не обсуждается в этой статье, но широко изучается в теории игр. В теории игр исследуется математическая основа стратегии и принятия решений. Теория игр применяется во множестве областей, включая экономику, политические науки и психологию. В отношении автономных агентов теория игр может управлять тем, как и когда принимаются решения. «Теория игр 101: полный справочник» Уильяма Спаниэля (William Spaniel) — отличный начальный ресурс, снабженный серией видеоматериалов в YouTube.

6. Заключение

Существует целый арсенал инструментов для настройки движения, поведения и действий агентов. Автономная навигация наиболее подходит для динамических сред, подобных создаваемым камерой Intel RealSense в приложениях дополненной реальности. Даже простые модели движения и наведения могут образовывать сложное поведение без предварительного знания среды. Изобилие доступных моделей и алгоритмов обеспечивает гибкость реализации автономных решений для любых приложений.

Об авторах

Райан Мизел (Ryan Measel) — основатель и технический директор компании Fantasmo Studios. Ашвин Синха (Ashwin Sinha) — основатель и разработчик. Компания Fantasmo Studios, основанная в 2014 году, работает в области развлекательных технологий и занимается материалами и услугами для приложений смешанной реальности.


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

$
0
0

Download [PDF 1.2MB]

Введение

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

Ошибочный подход № 1. Недостаточное понимание технологий разработки

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

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

Это один из примеров ситуации, когда мы, разработчики, идем по неверному пути. Впрочем, таких путей немало. К примеру, когда я был моложе и только начинал знакомство с разработкой программного обеспечения, я старался во всем подражать моему начальнику: все, что он делал, казалось мне безупречным и безусловно правильным. Когда мне нужно было что-нибудь сделать, я смотрел, как то же самое делает начальник, и стремился как можно точнее повторить все его действия. Неоднократно бывало, что я просто не понимал, почему его подход работает, но разве это важно? Главное, что все работает!

Есть такой тип разработчиков, которые будут работать как можно упорнее, чтобы решить поставленную перед ними задачу. Как правило, они ищут уже готовые составляющие, компоненты, блоки, собирают все эти кусочки воедино, и готово! Задача выполнена! Такие разработчики редко тратят время, чтобы изучить и понять найденные фрагменты кода, и совершенно не заботятся о таких «второстепенных» вещах, как масштабируемость, удобство в обслуживании или производительность.

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

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

JavaScript* и DOM

Рассмотрим приведенный ниже пример кода. Все просто. Код всего лишь обновляет стиль одного элемента в DOM. Проблема (сейчас в современных браузерах эта проблема уже не столь актуальна, но она вполне пригодна для иллюстрации моей мысли) состоит в том, что код обходит дерево DOM три раза. Если код повторяется, а документ при этом достаточно крупный и сложный, производительность приложения ощутимо снизится.

Устранить такую проблему довольно просто. Посмотрите на следующий пример кода. Перед работой с объектом в переменной myFieldпроисходит удержание прямой ссылки. Новый код компактнее, его удобнее читать и понимать, и он быстрее работает, поскольку доступ к дереву DOM осуществляется только один раз.

Рассмотрим еще один пример. Этот пример взят из материала: http://code.tutsplus.com/tutorials/10-ways-to-instantly-increase-your-jquery-performance--net-5551

На следующем рисунке показаны два равноценных фрагмента кода. Каждый из них создает список с 1000 элементов li. Код справа добавляет атрибут idк каждому элементу li, а код слева добавляет атрибут classк каждому элементу li.

Как видите, вторая часть фрагмента кода просто обращается к каждому из тысячи созданных элементов li. Я измерил скорость в браузерах Internet Explorer* 10 и Chrome* 48: среднее время выполнения кода, приведенного слева, составило 57 мс, а время выполнения кода, показанного справа, — всего 9 мс, существенно меньше. Разница огромна, притом что в данном случае она обусловлена лишь разными способами доступа к элементам.

К этому примеру стоит отнестись крайне внимательно. В этом примере есть еще немало интересных для анализа моментов, например порядок проверки селекторов (здесь это порядок справа налево). Если вы используете jQuery*, то почитайте и про контекст DOM. Сведения об общих принципах производительности селекторов CSS см. в следующей статье: https://smacss.com/book/selectors

Заключительный пример — код JavaScript. Этот пример более связан с памятью, но поможет понять, как все работает на самом деле. Излишнее потребление памяти в браузерах приведет к снижению производительности.

На следующем рисунке показано два разных способа создания объекта с двумя свойствами и одним методом. Слева конструктор класса добавляет два свойства в объект, а дополнительный метод добавляется через прототип класса. Справа конструктор добавляет сразу и свойства, и метод.

После создания такого объекта создаются тысячи объектов с помощью этих двух способов. Если сравнить объем памяти, используемой этими объектами, вы заметите разницу в использовании областей памяти Shallow Size и Retained Size в Chrome. Подход, где используется прототип, задействует примерно на 20 % меньше памяти (20 КБ по сравнению с 24 КБ) в области Shallow Size и на 66 % меньше в области Retained Memory (20 КБ по сравнению с 60 КБ).

Для получения дополнительных сведений о характеристиках памяти Shallow Size и Retained Size см.

https://developers.google.com/web/tools/chrome-devtools/profile/memory-problems/memory-101?hl=en

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

LINQ

При подготовке к выступлению на конференции по описываемой теме я решил подготовить пример с серверным кодом. Я решил использовать LINQ*, поскольку LINQ получил широкое распространение в мире .NET для новых разработок и обладает значительным потенциалом для повышения производительности.

Рассмотрим следующий распространенный сценарий. На следующем рисунке показано два функционально равноценных фрагмента кода. Цель кода — создать список всех отделений и всех курсов для каждого отделения в школе. В коде под названием Select N+1 мы выводим список всех отделений, а для каждого отделения — список курсов. Это означает, что при наличии 100 отделений нам потребуется 1 + 100 вызовов к базе данных.

Эту задачу можно решить и иначе. Один из простых подходов показан во фрагменте кода с правой стороны. При использовании метода Include (в этом случае я задействую жестко заданную строку для простоты понимания) будет всего один вызов к базе данных, и этот единственный вызов выдаст сразу все отделения и курсы. В этом случае при выполнении второго цикла foreachвсе коллекции Courses для каждого отделения уже будут в памяти.

Таким образом, можно повысить производительность в сотни раз, просто избегая подхода Select N+1.

Рассмотрим менее очевидный пример.

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

В примере Code #1, где ожидается тип данных IEnumerable, запрос выполняется непосредственно перед выполнением Take<Employee>(10). Это означает, что при наличии 1000 сотрудников они все будут получены из базы данных, после чего из них будет выбрано 10.

В примере Code #2 запрос выполняется после выполнения Take<Employee>(10).
Из базы данных при этом извлекается всего 10 записей.

В следующей статье подробно поясняются различия при использовании разных типов коллекций.

http://www.codeproject.com/Articles/832189/List-vs-IEnumerable-vs-IQueryable-vs-ICollection-v

SQL Server*

В SQL необходимо изучить множество особенностей, чтобы добиться наивысшей производительности базы данных. Работать с SQL Server непросто: нужно понимать, как используются данные, какие таблицы запрашиваются чаще всего и какими именно полями.

Тем не менее для повышения производительности можно применять и ряд общих принципов, например:

  • кластерные либо некластерные индексы;
  • правильный порядок инструкций JOIN;
  • понимание, когда следует использовать таблицы #tempи таблицы переменных;
  • использование представлений либо индексированных представлений;
  • использование заранее скомпилированных инструкций.

Для краткости я не буду приводить конкретных примеров, но эти принципы можно использовать, анализировать и оптимизировать.

Изменение образа мышления

Итак, как мы, разработчики, должны изменить образ мышления, чтобы избегать ошибочного подхода № 1?

  • Перестаньте думать: «Я — разработчик интерфейсов» или «Я — разработчик внутреннего кода». Возможно, вы инженер, вы специализируетесь на какой-то одной области, но не используете эту специализацию, чтобы отгораживаться от изучения и других областей.
  • Перестаньте думать: «Пусть этим занимается специалист, потому что у него получится быстрее». В современном мире в ходу гибкость, мы должны быть многофункциональными ресурсами, мы должны изучать области, в которых наши знания недостаточны.
  • Перестаньте говорить себе: «Я этого не понимаю». Разумеется, если бы это было просто, то все уже давно стали бы специалистами. Не стесняйтесь тратить время на чтение, консультации и изучение. Это нелегко, но рано или поздно окупится.
  • Перестаньте говорить: «Мне некогда». Это возражение я могу понять. Так бывает нередко. Но однажды один коллега в Intel сказал: «Если тебе действительно интересно что-либо, то и время на это найдется». Вот эту статью я пишу, например, в субботу в полночь!

Ошибочный подход № 2. Предпочтение определенных технологий

Я занимаюсь разработкой на .NET с версии 1.0. Я в мельчайших подробностях знаю все особенности работы веб-форм, а также множества клиентских библиотек .NET (некоторые из них я самостоятельно изменил). Когда я узнал о выпуске Model View Controller (MVC), то не хотел его использовать: «Это нам не нужно».

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

Мне часто приходится слышать обсуждения, касающиеся либо связи LINQ с объектами в Entity Framework, либо хранимых процедур SQL при запросе данных. Люди настолько привыкли использовать одно или другое решение, что пытаются использовать их везде.

Еще один фактор, влияющий на предпочтения разработчиков (преимущественный выбор одних технологий и отказ от других), — личное отношение к ПО с открытым исходным кодом. Разработчики зачастую выбирают не то решение, которое лучше всего подходит для текущей ситуации, а то, которое лучше согласуется с их жизненной философией.

Иногда внешние факторы (например, жесткие сроки) вынуждают нас принимать неоптимальные решения. Для выбора наилучшей технологии требуется время: нужно читать, пробовать, сравнивать и делать выводы. При разработке нового продукта или новой версии существующего продукта часто бывает, что мы уже опаздываем: «Крайний срок — вчера». Два очевидных выхода из такой ситуации: затребовать дополнительное время или работать сверхурочно для самообразования.

Изменение образа мышления

Как мы, разработчики, должны изменить образ мышления, чтобы избегать ошибочного подхода № 2:

  • Перестаньте говорить: «Этот способ всегда работал», «Мы всегда делали именно так» и т. д. Нужно знать и использовать и другие варианты, особенно если эти варианты в чем-то лучше.
  • Не пытайтесь использовать неподходящие решения! Бывает, что разработчики упорно пытаются применять какую-то определенную технологию, которая не дает и не может дать нужных результатов. Разработчики тратят много времени и сил, стараясь все же как-то доработать эту технологию, подогнать ее под результат, не рассматривая иных вариантов. Такой неблагодарный процесс можно назвать «попыткой натянуть сову на глобус»: это стремление ценой любых усилий приспособить существующее неподходящее решение вместо того, чтобы сосредоточиться на проблеме и отыскать другое, более изящное и быстрое решение.
  • «Мне некогда». Разумеется, у нас всегда не хватает времени на изучение нового. Это возражение я могу понять.

Ошибочный подход № 3.Недостаточное понимание инфраструктуры приложения

Итак, мы приложили немало усилий и создали самое лучшее приложение. Пора перейти к его развертыванию. Мы все протестировали. На наших машинах все превосходно работает. Все 10 тестировщиков были полностью довольны и самим приложением, и его производительностью. Следовательно, теперь уж точно никаких проблем не может возникнуть, все в полнейшем порядке?

Отнюдь, все может быть вовсе не в порядке!

Задали ли вы себе следующие вопросы?

  • Пригодно ли приложение для работы в среде с балансировкой нагрузки?
  • Приложение будет размещено в облаке, где будет много экземпляров этого приложения?
  • Сколько других приложений работают на машине, для которой предназначено мое приложение?
  • Какие еще программы выполняются на этом сервере? SQL Server? Службы Reporting Services? Какие-либо расширения SharePoint*?
  • Где находятся конечные пользователи? Они распределены по всему миру?
  • Сколько пользователей будет у моего приложения в течение следующих пяти лет?

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

Давайте рассмотрим несколько возможных факторов, которые могут повлиять на производительность нашего приложения. Предположим, что пользователи находятся в разных странах мира. Быть может, приложение будет работать очень быстро, без каких-либо жалоб со стороны пользователей в США, но вот пользователи из Малайзии будут жаловаться на низкую скорость.

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

Возможна еще одна ситуация: предположим, что приложения работают на серверах, на которых одновременно запущена СУБД SQL Server и веб-сервер. В этом случае на одном физическом сервере выполняются одновременно две серверных системы с интенсивной нагрузкой на ЦП. Как решить эту проблему? Если мы говорим о приложении .NET на сервере Internet Information Services (IIS), то можно воспользоваться соответствием процессоров. Соответствие процессоров — это привязка одного процесса к одному или нескольким определенным ядрам ЦП компьютера.

К примеру, предположим, что на компьютере с четырьмя процессорами выполняется SQL Server и веб-сервер IIS.

Если позволить операционной системе решить, какой ЦП будет использоваться для SQL Server, а какой — для IIS, ресурсы могут распределяться по-разному. Возможно, что каждой серверной нагрузке будет назначено по два процессора.

А возможно, что все четыре процессора будут выделены только одной нагрузке.

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

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

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


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

Изменение образа мышления

Как мы, разработчики, должны изменить образ мышления, чтобы избегать ошибочного подхода № 3?

  • Перестаньте думать: «Это не моя работа». Мы, инженеры, должны стремиться расширять кругозор, чтобы предоставлять заказчикам наилучшее решение.
  • «Мне некогда». Разумеется, нам всегда некогда. Это самое распространенное обстоятельство. Выделение времени — то, что отличает успешного, опытного, выдающегося профессионала.

Не оправдывайтесь!

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

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

Вот как их можно избежать.

  1. Выделяйте время, если нужно — с запасом. Когда у вас просят оценить сроки, необходимые для работы над проектом, не забудьте выделить время для исследования и тестирования, для подготовки выводов и принятия решений.
  2. Постарайтесь одновременно создать и личное приложение для тестирования. В этом приложении вы сможете пробовать разные решения перед их воплощением (или отказом от их воплощения) в разрабатываемом приложении. Мы все порой ошибаемся.
  3. Найдите людей, уже владеющих нужной технологией, и попробуйте программировать вместе. Поработайте со специалистом, который разбирается в инфраструктуре, когда он будет развертывать приложение. Это время будет потрачено с пользой.
  4. Избегайте переполнения стека! Большая часть моих проблем уже решена. Если просто копировать ответы, не анализируя их, вы в итоге получите неполное решение.
  5. Не считайте себя узким специалистом, не ограничивайте свои возможности. Разумеется, если вам удастся стать экспертом в какой-либо области, это замечательно, но вы должны уметь поддержать разговор на должном уровне и в том случае, если разговор касается областей, в которых вы пока не являетесь экспертом.
  6. Помогайте другим! Это, пожалуй, один из лучших способов обучения. Если вы помогаете другим решать их проблемы, то в конечном итоге вы сэкономите собственное время, поскольку уже будете знать, что делать, если столкнетесь с подобными проблемами.

См. также

Веселый и интересный блог Скотта Хансельмана (Scott Hanselman) о том, как лучше создавать код: разрабатывать самому или находить в Google.

http://www.hanselman.com/blog/AmIReallyADeveloperOrJustAGoodGoogler.aspx

Информация об объектах и прототипах:

http://thecodeship.com/web-development/methods-within-constructor-vs-prototype-in-javascript/

Об авторе

Александр Гарсия (Alexander García) — компьютерный инженер из филиала корпорации Intel в Коста-Рике. Он обладает 14-летним профессиональным опытом создания программного обеспечения. Сфера интересов Александра весьма разнообразна — от практики разработки программного обеспечения и безопасности программ до производительности, интеллектуального анализа данных и смежных областей.  В настоящее время Александр обладает ученой степенью магистра в области компьютерных наук.

 

RealPerspective: отслеживание движения головы с помощью технологии Intel® RealSense™

$
0
0

Code Sample

Введение

В RealPerspective используется технология Intel® RealSense™. В этом примере кода реализовано отслеживание движения головы для точного позиционирования в трехмерном пространстве.

Работая с системой, оборудованной камерой Intel® RealSense®, пользователь может управлять обзором в игре, поворачивая голову. Так наши технологии позволяют заглянуть в вирту­альный мир. Обычно для таких задач применялись цветные камеры или инфракрасные датчики[3], но камера Intel RealSense предоставляет данные о глубине сцены, поэтому с ней не требуется никакого дополнительного оборудования на пользователе.

В образце кода используется проецирование перспективы вне осей, описанное в работе Куима (Kooima)[1]. Входные данные — пространственные координаты X и Y лица, а также средняя глубина лица.

Сборка и развертывание

Для создания программы требуется пакет Intel® RealSense™ SDKи Intel RealSense Depth Camera Manager.

Для развертывания пакета конечными пользователями понадобится установить соответствующий распространяемый модуль среды выполнения SDK.

Загрузить SDK, среду выполнения SDK и Depth Camera Manager можно здесь: https://software.intel.com/ru-ru/intel-realsense-sdk/download

Unity

В проекте Unity для совместимости с пакетом SDK, установленным на компьютере, следует заменить файлы libpxcclr.unity.dllи libpxccpp2c.dll, находящиеся в папках проекта Libraries\x64 и Libraries\x86, на библиотеки DLL из папок bin\x64 и bin\x86 пакета Intel RealSense SDK.

Метод

Инициализация камеры Intel RealSense

При запуске Sense Manager инициализирует и настраивает модуль face для обнаружения лица (ограничивающий прямоугольник и глубина). После этого конвейер Sense Manager будет готов к приему данных.

Обработка ввода

Функция обработки ввода возвращает объект Vector3, нормализованный до 0 к 1, содержащий положение лица в трехмерном пространстве, полученное от камеры Intel RealSense. Если камера Intel RealSense недоступна, используются координаты мыши.

Координаты расположения лица X, Y и Z берутся из модуля face пакета Intel RealSense SDK. Плоские координаты X и Y лица отсчитываются от центра прямоугольника, в который вписано лицо, измеряются в пикселях. Координата Z лица — средняя глубина лица в миллиметрах. Эта функция не блокирует другие, поэтому, если данные недоступны, работа функции Update не будет задержана. В противном случае прежние матрицы перспективы и просмотра не изменяются.

Вычисление внеосевых параметров

Точки pa, pbи pcопределяют пространство экрана и задают размер экрана, его соотношение сторон и ориентацию в пространстве. Пространство экрана масштабируется на основе размера экрана и окна приложения. Наконец, n и fопределяют передний и задний планы. В Unity эти значения берутся из класса Camera.

Например, если комната имеет размер 16 на 9 единиц с соотношением сторон 16:9, то можно задать такие pa, pb, pc, чтобы комната занимала весь экран. Расстояние от paдо pbбудет шириной комнаты, 16 единиц, а расстояние от paдо pc — высота комнаты, 9 единиц. Дополнительные примеры см. в статье Роберта Куима (Kooima)[1].

Off-Axis Parameters

Вычисление внеосевых матриц

Назначение этой функции — возвращать внеосевую матрицу. Матрица проекции основывается на стандарте OpenGL* glFrustum. Последний этап — выравнивание направления взгляда с плоскостью XY и преобразование координат. Этот процесс аналогичен действиям камеры или матрицы просмотра в графическом конвейере.

Матрица проекции

Сначала вычисляются ортонормальные базисные векторы (vr, vu, vn) на основе пространства экрана. Впоследствии ортонормальные базисные векторы помогут спроецировать пространство экрана на передний план и создать матрицу, чтобы выровнять пространство отслеживания с плоскостью XY.

Off-Axis Matrices

Затем из плоскости экрана создаются векторы пространства экрана va, vbи vc.

Screen extents vectors

После этого на основе пространства экрана вычисляются стороны усеченной пирамиды l, r, bи t (путем проецирования базовых векторов на векторы пространства экрана для получения их расположения на плоскости), а затем уменьшаются на коэффициент расстояния от плоскости экрана до переднего плана. Это обусловлено тем, что стороны усеченной пирамиды определяют усеченную пирамиду, построенную на плоскости переднего плана.

Наконец, после вычисления сторон усеченной пирамиды значения подаются в функцию glFrustum для получения матрицы перспективной проекции. Поле обзора вычисляется по сторонам усеченной пирамиды[2].

Ориентация плоскости проекции

Эффект перспективного сокращения проекции работает только при исходном положении точки обзора. Поэтому первый шаг — выравнивание экрана с плоскостью XY. Матрица M создается для получения системы прямоугольных (декартовых) координат по базисным векторам (vr, vuи vn). Пространство экрана нужно выровнять с плоскостью XY, поэтому берется транспозиция матрицы M.

Сдвиг точки обзора

Аналогичным образом отслеживаемое положение глаза peнеобходимо переместить к усеченной пирамиде. Для этого используется матрица преобразования T.

Композиция

Вычисленные матрицы передаются обратно в структуру данных Camera в Unity.

Производительность

В качестве тестового устройства использовалась система BRIX* Pro компании GIGABYTE Technology с процессором Intel® Core™ i7-4770R (выделение тепла — 65 Вт).

Издержки производительности в среднем весьма низки. На выполнение функции Update() требуется менее 1 мс. Около 0,5 мс необходимо для последовательно обнаруженных кадров с лицами, 0,2 мс — для кадров без лиц. Новые данные поступают каждые 33 мс.

Использование и дальнейшая работа

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

Возможные сценарии использования — игры жанра RTS (стратегии в реальном времени), MOBA (многопользовательская сетевая боевая арена), настольные игры, в которых пользователь может наблюдать за действиями и ходами, как при игре в шахматы. В симуляторах и играх с экспериментальной средой пользователь наблюдает действие и может выбрать наиболее удобный ракурс наблюдения за своими виртуальными персонажами с возможностью приближения для более подробного просмотра.

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

Справочные материалы

[1]: Роберт Куима (Kooima, Robert). Перспективное проецирование в целом. 2009.

[2]: OpenGL.org. Преобразования.

[3]: Джонни Ли (Johnny Lee). Отслеживание движений головы для систем виртуальной реальности с использованием Wii Remote. 2007.

Приложение

Требования

  • Система с Intel RealSense или камера SR300
  • Intel RealSense SDK 6.0 или более поздней версии
  • Intel RealSense Depth Camera Manager SR300 3.0 или более поздней версии
  • Microsoft Windows 8.1* или более поздней версии
  • Unity 5.3 или более поздней версии

Руководство разработчика по методам обнаружения камер Intel® RealSense™

$
0
0

Аннотация

В связи с выпуском новой камеры переднего обзора SR300 были внесены изменения в Intel® RealSense™ SDKи Intel® RealSense™ Depth Camera Manager. Из-за этих изменений существующие приложения могут перестать работать. В этой статье приводится обзор некоторых аспектов разработки приложений, работающих с разными камерами: Intel® RealSense™ F200и SR300. Также описываются методы определения моделей камер переднего и заднего обзора в Intel RealSense SDK. В частности, эти методы предусматривают использование сценариев установщика для обнаружения локального устройства съемки и использование Intel RealSense SDK для определения модели камеры и ее конфигурации во время выполнения. Эта статья предназначена для начинающих разработчиков и специалистов среднего уровня, которые либо уже разрабатывали приложения для камер F200 и хотят убедиться в совместимости этих приложений с камерами SR300, либо хотят разработать новые приложения Intel® RealSense™ для новых возможностей камер SR300.

Введение

В связи с выпуском новой, усовершенствованной камеры переднего обзора Intel RealSense SR300 был внесен ряд изменений в пакет Intel RealSense SDK. Теперь следует принимать во внимание новые факторы для поддержания совместимости приложений с разными версиями SDK. В SDK, начиная с версии R5 2015 для Windows*, поддерживаются три модели камер: камера заднего обзора Intel RealSense R200 и две камеры переднего обзора (камера F200 и более новая камера SR300). В модели SR300 применен ряд усовершенствований по сравнению с F200: увеличена дальность отслеживания, улучшено обнаружение движений, используются более совершенные датчики цветного изображения и инфракрасные датчики, снижена нагрузка на системные ресурсы. Разработчикам рекомендуется создавать новые, интересные приложения, использующие эти новые возможности.

Тем не менее наличие систем с разными моделями камер переднего обзора повлекло определенные проблемы для разработчиков. Необходимо выполнять определенные действия, чтобы проверить наличие и конфигурацию камеры Intel RealSense для обеспечения совместимости. В этой статье приводятся наиболее известные методы разработки приложений для SR300 и адаптации приложений, предназначенных для камеры F200, к платформе SR300 с сохранением совместимости с обеими моделями камер.

Определение камеры Intel® RealSense™ при установке

Чтобы обеспечить поддержку камеры, следует проверить, какая модель камеры есть в системе на момент установки приложения. Сценарий установщика в Intel RealSense SDK поддерживает возможность проверки наличия любых моделей камер с помощью параметров командной строки. Кроме случаев, когда требуется какая-либо одна определенная модель камеры, мы рекомендуем использовать установщик для определения не модели, а ориентации камеры (передний или задний обзор), чтобы приложение поддерживало платформы с разными моделями камеры. Если же нужно проверить наличие определенных функций, можно проверять конкретную модель камеры (Intel RealSense F200, SR300 и R200), указав соответствующие параметры. Если запрошенная модель камеры не будет обнаружена, программа установки завершит работу с кодом ошибки. Полный список команд установщика SDK см. на веб-сайте документации SDKв разделе Параметры установщика. Параметры, относящиеся к определению камеры, и образцы команд приведены ниже.

Параметр команды установщика

--f200
--sr300
--f200
--r200

Принудительная проверка модели камеры, чтобы среда выполнения устанав­ливалась только при обнаружении указанной модели камеры. Если модель камеры не обнаружена, программа установки завершает работу с кодом состояния 1633.

--front
--rear

Если указан параметр --front, установщик проверяет наличие любой камеры переднего обзора, а если указан параметр --rear, то установщик проверяет наличие любой камеры заднего обзора.

Примеры

Определение наличия любой камеры заднего обзора и автоматическая установка среды выполнения трехмерного сканирования путем загрузки с веб-сайта:

intel_rs_sdk_runtime_websetup_YYYY.exe --rear --silent --no-progress --acceptlicense=yes --finstall=core,3ds --fnone=all

Определение наличия камеры F200 и автоматическая установка среды выполнения face:

intel_rs_sdk_runtime_YYYY.exe --f200 --silent --no-progress --acceptlicense=yes --finstall=core,face3d --fnone=all

Определение конфигурации камеры Intel RealSense во время выполнения

Проверив правильность определения камеры во время установки, следует проверить версию устройства съемки и драйвера, т. е. версию Intel RealSense Depth Camera Manager (DCM), при инициализации приложения. Для этого используйте механизмы в составе Intel RealSense SDK, например DeviceInfoи ImplDesc. Обратите внимание, что информация об устройстве действительна только после функции Initинтерфейса SenseManager.

Проверка модели камеры

Чтобы проверить модель камеры при запуске, используйте функцию QueryDeviceInfo, которая возвращает структуру DeviceInfo. Структура DeviceInfoвключает переменную-член DeviceModel, в состав которой входят все доступные поддерживаемые модели камер. Обратите внимание, что все значения, перечисленные переменной DeviceModel, включают заранее заданные модели камер, которые будут изменяться по мере развития SDK. Нужно убедиться в том, что версия SDK, в которой компилируется ваше приложение, достаточно свежая и включает поддержку нужной модели камеры, необходимой вашему приложению.

В примере кода 1 показано использование функции QueryDeviceInfoдля получения модели подключенной камеры на C++. Обратите внимание, что информация об устройстве действительна только после функции Initинтерфейса SenseManager.

Пример кода 1.Проверка модели камеры во время выполнения с помощью DeviceInfo

// Create a SenseManager instance
PXCSenseManager *sm=PXCSenseManager::CreateInstance();
// Other SenseManager configuration (say, enable streams or modules)
...
// Initialize for starting streaming.
sm->Init();
// Get the camera info
PXCCapture::DeviceInfo dinfo={};
sm->QueryCaptureManager()->QueryDevice()->QueryDeviceInfo(&dinfo);
printf_s("camera model = %d\n", dinfo.model);
// Clean up
sm->Release();

Проверка версии Intel RealSense Depth Camera Manager во время выполнения

Пакет Intel RealSense SDK также дает возможность проверять версию DCM во время выполнения (помимо версий среды выполнения SDK и отдельных алгоритмов). Это полезно, чтобы убедиться в том, что необходимые технологии Intel® RealSense™ установлены в системе. Устаревшая версия DCM может вызвать непредвиденное поведение камеры, неработоспособность различных функций SDK (таких как обнаружение, отслеживание и т. п.) или снижение производительности. Кроме того, последняя версия Gold DCM для камеры Intel RealSense SR300 необходима, чтобы реализовать обратную совместимость для приложений, предназначенных для камеры F200 (последнюю версию SR300 DCMнеобходимо установить на ПК с Windows 10 с помощью Центра обновления Windows). Приложение, разработанное в SDK версии до R5 2015 для камеры F200, должно проверять и модель камеры, и версию DCM при запуске, чтобы обеспечить совместимость на компьютере с камерой SR300.

Для проверки версии драйвера камеры во время выполнения используйте функцию QueryModuleDesc, которая возвращает дескриптор указанного модуля в структуре ImplDesc. Для получения версии драйвера камеры укажите устройство съемки в качестве входного аргумента для QueryModuleDescи получите версию в качестве члена структуры ImplDesc. В примере кода 2 показано получение версии драйвера камеры в SDK версии R5 с помощью кода на C++. Если в системе не установлен DCM, то вызов QueryModuleDescвозвращает ошибку STATUS_ITEM_UNAVAILABLE. В случае отсутствия DCM или несовпадения версии рекомендуется предложить пользователю установить последнюю версию с помощью Центра обновления Windows. Полные сведения о проверке версий SDK, камеры и алгоритмов см. в разделе справки Проверка версий SDK, драйвера камеры и алгоритмовна веб-сайте документации SDK.

Пример кода 2.Получение версий алгоритма и драйвера камеры во время выполнения с помощью ImplDesc

PXCSession::ImplVersion GetVersion(PXCSession *session, PXCBase *module) {
    PXCSession::ImplDesc mdesc={};
    session->QueryModuleDesc(module, &mdesc);
    return mdesc.version;
}
// sm is the PXCSenseManager instance
PXCSession::ImplVersion driver_version=GetVersion(sm->QuerySession(), sm->QueryCaptureManager()->QueryCapture());
PXCSession::ImplVersion face_version=GetVersion(sm->QuerySession(), sm->QueryFace());

Разработка для разных моделей камер переднего обзора

Начиная с SDK версии R5 2015 для Windows, в список поддерживаемых камер добавлена новая камера Intel RealSense SR300. Камера SR300 является улучшенной версией модели Intel RealSense F200. Усовершенствования затронули несколько важных областей: увеличена дальность отслеживания, снижено потребление электроэнергии, повышено качество цветопередачи при малой яркости освещения, повышено соотношение «сигнал/шум» для ИК-датчика и т. д. В приложениях, использующих возможности SR300, можно добиться повышенного качества и скорости отслеживания, а также ускоренного реагирования по сравнению с приложениями для F200. Впрочем, выпуск новой камеры означает повышение сложности и в обеспечении совместимости приложений, и в задействовании конкретных функций в разных моделях камер.

В этом разделе приводятся основные факторы, которые необходимо учитывать разработчикам при создании приложений, способных воспользоваться новыми возможностями камер SR300 или работать в режиме обратной совместимости, используя только возможности камер F200. Более полное описание переделки приложений для камеры F200 в приложения для камеры SR300 см. в разделе Работа с камерой SR300на веб-сайте документации SDK.

Режим совместимости с камерой Intel RealSense F200

Чтобы приложения, предназначенные для камеры F200, могли работать в системах с камерой SR300, в DCM для камеры SR300 (версии Gold или более поздней) реализован режим совместимости с F200. Этот режим автоматически включается при получении запроса от приложения, скомпилированного в SDK версии до R5, и позволяет драйверу DCM имитировать работу камеры F200. Если в этом режиме приложение вызовет QueryDeviceInfo, то в качестве имени и модели устройства будет возвращено значение F200. При этом запросы, поступающие от приложений, скомпилированных в SDK версии R5 2015 или более поздней, будут обрабатываться без изменений: режим совместимости отключается, приложение сможет использовать все возможности камеры SR300.

Следует отметить, что одновременно можно использовать только один режим: обычный режим или режим совместимости. Это означает, что при последовательном запуске двух приложений необходимость включения режима совместимости с F200 будет определяться по первому приложению. Если первое приложение было скомпилировано в SDK версии до R5, то режим совместимости с F200 будет автоматически включен вне зависимости от версии SDK второго приложения. Если же первое приложение было скомпилировано в SDK версии R5 или более поздней, то режим совместимости с F200 будет автоматически отключен, все последующие приложения будут определять модель камеры как SR300. Поэтому, если первое приложение создано в SDK версии R5 или более поздней (режим совместимости с F200 отключается), а второе приложение создано в SDK версии до R5, то второе приложение не найдет в системе доступную камеру Intel RealSense и не будет работать. Причина в том, что приложению, созданному в SDK версии до R5, требуется камера F200, но DCM работает в режиме SR300 из-за первого приложения. В настоящее время нет способа переопределить состояние совместимости с F200 для последующих приложений. Невозможно и включить в DCM поддержку режимов F200 и SR300 одновременно.

В таблице 1 приводится сводка по состоянию режима совместимости при запуске нескольких приложений Intel RealSense в одной и той же системе с камерой SR300 (приложение 1 запускается до приложения 2).

Таблица 1. Состояние режима совместимости с камерой IntelRealSenseF200 при нескольких запущенных приложениях

Приложение 1

Приложение 2

Состояние режима совместимости с камерой F200

Комментарии

Компиляция в версии до R5

Компиляция в версии до R5

ВКЛЮЧЕН

Приложение 1 запускается первым, DCM определяет, что приложение скомпилировано в версии до R5, и включает режим совместимости с F200.

Компиляция в версии до R5

Компиляция в версии R5 или более поздней

ВКЛЮЧЕН

Приложение 1 запускается первым, DCM определяет, что приложение скомпилировано в версии до R5, и включает режим совместимости с F200.

Компиляция в версии R5 или более поздней

Компиляция в версии до R5

ОТКЛЮЧЕН

Приложение 1 запускается первым, DCM определяет, что приложение предназначено для камеры SR300 и отключает режим совместимости с F200. Приложение 2 не найдет допустимую камеру и не запустится.

Компиляция в версии R5 или более поздней

Компиляция в версии R5 или более поздней

ОТКЛЮЧЕН

Приложение 1 запускается первым, DCM определяет, что приложение скомпилировано для версии R5 или более поздней, и отключает режим совместимости с F200. Оба приложения будут использовать запросы, относящиеся к SR300.

Разработка приложений, независимых от устройств

В свете выпуска камеры Intel RealSense SR300 многие компоненты Intel RealSense SDK 2015 R5 были изменены, чтобы сохранить совместимость и при этом в полной мере задействовать возможности SR300. В большинстве случаев разработчикам рекомендуется создавать универсальные приложения, работающие с любыми камерами переднего обзора: это позволит добиться наиболее широкого охвата различных платформ. Модули SDK и интерфейсы потоков позволяют учитывать все различия платформ, если это необходимо. Если же приложение использует уникальные возможности конкретной модели камеры, то есть F200 или SR300, код должен определять камеру и обрабатывать ситуации, когда установленная в системе камера не обладает нужными возможностями. В этом разделе описываются факторы, о которых следует помнить при разработке приложений для камер Intel RealSense переднего обзора, чтобы добиться наибольшей совместимости.

Совместимость интерфейсов SDK

Для поддержания наибольшей совместимости между камерами F200 и SR300 используйте встроенные модули алгоритмов (face, 3DS, BGS и т. д.) и интерфейс SenseManager, чтобы прочитывать необработанные потоки, не указывая разрешение потоков и формат пикселей. При таком подходе SDK будет автоматически обеспечивать необходимые преобразования, а количество требуемых переделок кода будет наименьшим. Помните, что уровень зрелости алгоритмов, созданных для SR300, может быть ниже, чем у алгоритмов для камеры F200, учитывая, что поддержка SR300 реализована только в версии SDK 2015 R5. Внимательно прочтите заметки к выпуску SDK, чтобы оценить уровень развития различных алгоритмов, необходимых для вашего приложения.

Ниже приводятся общие рекомендации по указанию потоков и чтению данных изображений.

  • Избегайте указания потоков с использованием определенной конфигурации (разрешения, кадровой скорости):

    sm->EnableStream(PXCCapture::STREAM_TYPE_COLOR, 640, 480, 60);

    Вместо этого пусть SenseManager выбирает подходящую конфигурацию в зависимости от доступной модели камеры:

    sm->EnableStream(PXCCapture::STREAM_TYPE_COLOR);

  • Используйте функции Image (например, AcquireAccessи ExportData) для принудительного преобразования формата пикселей.

    PXCImage::ImageData data;

    image->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_RGB32,&data);

  • Если требуется собственный формат пикселей, обязательно обрабатывайте все такие случаи, чтобы код работал независимо от модели камеры (см. пример SoftwareBitmapToWriteableBitmapв приложении к этому документу).

  • При доступе к свойствам камеры используйте свойства, независимые от устройства. Они перечислены в разделе Device Neutral Device Properties.

Несовместимость Intel RealSense SDK

На момент выпуска Intel RealSense SDK версии R5 2015 остается еще несколько API, обладающих несовместимостью между камерами F200 и SR300. Выполните действия по адаптации, приведенные в таблице 2, чтобы написать код, работающий с любыми камерами.

Таблица 2.Действия по устранению несовместимости с камерами переднего обзора

 

Функция

Проблема совместимости

Рекомендации

Имя камеры

Понятное имя и идентификатор модели устройства различаются у F200 и SR300.

- Не используйте строку с понятным именем модели в качестве уникального идентификатора. Используйте ее только для отображения имени устройства в текстовой строке для пользователя.

- Используйте имя модели устройства для выполнения операций с камерой. Используйте значение ориентации (передний обзор или задний обзор) из DeviceInfo, если этого достаточно.

Соотношение «сигнал/шум»

Инфракрасный датчик камеры SR300 обладает гораздо более высоким соотношением «сигнал/шум» и поддерживает 10-битный тип данных (по сравнению с 8-битными данными камеры F200). Поэтому формат пикселей IR_RELATIVEбольше не выдается.

- Используйте функцию AcquireAccessдля принудительного использования формата Y16при доступе к потоку данных ИК-датчика камеры SR300.

Коэффициент увеличения данных глубины

Собственное представление данных в потоке глубины изменено с 1/32 мм у камеры F200 на 1/8 мм у камеры SR300. При доступе к собственным данным глубины с форматом пикселей DEPTH_RAWнеобходимо использовать соответствующий коэффициент увеличения. (Это не влияет на приложения, использующие формат пикселей DEPTH.)

- Для получения правильного коэффициента увеличения используйте QueryDepthUnitили задействуйте принудительное преобразование формата DEPTH_RAWв формат DEPTHс помощью функции AcquireAccess.

Свойства устройства

В некоторых свойствах устройств, описанных в документе Функции-члены F200 и SR300, содержатся различия между этими двумя камерами, о которых следует помнить.

Таблица определения параметров фильтровразличается в зависимости от дальности действия камер.

— SR300 поддерживает только параметр FINESTдля функции SetIVCAMAccurary

- Не используйте свойства, относящиеся к конкретной камере, чтобы не потерять функциональность при смене камеры. Используйте модули алгоритмов Intel RealSense SDK, чтобы пакет SDK автоматически подбирал наилучшие параметры для каждого алгоритма.

Заключение

В этой статье описаны рекомендации по обеспечению совместимости между разными моделями камер Intel RealSense. В SDK версии R5 2015 для Windows предусмотрены встроенные функции поддержки совместимости. В целом, рекомендуется создавать приложения так, чтобы использовать только общие для всех камер возможности. За счет этого ускоряется разработка и обеспечивается универсальность. Если приложение использует уникальные возможности какой-то одной модели камер, позаботьтесь о том, чтобы проверять конфигурацию системы как при установке приложения, так и при его инициализации. Чтобы упросить адаптацию приложений, созданных для камеры F200, к работе с камерой SR300, в драйвере DCM SR300 поддерживается режим совместимости с F200. В этом режиме приложения для предыдущей модели камеры будут безупречно работать с более современной камерой. При этом следует помнить, что прежние приложения (скомпилированные в SDK версии до R5) необходимо обновить. Иначе эти приложения не будут работать в системах с камерами SR300, если одновременно запустить другие приложения, созданные в SDK версии R5 или более поздней. И наконец, важно прочесть всю вспомогательную документацию по SDK, чтобы понять разницу в работе определенных функций SDK с разными моделями камер.

Ресурсы

Документация к Intel RealSense SDK

https://software.intel.com/sites/landingpage/realsense/camera-sdk/v1.1/documentation/html/index.html?doc_devguide_introduction.html

Руководство по переходу на SR300

https://software.intel.com/sites/landingpage/realsense/camera-sdk/v1.1/documentation/html/index.html?doc_mgsr300_working_with_sr300.html

Приложение

SoftwareBitmapToWriteableBitmap Code Sample

// SoftwareBitmap is the UWP data type for images.
public SoftwareBitmapToWriteableBitmap(SoftwareBitmap bitmap,
WriteableBitmap bitmap2)
{
switch (bitmap.BitmapPixelFormat)
{
default:
using (var converted = SoftwareBitmap.Convert(bitmap,
BitmapPixelFormat.Rgba8))
converted.CopyToBuffer(bitmap2.PixelBuffer);
break;
case BitmapPixelFormat.Bgra8:
bitmap.CopyToBuffer(bitmap2.PixelBuffer);
break;
case BitmapPixelFormat.Gray16:
{
// See the UWP StreamViewer sample for all the code.
....
break;
}
}
}

Об авторе

Тион Томас (Tion Thomas) — инженер по программному обеспечению в подразделении Developer Relations корпорации Intel. Он помогает создавать современные пользовательские интерфейсы, отличающиеся оптимальной производительностью и потреблением электроэнергии, для всех типов потребительских приложений, особенно при управлении без помощи контроллеров. Тион с большим интересом создает удобные и мощные решения с использованием современных технологий. Кроме того, он изучает игры и технологии виртуальной реальности.

Использование камеры Intel® RealSense™ с TouchDesigner*. Часть 2

$
0
0

Загрузить демонстрационные файлы ZIP 14KB

Камера Intel® RealSense™ — очень полезный инструмент для создания проектов виртуальной реальности и дополненной реальности. Во второй части этой статьи вы узнаете, как использовать узлы камеры Intel RealSense в TouchDesigner для настройки рендеринга или проекции в реальном времени для многоэкранных систем, одиночных экранов, 180-градусных (полнокупольных) и 360-градусных систем виртуальной реальности. Кроме того, информацию с камеры Intel RealSense™ можно передавать в Oculus Rift* с помощью узла Oculus Rift TOP в TouchDesigner.

Вторая часть будет посвящена узлу RealSense CHOP в TouchDesigner.

Доступ к самым важным функциям отслеживания камер RealSense F200и R200, таким как отслеживание глаз, пальцев и лица, осуществляется в узле RealSense CHOP в TouchDesigner. Эти функции отслеживания особенно интересно использовать в анимации реального времени или при отслеживании анимации в соответствии с движениями тела и жестами людей. Мне это представляется наиболее полезным для выступлений танцоров или музыкантов, где требуется высокий уровень интерактивности между живым видео, анимацией, графикой, звуком и выступлением.

Для получения файлов TouchDesigner* (.toe), связанных с этой статьей, нажмите кнопку в верхней части этой статьи. Также доступна бесплатная копия TouchDesigner для некоммерческого использования. Она обладает полной функциональностью, но максимальное разрешение не может превышать 1280 x 1280.

Вновь следует отметить, что благодаря поддержке камеры Intel RealSense программа TouchDesigner* становится еще более универсальным и мощным средством.

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

Примечание.При использовании камеры Intel RealSense для достижения оптимальных результатов следует учитывать дальность. На этой веб-странице Intel указана дальность всех моделей камер и даны рекомендации по использованию камер..

Исторические сведения

Все данные, предоставляемые камерами Intel RealSense, очень полезны для создания виртуальной реальности и дополненной реальности. Некоторые попытки делать то, что сейчас делается с помощью камеры Intel RealSense, были еще в 80-х годах. Технология отслеживания расположения руки была разработана в 80-х годахв виде перчатки, передающей данные, авторы этого изобретения — Джейсон Ланьер (Jason Lanier) и Томас Циммерман (Thomas G. Zimmerman). В 1987 году компания Nintendo выпустила первый манипулятор для управления играми в виде перчатки, подключаемой по проводам к игровой консоли Nintendo.

Устройства, развитие которых привело к созданию камер Intel RealSense, изначально предназначались для анимации на выступлениях: технологии захвата движения применялись, чтобы преобразовать выступление человека в математические данные, то есть в цифровую информацию. Захват движения применялся еще с 70-х годов в исследовательских проектах в различных университетах, а также в войсках для обучения. Одним из первых анимационных фильмов, созданных с помощью захвата движения, был анимационный ролик Sexy Robot https://www.youtube.com/watch?v=eedXpclrKCc, созданный в 1985 году Робертом Абелем (Robert Abel) и его коллегами. В ролике Sexy Robot использовалось несколько технологий для получения информации, с помощью которой была создана и анимирована цифровая модель робота. Сначала была создана модель робота. Ее измерили со всех сторон, описывающую ее информацию перевели в цифровой вид: аналогичных результатов камера RealSense добивается при съемке объектов. Для вычисления движения на актере нарисовали точки, движение которых соотнесли с движением цифрового «скелета»: была создана векторная анимация, при помощи которой двигалась цифровая модель. Камера RealSense обладает возможностью инфракрасной съемки и инфракрасным лазерным проектором, что позволяет получать данные для цифровых моделей и отслеживания движений. Возможности отслеживания камеры Intel RealSense достаточно совершенны: можно отслеживать даже движения глаз.

Камеры Intel RealSense

В настоящее время существует две модели камер Intel RealSense. Они выполняют схожие функции, но кое в чем различаются: это камера Intel RealSense F200, для которой предназначены упражнения в этой статье, и камера Intel RealSense R200.

Камера Intel RealSense R200 благодаря своему компактному размеру обладает важными преимуществами. Она предназначена для установки на штатив или на заднюю часть планшета. Таким образом, объектив камеры направлен не на пользователя, а на окружающий мир, а благодаря усовершенствованным возможностям съемки поле зрение камеры охватывает более широкую область. Кроме того, у этой камеры улучшены и возможности измерения глубины. Эту камеру очень интересно использовать для проектов дополненной реальности, поскольку в ней поддерживается функция восприятия сцены, позволяющая добавлять виртуальные объекты в отснятую сцену реального мира. Также можно накладывать виртуальную информацию на снимаемое изображение в прямом эфире. В отличие от модели F200 камера R200 не поддерживает отслеживания пальцев, рук и лиц. TouchDesigner поддерживает обе модели камер Intel RealSense: и F200, и R200.

Камеры Intel RealSense в TouchDesigner

TouchDesigner идеально сочетается с камерой Intel RealSense: поддерживается прямая связь между мимикой лица пользователя и движениями рук и программным интерфейсом. TouchDesigner может напрямую использовать эти данные отслеживания и положения. TouchDesigner также может использовать данные глубины, цветного изображения и инфракрасного изображения, передаваемые камерой Intel RealSense. Камеры Intel RealSense очень легкие и компактные, особенно модель R200, которую можно легко разместить рядом с исполнителями незаметно для аудитории.

Адам Берг (Adam Berg), исследователь в компании Leviathan, работающий над проектом по использованию камеры Intel RealSense вместе с TouchDesigner для создания интерактивных инсталляций, заявляет: «Благодаря компактному размеру и простой конструкции камера отлично подходит для интерактивных решений. Камера не бросается в глаза, а требования к инфраструктуре упрощаются, поскольку камере не требуется внешний источник питания. Кроме того, нам понравились низкие задержки при создании изображения глубины. TouchDesigner — великолепная платформа для работы (от создания первоначального прототипа до разработки финальной версии). Она обладает встроенной поддержкой пяти камер, возможностью высокопроизводительного воспроизведения мультимедиа и удобными возможностями работы с шейдерами. Помимо этого, безусловно, следует отметить и великолепную поддержку».

Использование камеры Intel® RealSense™ в TouchDesigner

Во второй части мы рассматриваем узел CHOP в TouchDesigner для камеры Intel RealSense.

Узел RealSenseCHOP

Узел RealSense CHOP управляет трехмерным отслеживанием и данными о положении. Узел CHOP содержит информацию двух типов. (1) Положение в реальном мире (измеряется в метрах, но можно довести точность до единиц миллиметров) используется для преобразования по осям x, y и z. Повороты вокруг осей x, y и z в RealSense CHOP выводятся в виде углов Эйлера по осям x, y и z в градусах. (2) Узел RealSense CHOP также получает пиксели входного изображения и преобразует их в нормализованные UV-координаты. Это полезно для отслеживания изображений.

Узел RealSense CHOP обладает двумя настраиваемыми параметрами: отслеживание пальцев/лица и отслеживание маркера.

  • В разделе Finger/Face Tracking можно выбрать отслеживаемые элементы. Можно ограничить список отслеживаемых элементов только одним аспектом, а затем, соединив узел Select CHOP с узлом RealSense CHOP, вновь ограничить список, чтобы отслеживать только движение брови или глаза.
  • Отслеживание маркеров позволяет загрузить изображение и отслеживать этот элемент, где бы он ни находился.

Использование узла RealSense CHOP в TouchDesigner

Демонстрация 1: использование отслеживания

Это простая первая демонстрация узла RealSense CHOP показывает, как его можно соединять с другими узлами и использовать для отслеживания и создания движения. Вновь обратите внимание, что для этих демонстраций достаточно крайне поверхностного знания TouchDesigner.  Если у вас нет опыта работы с TouchDesigner* и вы собираетесь постепенно разбираться в этой статье, то рекомендую сначала просмотреть документацию, доступную здесь:  Изучение TouchDesigner.

  1. Создайте узлы, которые нам потребуются, и расположение их в горизонтальной строке в следующем порядке: узел Geo COMP, узел RealSense CHOP, узел Select CHOP, узел Math CHOP, узел Lag CHOP, узел Out CHOP и узел Trail CHOP.
  2. Соедините узел RealSense CHOP с узлом Select CHOP, узел Select CHOP — с узлом Math CHOP, узел Math CHOP — с узлом Lag CHOP, узел Lag CHOP — с узлом Out CHOP Node, а узел Out CHOP — с узлом Trail CHOP.
  3. Откройте страницу параметров Setupузла RealSense CHOP и убедитесь, что для параметра Hands World Position задано значение On. Выводится расположение отслеживаемых суставов руки в пространстве. Значения указываются в метрах по отношению к камере.
  4. На странице параметров Selectузла Select CHOP установите для параметра ChannelNamesзначение hand_r/wrist:tx, выбрав его среди доступных значений в раскрывающемся списке справа от параметра.
  5. В параметре RenameFromвведите hand_r/wrist:tx, затем в параметре RenameToparameterвведите x.
    Рисунок 1.Отбор каналов из узла RealSenseCHOPпроисходит в узле SelectCHOP
  6. В параметре Range/To Rangeузла Math CHOP введите 0, 100. Для уменьшенного диапазона движений введите число меньше 100.
  7. Выберите узел Geometry COMP и убедитесь, что он находится на странице параметров Xform. Нажмите кнопку «+» в правом нижнем углу узла Out CHOP, чтобы включить просмотр. Перетащите канал X на параметр Translate X узла Geometry COMP и выберите ExportCHOPв раскрывающемся меню.
    Рисунок 2.Здесь вы добавляете анимацию, полученную из RealSenseCHOP

    Для рендеринга геометрии понадобится узел Camera COMP, узел Material (MAT) (я использовала Wireframe MAT), узел Light COMP и узел Render TOP. Добавьте эти узлы для рендеринга этого проекта.

  8. В узле Camera COMP на странице параметров Xformустановите для параметра Translate Z значение 10. Это позволит лучше видеть движение созданной геометрии, поскольку камера сдвигается назад по оси Z.
  9. Проведите рукой перед камерой и посмотрите, как геометрическая фигура будет двигаться в узле Render TOP.
Рисунок 3.Как узлы соединены друг с другом. Благодаря узлу TrailCHOPв конце можно просмотреть анимацию в графической форме

Рисунок 4.Значение преобразования xузла GeometryCOMPбыло экспортировано из канала xв узел OutCHOP, который был передан далее по цепочке от узла SelectCHOP

Демонстрация 2. Отслеживание маркера RealSense CHOP

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

  1. Добавьте узел RealSense CHOP в сцену.
  2. На странице параметров Setupузла RealSense CHOP выберите для параметра Mode значение MarkerTracking.
  3. Создайте ресурс Movie File в TOP.
  4. На странице параметров Playузла TOP в разделе Fileвыберите и загрузите цифровое изображение, для которого у вас также есть печатная версия.
  5. Перетащите Movie File в TOP на страницу параметров Setupузла RealSense CHOP и в ячейку MarkerImageTOPв нижней части страницы.
  6. Создайте узлы Geometry COMP, Camera COMP, Light COMP и Render TOP.
  7. Как было сделано ранее на шаге 7 в демонстрации 1, экспортируйте канал tx из RealSense CHOP и перетащите его в параметр TranslateXузла Geometry COMP.
  8. Создайте узел Reorder TOP и соедините его с узлом Render TOP. На странице параметров Reorder узла OutputAlphaвыберите Oneв раскрывающемся списке.
  9. Поместите напечатанное изображение цифрового файла перед камерой Intel RealSense и подвигайте его. Камера должна отслеживать движение и выдавать его узлу Render TOP. Числа в RealSense CHOP также изменятся.
Рисунок 5. Это полный макет демонстрации с отслеживанием маркера

 

Рисунок 6. На странице параметров узла GeoCOMPканал txиз узла RealSenseCHOPперетащен на параметр Translatex

Отслеживание глаза в TouchDesigner с помощью узла RealSense CHOP

На палитре программ TouchDesigner в разделе RealSenseесть шаблон eyeTracking, который можно использовать для отслеживания движения глаз пользователя. Этот шаблон использует отслеживание пальцев/лицаузла RealSense CHOP; для узла RealSense TOP должен быть задан Color. В шаблоне зеленые прямоугольники WireFrame двигаются в соответствии с движением глаз человека и накладываются на цветное изображение человека в RealSense TOP. Вместо открытых зеленых прямоугольников можно использовать любые другие геометрические фигуры или частицы. Это очень удобный шаблон. Вот изображение с шаблоном.

Рисунок 7.Обратите внимание, что глаза отслеживаются даже через очки

Демонстрация 3, часть 1. Простой способ настройки полнокупольного рендеринга или виртуальной реальности

В этой демонстрации мы берем файл и показываем, как представить его в полнокупольном рендеринге и в 360-градусной виртуальной реальности. Я уже подготовила такой файл для загрузки. Это файл chopRealSense_FullDome_VR_render.toe.

Краткое описание процесса создания этого файла

В этом файле я хотела разместить геометрические фигуры (сферу, тор, цилиндры и прямоугольники) в сцене. Поэтому я создала несколько узлов SOP для этих различных геометрических фигур. Каждый узел SOP был присоединен к узлу Transform SOP для перемещения (преобразования) геометрических фигур в разных местах сцены. Все узлы SOP соединены с одним узлом Merge SOP. Узел Merge SOP подан узлу Geometry COMP.

Рисунок 8.Это первый шаг в разметке геометрических фигур, размещенных в сцене, в загружаемом файле

Затем я создала узел Grid SOP и узел SOP–DAT. Узел SOP–DAT был использован для получения экземпляра Geometry COMP, чтобы можно было добавить в сцену больше геометрических фигур. Я также создала узел Constant MAT, выбрала зеленый цвет и включила параметр WireFrameна странице Common.

Рисунок 9.Узел SOPDATбыл создан с помощью узла GridSOP

Затем я создала узел RealSense CHOP и соединила его с узлом Select CHOP, в котором я выбрала канал hand_r/wrist:txдля отслеживания и переименовала его в x. Я соединила Select CHOP с узлом Math CHOP, чтобы можно было изменить дальность, и соединила Math CHOP с узлом Null CHOP. Рекомендуется всегда завершать цепочку узлом Null или Out, чтобы было удобнее вставлять новые фильтры в цепочку. Затем я экспортировала x Channel из узла Null CHOP в параметр ScaleXузла Geometry COMP. Это обеспечивает управление всеми перемещениями геометрических фигур по оси x в сцене, когда я провожу правой рукой перед камерой Intel RealSense.

Рисунок 10.Данные отслеживания из узла RealSenseCHOPиспользуются для создания анимации в реальном времени и движения геометрических фигур вдоль оси x

Для создания полнокупольного 180-градусного рендеринга из этого файла

  1. Создайте узлы Render TOP, Camera COMP и Light COMP.
  2. На странице параметров Renderузла Render TOP выберите CubeMapв раскрывающемся меню Render Mode.
  3. На странице параметров Common узла Render TOP задайте для параметра Resolution разрешение с соотношением сторон 1:1, например 4096 на 4096, для получения разрешения 4K.
  4. Создайте узел Projection TOP и соедините с ним узел Render TOP.
  5. На странице параметров Projection узла Projection TOP выберите Fish-Eyeв раскрывающемся меню Output.
  6. (Это необязательно, в этом случае у файла будет черный фон.) Создайте узел Reorder TOP и на странице параметров Reorder в правом раскрывающемся меню Output Alpha выберите One.
  7. Теперь все готово либо к непосредственному выполнению анимации, либо к экспорту файла фильма. Инструкции см. в первой частиэтой статьи. Вы создаете круговую купольную анимацию типа «Рыбий глаз». Это будет окружность с квадратом.

Чтобы использовать альтернативный метод, вернитесь на шаг 2 и вместо выбора Cube Map в раскрывающемся меню Render Mode выберите Fish-Eye(180). Теперь перейдите к шагу 3, а также при желании — к шагу 6. Теперь анимация готова к запуску или к экспорту.

Для создания 360-градусной виртуальной реальности из этого файла

  1. Создайте узлы Render TOP, Camera COMP и Light COMP.
  2. На странице параметров Renderузла Render TOP выберите CubeMapв раскрывающемся меню Render Mode.
  3. На странице параметров Commonузла Render TOP задайте для параметра Resolutionразрешение с соотношением сторон 1:1, например 4096 на 4096, для получения разрешения 4K.
  4. Создайте узел Projection TOP и соедините с ним узел Render TOP.
  5. На странице параметров Projectionузла Projection TOP выберите Equirectangularв раскрывающемся меню Output. При этом будет автоматически установлено соотношение сторон 2:1.
  6. (Это необязательно, в этом случае у файла будет черный фон.) Создайте узел Reorder TOP, затем на странице параметров Reorder в правом раскрывающемся меню Output Alpha выберите One.
  7. Теперь все готово либо к непосредственному выполнению анимации, либо к экспорту файла фильма. Инструкции см. в первой частиэтой статьи. При экспорте фильма вы создаете прямоугольную анимацию с соотношением сторон 2:1 для просмотра в очках виртуальной реальности.
Рисунок 11.В файл добавлены длинные оранжевые узлы TubeSOP. Вы можете добавить собственную геометрию в этот файл

Вывод на Oculus Rift* из TouchDesigner при использовании камеры Intel RealSense

В TouchDesigner создано несколько шаблонов для загрузки. В них показано, как настроить Oculus Rift в TouchDesigner. Один из этих шаблонов — OculusRiftSimple.toe — можно загрузить с помощью кнопки в правом верхнем углу этой статьи.   Для просмотра в Oculus Rift, естественно, компьютер должен быть подключен к Oculus Rift. Без Oculus Rift можно создать файл, просмотреть изображения в узлах LeftEye Render TOP и RightEye Render TOP и отобразить их в фоне сцены. Я добавила поддержку Oculus Rift в файл, использованный в демонстрации 3. Таким образом, камера Intel RealSense анимирует изображение, которое я вижу в Oculus Rift.

Рисунок 12.Здесь в фоне отображается левый глаз и правый глаз. Большая часть анимации этой сцены управляется путем отслеживания из узла CHOPкамеры Intel®RealSense™. Файл, использованный для получения этого изображения, можно загрузить, нажав на кнопку в правом верхнем углу этой статьи, chopRealSense_FullDome_VRRender_FinalArticle2_OculusRiftSetUp.toe

Об авторе

Одри Филипс (Audri Phillips) — специалист по визуализации и трехмерной анимации из Лос-Анджелеса. Она располагает обширным профессиональным опытом, включая 25 лет стажа работы в отрасли визуальных эффектов и развлечений в таких анимационных студиях, как Sony*, Rhythm and Hues*, Digital Domain*, Disney* и Dreamworks*. Сначала она занималась рисованием, но быстро перешла к созданию анимационных изображений. Она всегда интересовалась новыми инструментами и применяла компьютерные изображения и анимацию в экспериментальных фильмах, включая демонстрации для погружения в виртуальную среду. Сейчас она работает над системами виртуальной реальности. Корпорация Samsung* недавно использовала ее работы в новом канале виртуальной реальности Gear Indie Milk.

Вот ее последние работы и анимации: мультимедиаанимации для фестиваля Implosion a Dance Festival в 2015 году в театральном центре Лос-Анджелеса, 3 полусферические демонстрации в куполе Vortex Immersion, над созданием одной из которых также работал известный композитор и музыкант Стив Роуч (Steve Roach). 7 ноября 2015 г. вышла четвертая полнокупольная демонстрация под названием Relentless Universe. Помимо этого, она создала анимационные материалы для телесериала «Константин». Они были показаны на конференции «Комик-Кон» 2014 года. Некоторые ее полнокупольные демонстрации, в том числе Migrations и Relentless Beauty, получили оценку жюри на международном фестивале Santa Fe International New Media Festival и на фестивале Jena FullDome Festival в Германии. Она выставляет свои работы в галерее Young Projects в Лос-Анджелесе.

Она публикует материалы в Интернете и ведет блог на портале корпорации Intel®. Одри — адъюнкт-профессор в Университете Вудбери, член-основатель и лидер организации Los Angeles Abstract Film Group, основатель студии Hybrid Reality Studio (занимающейся созданием материалов для виртуальной реальности), член правления Iota Center, а также участник выставок LA Art Lab. В 2011 году Одри стала постоянным художником Vortex Immersion Media и c3: CreateLAB. Ее работы можно посмотреть на сайтах Vimeo, creativeVJи Vrideo.

Intel RealSense Technology + Unity 5: полезные советы

$
0
0

Джекоб Пеннок из компании Livid Interactive предлагает полезные советы по работе с технологиями Intel® RealSense™и Unity* 5в этом наборе из семи видеороликов. Описание каждого видеоролика см. ниже.

Примечание. В некоторых видеороликах Джекоб ссылается на видео, описывающее модуль распознавания эмоций в составе SDK. Это видео уже недоступно, поскольку модуль распознавания эмоций упразднен и отсутствует в Intel® RealSense™ SDK, начиная с версии R5.

Настройка набора инструментов Intel® RealSense™ SDK в Unity* 5

Джекоб описывает, как импортировать набор инструментов Intel RealSense SDKв Unity 5 и проверить правильность установки, используя образец кода с перетаскиванием из Intel RealSense SDK. Примечание. Если установлена версия Intel RealSense SDK R4 или более поздняя, можно пропустить инструкции, касающиеся замены 32-разрядных двоичных файлов на 64-разрядные, поскольку начиная с версии R4 набор инструментов поставляется с 64-разрядным двоичными файлами для Unity 5.

 

Оптимизация для набора инструментов Intel® RealSense™ SDK — часть 1

В этом наборе из двух видео, посвященных оптимизации, Джекоб рассказывает об областях набора инструментов Intel RealSense, где производительность недостаточна для рабочего приложения. В первой части описывается значительное повышение кадровой скорости за счет использования SenseToolkitMgr.Update(). Также показано, как устранить проблему зеркалирования в одном из образцов набора инструментов.

 

Оптимизация для набора инструментов Intel® RealSense™ SDK — часть 2

Во второй части Джекоб показывает устранение проблемы производительности в методе DrawImages.Update(). В этом видео он создает новый, более эффективно работающий с памятью метод вместо метода Intel, потребляющего слишком много памяти.

 

Использование Intel® RealSense™ SDK непосредственно в Unity* 5 (без набора инструментов)

В этом видео говорится о доступе к Intel RealSense SDK непосредственно из кода C# Unity 5. Набор инструментов Intel RealSense может быть полезен для быстрого тестирования, но разработчики могут добиваться более эффективной работы приложений, реализуя собственные способы взаимодействия с Intel RealSense SDK. Джекоб перечисляет основные действия, необходимые для этого.

 

Intel® RealSense™ SDK + Unity* 5 — полезный совет: следите за кадровой скоростью

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

 

Альтернативные режимы отслеживания рук в Intel® RealSense™ SDK и Unity* 5

В составе пакета Intel RealSense SDK есть несколько примеров отслеживания движения рук путем распознавания суставов. В этом виде Джекоб показывает еще одну методику отслеживания рук в режиме Extremities и итоговое сегментированное изображение. Этот метод работает гораздо быстрее, чем отслеживание с распознаванием суставов.

 

Intel® RealSense™ SDK + Unity* 5 — полезный совет: отображение сегментированных изображений

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

 

 

Intel® RealSense™ SDK + Unity* 5 — полезный совет: используйте отдельный поток для обновления

Джекоб описывает свой новый ноутбук Asus со встроенной камерой Intel® RealSense™и показывает, как повысить производительность приложения, используя отдельный поток для взаимодействия с Intel RealSense SDK.

 

Об авторе

Джекоб Пеннок (Jacob Pennock) — специалист по технологии Intel® RealSense™. Он занимает должности старшего творческого разработчика в компании Helios Interactive Technologies и главного игрового дизайнера/ведущего разработчика в компании Livid Interactive.

Viewing all 156 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>