Pull to refresh

Kinect for Windows SDK. Часть 2. Потоки данных

Reading time4 min
Views15K

Продолжим знакомство с возможностями Kinect. В прошлый раз я обозначил несколько особенностей Kinect, каждая из которых, несомненно, заслуживает отдельной статьи, и совсем не упомянул тружеников, силами которых обеспечивается и распознавание речи и трекинг фигуры человека. Задумывались ли вы, в каком виде сенсор передает данные? Что представляет собой этот поток или потоки данных? И если однажды безлунной ночью, в темном переулке к вам подкрадётся маньяк и спросит: «Сколько потоков данных у Kinect на выходе?», не задумываясь отвечайте: «Три!». Видеопоток (Color Stream), Aудиопоток (Audio Stream) и данные дальномера (Depth Stream). SDK строится на этих потоках. Начнем же и мы с них.
image

Задавшись целью использовать возможности Kinect, первое, что необходимо сделать – это выбрать нужный сенсор и инициализировать требуемые потоки данных. Помните, что одновременно к компьютеру может быть подключено до 4 сенсоров? С помощью класса KinectSensor не составляет большого труда перебрать их все. В документации вы найдете такой способ выбрать и включить первый подключенный сенсор:

KinectSensor kinect = KinectSensor.KinectSensors.Where(s => s.Status == KinectStatus.Connected).FirstOrDefault();
kinect.Start();


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

Видеопоток от сенсора

Внимательно почитав MSDN можно узнать вроде бы полезную информацию об этом потоке. Например, разработчик волен установить уровень качества и формат картинки при инициализации видеопотока. От уровня качества напрямую зависит количество и скорость передаваемых от сенсора данных, ограниченной, в свою очередь, пропускной способностью USB 2.0. Так для картинки разрешением 1280x960 количество кадров в секунду составит 12, а для картинки разрешением 640x480 – 30. Формат изображения определяется цветовой моделью и может быть либо RGB, либо YUV.

Комбинации уровня качества и формата картинки представлены перечислением ColorImageFormat. Три из его значений определяют 32-битное кодирование каждого пиксела изображения: RgbResolution1280x960Fps12, RgbResolution640x480Fps30 и YuvResolution640x480Fps15, а четвертый – 16-битное RawYuvResolution640x480Fps15. Большое недоумение вызывает YuvResolution640x480Fps15. В MSDN четко сказано (тут и тут), что это YUV конвертированный в RGB32… но, тем не менее, продолжающий оставаться YUV…

Чтобы начать принимать видеопоток от сенсора, этот самый поток необходимо инициализировать:

// включаем видеопоток с цветовой моделью RGB и разрешением 640x480(30fps)
kinect.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
// теперь можно подписаться на событие сенсора, чтобы получать готовый кадр и работать с ним
kinect.ColorFrameReady +=SensorColorFrameReady;


Чуть более детальный пример можно найти в MSDN.

Аудиопоток от сенсора

Вы уже знаете, что в Kinect встроен набор из четырёх микрофонов, использующий 24-битный аналого-цифровой преобразователь, а встроенный обработчик звукового сигнала включает подавление эха и уменьшение шума. Каждый микрофон установлен так, чтобы иметь небольшую направленность. Задействовать ли эхо или шумоподавление зависит от разработчика, т.е. эти опции задаются на этапе инициализации аудиопотока. Оптимальное расстояние между говорящим и сенсором – 1-3 метра.

Звуковые возможности Kinect могут быть использованы самыми различными способами, например, для высококачественного захвата аудиосигнала, определение положения аудиосигнала или распознавания речи. О распознавании речи мы поговорим далее, а сейчас мне бы хотелось остановиться на одной особенности Kinect, описание которой в документации я не нашел (плохо искал?). Инициализация аудиопотока занимает чуть меньше четырех секунд. Это необходимо учитывать, и, скажем, после вызова метода сенсора Start(), делать задержку в четыре секунды, прежде чем настраивать параметры аудиопотока — KinectSensor.AudioSource. Пример определения направления звука можно найти в MSDN.

Поток данных дальномера от сенсора

Должно быть самый интересный поток. И интересен он в первую очередь тем, кто хочет знать больше о трекинге человеческой фигуры (skeletal tracking).

Этот поток формируется из кадров, в которых каждый пиксель содержит расстояние (в миллиметрах) от плоскости сенсора до ближайшего объекта в определенных координатах поля зрения камеры. Как и в случае видеопотока, для потока данных дальномера можно устанавливать разрешение одного кадра, которое определяется перечислением DepthImageFormat. При частоте кадров 30 в секунду, разработчик волен выбирать разрешения 80x60 (Resolution80x60Fps30), 320x240 (Resolution320x240Fps30) и 640x480 (Resolution640x480Fps30). И как уже было сказано в предыдущей части, существует два диапазона «рабочих» расстояний: Default Range и Near Range, определяемых перечислением DepthRange.

// устанавливаем диапазон расстояний
kinect.DepthStream.Range = DepthRange.Near;
// и включаем поток дальномера с разрешением 640x480(30fps)
kinect.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);


Но это не все. Дело в том, что значение расстояния в каждом пикселе кодируется только 13-ю битами, а 3 бита призваны идентифицировать человека. Если расстояние до объекта оказывается выходящим за рабочий диапазон (помните диапазоны Default и Near?), в 13 битах вернется ноль или определенная константа. Если при инициализации сенсора включить возможность трекинга человеческой фигуры, в 3 битах будет возвращаться порядковый номер (1 или 2) обнаруженного человека (если в данной точке найден человек, иначе вернется 0):

kinect.SkeletonStream.Enable();


Итак, мы с вами вплотную подошли к первой возможности Kinect, которую будем рассматривать, а именно трекинг человеческой фигуры (skeletal tracking).
Tags:
Hubs:
+13
Comments8

Articles