11.07.2015 Views

ПРИНТЕРЫ СЕГОДНЯ - Xakep Online

ПРИНТЕРЫ СЕГОДНЯ - Xakep Online

ПРИНТЕРЫ СЕГОДНЯ - Xakep Online

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

104КодингХАКЕР 04 /171/ 2013Рис. 3. Kinect Studioи содержащего сведения о кадре, возвращается сам фрейм —объект класса ColorImageFrame. Этот объект после использованиядолжен быть уничтожен, поэтому его получение и происходитвнутри конструкции using. Затем этот объект проверяетсяна равенство null, если так, то прекращаем выполнение метода.Такое может произойти, если фрейм еще не готов. Далее объявленномуранее массиву байт задается размер, равный длинефрейма, — colorFrame.PixelDataLength. Следующим действиемфункцией CopyPixelDataTo объекта класса ColorImageFrameпиксели фрейма копируются в байтовый массив. Далее, еслиbitmap — ссылка на объект класса WriteableBitmap, объявленногов начале класса, равняется null, значит, объект не создан и егонеобходимо создать при помощи конструктора данного класса.Объект принимает шесть параметров: ширина и высота (берутсяот соответствующих данных — членов фрейма), количествоточек на дюйм по горизонтали и вертикали, формат пикселей ипалитра. Палитра в данном случае не нужна — передаем вместонее null, а формат пикселей — обратный общепринятому, BGR.Между прочим, он прекрасно поддерживается и не требует преобразования.После создания этого объекта с помощью его методаWritePixels происходит запись в него пикселей из байтовогомассива. Метод принимает четыре параметра: прямоугольнаяобласть (объект класса Int32Rect) для копирования, буфер-источник,в нашем случае массив байт, размер копируемого буфера,шаг для обновления — в нашем случае 0. Последним действиемпередаем получившийся битмап на вывод для элементауправления класса Image. В конце работы приложения при закрытииокна надо остановить Кинект командой kinect.Stop();.Минимум действий выполнен, можешь откомпилить и посмотретьрезультат. Обрати внимание: некоторые программыдля Кинекта не работают под дебаггером!Для удобства работы с Кинектом хорошей идеей будет добавитьвозможность изменить угол обзора камеры. Добавьв разрабатываемую прогу две кнопки (см. на диске проектKinectStreamControl). Первая из них будет служить для наклонаКинекта кверху, вторая, соответственно, книзу. Заметь,Кстати, для удобства работы с Кинектомхорошей идеей будет добавить возможностьизменить угол обзора камерычто для добавления дополнительных объектов в XAML-разметку надо создать контейнер,в который и поместить Image и два Button’а. Например, в качестве такогоконтейнера может служить StackPanel. Далее создай обработчик нажатия на первуюкнопку. Предположим, что нам надо изменять наклон на пять градусов, в этомслучае для кнопки «Вверх» напиши: kinect.ElevationAngle += 5;, чтобы осуществитьнаклон книзу, надо просто изменить знак. В результате приложение сможет изменятьугол обзора (по оси X), наклоняя камеру. P. S. Или я пересидел, или это действительнонапоминает Валли. И звук такой же :).Поток глубиныДля вывода данных с камеры глубины нам потребуется внести некоторые измененияв наш прошлый проект. Сделай его копию, и начнем.Первым делом надо изменить поток получаемых данных, который назначаетсяв событие загрузки формы, то есть изменить ColorStream на DepthStream: kinect.DepthStream.Enable();. Вместе с этим измени тип и имя регистрируемого на получениеданных с Кинекта события: kinect.DepthFrameReady += new EventHandler(kinect_DepthFrameReady);. Соответственноизмени заголовок обработчика; в прошлом проекте мы получали данные, которыебыло удобно хранить в массиве байт, поскольку один пиксель описывался32 битами: по байту на каждый из трех цветов + байт на альфа-канал, а сейчасот камеры глубины мы будем получать данные в другом формате. Формат этотподразумевает, что каждый пиксель здесь представлен 13 битами, таким образом,ближайший к этому размеру имеет тип short, содержащий 16 бит. Следовательно,надо объявить массив данного типа: short[] depthData = null;. Междутем эти 3 бита не будут пропадать, поскольку в них записывается идентификаторигрока, попадающего в камеру. Как уже было сказано, Кинект позволяет различатьдо шести тел, но связанный скелет он строит только для двух из них. Но теманастоящего разговора не о скелетах, поэтому мы будем просто сдвигать эти 3бита. При этом старый массив типа byte остается нужен для хранения формированияитогового изображения глубины. Итак, перейдем в обработчик полученияданных и изменим его. Начало функции должно подвергнуться лишь изменениютипа данных с byte на short. После копирования пикселей фрейма в массив глубины:depthFrame.CopyPixelDataTo(depthData); мы инициализируем массив байтразмером, равным длине фрейма, умноженной на 4. Далее нам нужна переменная,которая будет указывать на определенный пиксель во фрейме и на соответствующуюпозицию в массиве, так как их размеры одинаковы. Следующимдействием запустим цикл по пикселям фрейма, чтобы узнать их значение. Первымделом в цикле, взяв значение элемента массива глубины, который, по сути,равен фрейму, сдвигаем 3 бита, тем самым оставляятолько значение глубины. После этого мы можем проверитьего. Кинект не всегда в состоянии правильно определитьзначение глубины (причиной этого может статьвыходящее за пределы расстояние между сенсороми объектом управления), в таком случае в пиксель записываютсяпредопределенные значения. Существует три

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!