Опубликован: 23.10.2013 | Уровень: для всех | Доступ: платный | ВУЗ: Северный (Арктический) федеральный университет им. М.В. Ломоносова
Лекция 2:

Основы, функциональность и особенности Intel Perceptual Computing SDK

Модули ввода/вывода и модули алгоритмов

Модули ввода/вывода служат в качестве источника получения информации от устройств ввода и передачи обработанной информации на устройства вывода.

Сессии SDK может содержать несколько и модулей ввода/вывода и модулей алгоритмов. На момент создания сессии, SDK загружает все предустановленные модули в сессию. Приложение также может явно загрузить модули, вызывая функцию LoadImplFromFile, как показано на следующем примере:

session->LoadImplFromFile(L"my_module.dll");
2.3. Загрузка модуля

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

PXCFaceAnalysis *fd=0;
session->CreateImpl<PXCFaceAnalysis>(&fd);
2.4. Создание экземпляра модуля, используя идентификатор интерфейса

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

1. Если приложение уже знает исполняемый идентификатор модуля, то оно может вызвать функцию CreateImpl с данным идентификатором, как показано в Примере 2.5. Идентификатор интерфейса и исполняемый идентификатор однозначно определяют модуль. Приложение может найти исполняемый идентификатор, вызвав функцию QueryImpl, которая перечисляет все доступные модули.

PXCFaceAnalysis *fd=0;
session->CreateImpl<PXCFaceAnalysis>(PXC_UID('F','I','L','C'),&fd);
2.5. Создание экземпляра модуля с уникальным исполняемым идентификатором

2. Кроме того, приложение может создать структуру ImplDesc, которая определяет различные аспекты модуля. Функция CreateImpl найдет совпадения и создаст экземпляр модуля, как показано на Примере 2.6.

PXCSession::ImplDesc desc;
memset(&desc,0,sizeof(desc));
desc.group=PXCSession::IMPL_GROUP_OBJECT_RECOGNITION;
desc.subgroup=PXCSession::IMPL_SUBGROUP_FACE_ANALYSIS;
desc.vendor=0x8086;        // от Intel
// Создаем образец алгоритма
PXCFaceAnalysis *fd=0;
Session->CreateImpl<PXCFaceAnalysis>(&desc,&fd);
2.6. Создание экземпляра модуля с использованием дескрипторов

Конфигурирование модулей

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

PXCFaceAnalysis::ProfileInfo info;
// первая поддерживаемая конфигурация
sts=face->QueryProfile(i,&info);
// устанавливаем рабочую конфигурацию
face->SetProfile(&info);
...
// получаем текущую рабочую конфигурацию
face->QueryProfile(&info);
2.7. Конфигурирование модуля

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

Создание конвейера

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

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

// получаем данные из модуля распознавания лиц
PXCFaceAnalysis::ProfileInfo info;
face->QueryProfile(0, &info);
// находим соответствующее устройство ввода
UtilCapture capture(session);
capture.LocateStream(&info.inputs);
// задаем конфигурацию модуля
face->SetProfile(&info);
2.8. UtilCapture инициализирует захват

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

Функция LocateStreams может объединить несколько входных потоков, как показано в Примере 2.9, где функция находит устройства для распознавания лица и жестов.

PXCFaceAnalysis::ProfileInfo pinfo1;
face->QueryProfile(0, &pinfo1);
PXCGesture::ProfileInfo pinfo2;
gesture->QueryProfile(0, &pinfo2);
UtilCapture capture(session);
std::vector<PXCCapture::VideoStream::DataDesc*> minputs;
minputs.push_back(&pinfo1.inputs);
minputs.push_back(&pinfo2.inputs);
capture.LocateStreams(minputs);
face->SetProfile(&pinfo1);
gesture->SetProfile(&pinfo2);
2.9. UtilCapture объединяет потоки с нескольких устройств

Передача данных и асинхронное выполнение

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

Обнаружения позиции лица

Рис. 2.3. Обнаружения позиции лица

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

PXCSmartArray<PXCImage> images;
PXCSmartSPArray sps(2);
stream->ReadStreamAsync(&images,&sps[0]);
face->ProcessImageAsync(images,&sps[1]);
sps.Synchronize();
2.10. Асинхронное выполнение псевдо-кода

SDK помечает асинхронные функций суффиксом "Async" в имени функции. Асинхронные функции не блокируют выполнение, а возвращают точку синхронизации (или SP) для последующей синхронизации результата выполнения. Приложение использует функцию Synchronize для явного ожидания завершения выполнения. Каждая асинхронная операция возвращает SP. Приложению не требуется синхронизация промежуточных SP (например, SP1). Вместо этого, приложение синхронизирует только окончание работы конвейера.

Асинхронное выполнение конвейера распознавания лиц с SP

Рис. 2.4. Асинхронное выполнение конвейера распознавания лиц с SP

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

Асинхронный конвейер распознавания лиц с SP и данными

Рис. 2.5. Асинхронный конвейер распознавания лиц с SP и данными

SDK поддерживает асинхронное выполнение в виде графа. Есть два способа построения графа выполнения:

  • Приложение передает одно и то же выходное значение для последующего выполнения.
  • Некоторые функции SDK создают несколько выходных значений. Приложение передает каждое выходное значение для последующего выполнения.

На рис. 2.6 Функция 1 генерирует два выходных значения. Приложение передает первое выходное значение на Функцию 2 и Функцию 4, а второе выходное значение на Функцию 3 и Функцию 5. Приложение также передает выходное значение Функции 2 на Функцию 5. Соответственно Функция 5 требуется несколько входов.

Граф асинхронного выполнения

Рис. 2.6. Граф асинхронного выполнения
Гульзия Калымова
Гульзия Калымова
Александр Радченко
Александр Радченко
Юрий Симонов
Юрий Симонов
Россия, Москва, Московский Государственный Университет им. М.В. Ломоносова, 2011
Вадим Сизоненко
Вадим Сизоненко
Россия, Братский р-н