- PVSM.RU - https://www.pvsm.ru -
Продолжим знакомство с возможностями Kinect. В прошлый раз [1] я обозначил несколько особенностей Kinect, каждая из которых, несомненно, заслуживает отдельной статьи, и совсем не упомянул тружеников, силами которых обеспечивается и распознавание речи и трекинг фигуры человека. Задумывались ли вы, в каком виде сенсор передает данные? Что представляет собой этот поток или потоки данных? И если однажды безлунной ночью, в темном переулке к вам подкрадётся маньяк и спросит: «Сколько потоков данных у Kinect на выходе?», не задумываясь отвечайте: «Три!». Видеопоток (Color Stream), Aудиопоток (Audio Stream) и данные дальномера (Depth Stream). SDK строится на этих потоках. Начнем же и мы с них.
Задавшись целью использовать возможности Kinect, первое, что необходимо сделать – это выбрать нужный сенсор и инициализировать требуемые потоки данных. Помните, что одновременно к компьютеру может быть подключено до 4 сенсоров? С помощью класса KinectSensor [4] не составляет большого труда перебрать их все. В документации вы найдете такой способ выбрать и включить первый подключенный сенсор:
KinectSensor kinect = KinectSensor.KinectSensors.Where(s => s.Status == KinectStatus.Connected).FirstOrDefault();
kinect.Start();
После этого для выбранного сенсора можно настроить и включить необходимые потоки. И именно на трех потоках данных получаемых от сенсора мы немного остановимся.
Внимательно почитав MSDN можно узнать вроде бы полезную информацию об этом потоке. Например, разработчик волен установить уровень качества и формат картинки при инициализации видеопотока. От уровня качества напрямую зависит количество и скорость передаваемых от сенсора данных, ограниченной, в свою очередь, пропускной способностью USB 2.0. Так для картинки разрешением 1280x960 количество кадров в секунду составит 12, а для картинки разрешением 640x480 – 30. Формат изображения определяется цветовой моделью и может быть либо RGB, либо YUV.
Комбинации уровня качества и формата картинки представлены перечислением ColorImageFormat [5]. Три из его значений определяют 32-битное кодирование каждого пиксела изображения: RgbResolution1280x960Fps12, RgbResolution640x480Fps30 и YuvResolution640x480Fps15, а четвертый – 16-битное RawYuvResolution640x480Fps15. Большое недоумение вызывает YuvResolution640x480Fps15. В MSDN четко сказано (тут [6] и тут [7]), что это YUV конвертированный в RGB32… но, тем не менее, продолжающий оставаться YUV…
Чтобы начать принимать видеопоток от сенсора, этот самый поток необходимо инициализировать:
// включаем видеопоток с цветовой моделью RGB и разрешением 640x480(30fps)
kinect.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
// теперь можно подписаться на событие сенсора, чтобы получать готовый кадр и работать с ним
kinect.ColorFrameReady +=SensorColorFrameReady;
Чуть более детальный пример [8] можно найти в MSDN.
Вы уже знаете, что в Kinect встроен набор из четырёх микрофонов, использующий 24-битный аналого-цифровой преобразователь, а встроенный обработчик звукового сигнала включает подавление эха и уменьшение шума. Каждый микрофон установлен так, чтобы иметь небольшую направленность. Задействовать ли эхо или шумоподавление зависит от разработчика, т.е. эти опции задаются на этапе инициализации аудиопотока. Оптимальное расстояние между говорящим и сенсором – 1-3 метра.
Звуковые возможности Kinect могут быть использованы самыми различными способами, например, для высококачественного захвата аудиосигнала, определение положения аудиосигнала или распознавания речи. О распознавании речи мы поговорим далее, а сейчас мне бы хотелось остановиться на одной особенности Kinect, описание которой в документации я не нашел (плохо искал?). Инициализация аудиопотока занимает чуть меньше четырех секунд. Это необходимо учитывать, и, скажем, после вызова метода сенсора Start(), делать задержку в четыре секунды, прежде чем настраивать параметры аудиопотока — KinectSensor.AudioSource [9]. Пример [10] определения направления звука можно найти в MSDN.
Должно быть самый интересный поток. И интересен он в первую очередь тем, кто хочет знать больше о трекинге человеческой фигуры (skeletal tracking).
Этот поток формируется из кадров, в которых каждый пиксель содержит расстояние (в миллиметрах) от плоскости сенсора до ближайшего объекта в определенных координатах поля зрения камеры. Как и в случае видеопотока, для потока данных дальномера можно устанавливать разрешение одного кадра, которое определяется перечислением DepthImageFormat [11]. При частоте кадров 30 в секунду, разработчик волен выбирать разрешения 80x60 (Resolution80x60Fps30), 320x240 (Resolution320x240Fps30) и 640x480 (Resolution640x480Fps30). И как уже было сказано в предыдущей части, существует два диапазона «рабочих» расстояний: Default Range и Near Range, определяемых перечислением DepthRange [12].
// устанавливаем диапазон расстояний
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, которую будем рассматривать, а именно трекинг человеческой фигуры (skeleton tracking).
Автор: Lardite
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/14767
Ссылки в тексте:
[1] Kinect for Windows SDK. Часть 1. Сенсор: http://habrahabr.ru/post/150955
[2] Играем в кубики с Kinect: http://habrahabr.ru/post/142236/
[3] Программа, апорт!: http://habrahabr.ru/post/142677/
[4] KinectSensor: http://msdn.microsoft.com/en-us/library/microsoft.kinect.kinectsensor
[5] ColorImageFormat: http://msdn.microsoft.com/en-us/library/microsoft.kinect.colorimageformat
[6] тут: http://msdn.microsoft.com/en-us/library/nuiimagecamera.nui_image_type
[7] тут: http://msdn.microsoft.com/en-us/library/jj131027
[8] пример: http://msdn.microsoft.com/en-us/library/hh973069
[9] KinectSensor.AudioSource: http://msdn.microsoft.com/en-us/library/microsoft.kinect.kinectsensor.audiosource
[10] Пример: http://msdn.microsoft.com/en-us/library/hh855349
[11] DepthImageFormat: http://msdn.microsoft.com/en-us/library/microsoft.kinect.depthimageformat
[12] DepthRange: http://msdn.microsoft.com/en-us/library/microsoft.kinect.depthrange.aspx
Нажмите здесь для печати.