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

Применение возможностей Intel Perceptual Computing SDK для расширения границ взаимодействия людей с ограниченными возможностями с внешним миром

< Лекция 2 || Лабораторная работа 1 || Лекция 3 >
Аннотация: В данной лабораторной работе мы рассмотрим возможности Intel Perceptual Computing SDK для создания приложений по распознаванию жестов.

Дополнительные материалы к работе можно скачать здесь и здесь.

Перед началом выполнения работы необходимо настроить проект для работы с SDK. Подробно о том, как настраивать проект, было описано в первой части курса. Здесь мы только кратко напомним, что необходимо для настройки. В Проект -> Свойства добавим:

  • В Каталоги VC++ -> Каталоги включения: $(PCSDK_DIR)/include и $(PCSDK_DIR)/sample/common/include;
  • В Каталоги VC++ -> Каталоги библиотек: $(PCSDK_DIR)/lib/$(Platform) и $(PCSDK_DIR)/sample/common/lib/$(Platform)/$(PlatformToolset);
  • В Компоновщик -> Ввод-> Дополнительные зависимости: libpxc_d.lib, libpxcutils_d.lib и msimg32.lib;
  • В С/С++ -> Создание кода -> Библиотека времени выполнения: Многопоточная отладка (/MTd).

Упражнение 2.1

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

В основе приложения конвейерный класс UtilPipeline (пример 2.1), функция EnableGesture() - вызывается когда распознан жест или определен геометрический узел, функция OnGesture() вызывается, когда распознан жест или геометрический узел; функция OnNewFrame() вызывается для обработки данных нового кадра.

Для обозначения кончиков пальцев разноцветными маркерами напишем следующий код, представленный в примере 2.2. Создадим структуру skeletons[], где перечислим все необходимые нам геометрические узлы. Например, в данном приложении будем использовать кончики всех пальцев левой руки. Каждому кончику пальца присвоен свой цвет, и обозначен радиус маркера. При этом необходимо предварительно прописать необходимые цвета, как это показано в примере 2.3. Функция MapXY() используется для перевода координатного пространства глубинного изображения к RGB и обратно.

В приложении 1 приведен код упражнения 2.1.

class GesturePipeline: public UtilPipeline 
{    
public:
       GesturePipeline (void):UtilPipeline(),m_render(L"Gesture Viewer") 
	{
         EnableGesture(); 
    }
	virtual void PXCAPI OnGesture(PXCGesture::Gesture *data) 
    {
		PXCGesture* gest=QueryGesture();
		if (data->active) m_gdata = (*data);
    }
	  virtual bool OnNewFrame(void) 
    {
		return m_render.RenderFrame(QueryImage(PXCImage::IMAGE_TYPE_DEPTH),QueryGesture(), &m_gdata);
	}
protected:
    GestureRender m_render;
    PXCGesture::Gesture m_gdata;
};
    
2.1. Использование конвейерного класса UtilPipeline в приложении
static struct {
    PXCGesture::GeoNode::Label label;
    COLORREF color;
    int raduis;
} skeletons[]={
	        { PXCGesture::GeoNode::LABEL_BODY_HAND_LEFT|PXCGesture::GeoNode::LABEL_FINGER_THUMB, COLOR_GREEN, 2 },
            { PXCGesture::GeoNode::LABEL_BODY_HAND_LEFT|PXCGesture::GeoNode::LABEL_FINGER_INDEX, COLOR_RED, 2 },
            { PXCGesture::GeoNode::LABEL_BODY_HAND_LEFT|PXCGesture::GeoNode::LABEL_FINGER_MIDDLE, COLOR_BLUE, 2 },
            { PXCGesture::GeoNode::LABEL_BODY_HAND_LEFT|PXCGesture::GeoNode::LABEL_FINGER_RING, COLOR_YELLOW, 2 },
            { PXCGesture::GeoNode::LABEL_BODY_HAND_LEFT|PXCGesture::GeoNode::LABEL_FINGER_PINKY, COLOR_PINK, 2 }
};
    
2.2. Создание структуры с перечислением геометрических узлов
// задаем значения цветов в RGB палитре
#define COLOR_RED        RGB(255,0,0)
#define COLOR_GREEN      RGB(0,255,0)
#define COLOR_BLUE       RGB(0,0,255)
#define COLOR_YELLOW     RGB(255,255,0)
#define COLOR_PINK       RGB(255,0,255)
    
2.3. Перечисление значения цветов в RGB палитре

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

Рис. 2.1. Результаты распознавания кончиков пальцев: 1а - Результат распознавания, когда доступны все кончики пальцев ладони; 1б - Результат распознавание кончиков пальцев, когда доступны не все кончики пальцев

Упражнение 2.2

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

Жестовое обозначение цифр

Рис. 2.2. Жестовое обозначение цифр

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

Модуль SDK позволяет отслеживать геометрические узлы на каждом кадре, для этого используется функция QueryNodeData, которая извлекает данные о геометрических узлах. Геометрическая метка узла всегда состоит из двух частей: метки тела и локальной детализирующей метки. В примере 2.4 создадим метку геометрическую метку указательного пальца. Описание геометрического узла необходимо добавлять в функцию OnNewFrame(), которая вызывается когда новый кадр готов к обработке.

PXCGesture::GeoNode indexNode; //указательный палец
gest-> QueryNodeData(0,PXCGesture::GeoNode::LABEL_BODY_HAND_PRIMARY|PXCGesture::GeoNode::LABEL_FINGER_INDEX, &indexNode);
    
2.4. Описание геометрического узла указательного пальца

Теперь можем получить координаты (x,y) кончика пальца indexNode.positionImage.x и indexNode.positionImage.y.

Для создания приложения по распознаванию жестового обозначения цифр необходимо определять доступен ли палец в кадре. Для начала добавим метки геометрических узлов всех пальцев, как показано в примере 2.5. Следующим шагом необходимо определить доступен ли палец в кадре. Если координаты пальца больше нуля, то палец доступен в кадре (indexNode.positionImage.x>0 && indexNode.positionImage.y).

PXCGesture::GeoNode indexNode; //указательный палец
gest->QueryNodeData(0,PXCGesture::GeoNode::LABEL_BODY_HAND_PRIMARY|PXCGesture::GeoNode::LABEL_FINGER_INDEX, &indexNode);
PXCGesture::GeoNode ringNode; //безымянный палец
gest->QueryNodeData(0,PXCGesture::GeoNode::LABEL_BODY_HAND_PRIMARY|PXCGesture::GeoNode::LABEL_FINGER_RING, &ringNode);
PXCGesture::GeoNode pinkyNode; //мизинец
gest->QueryNodeData(0,PXCGesture::GeoNode::LABEL_BODY_HAND_PRIMARY|PXCGesture::GeoNode::LABEL_FINGER_PINKY, &pinkyNode);
PXCGesture::GeoNode middle; //средний палец
gest->QueryNodeData(0,PXCGesture::GeoNode::LABEL_BODY_HAND_PRIMARY|PXCGesture::GeoNode::LABEL_FINGER_MIDDLE, &middle);
PXCGesture::GeoNode thumb; //большой палец
gest->QueryNodeData(0,PXCGesture::GeoNode::LABEL_BODY_HAND_PRIMARY|PXCGesture::GeoNode::LABEL_FINGER_THUMB, &thumb);
    
2.5. Описание геометрических узлов всех пальцев

Следующий код, представленный в примере 2.6, позволяет распознавать жестовое обозначение цифр 1, 2, 3 и 4.

PXCGesture* gest=QueryGesture();

		int i=0;
		int t=0;
		int m=0;
		int r=0;
		int p=0;

PXCGesture::GeoNode indexNode; //указательный палец
gest->QueryNodeData(0,PXCGesture::GeoNode::LABEL_BODY_HAND_PRIMARY|PXCGesture::GeoNode::LABEL_FINGER_INDEX, &indexNode);
PXCGesture::GeoNode ringNode; //безымянный палец
gest->QueryNodeData(0,PXCGesture::GeoNode::LABEL_BODY_HAND_PRIMARY|PXCGesture::GeoNode::LABEL_FINGER_RING, &ringNode);
PXCGesture::GeoNode pinkyNode; //мизинец
gest->QueryNodeData(0,PXCGesture::GeoNode::LABEL_BODY_HAND_PRIMARY|PXCGesture::GeoNode::LABEL_FINGER_PINKY, &pinkyNode);
PXCGesture::GeoNode middle; //средний палец
gest->QueryNodeData(0,PXCGesture::GeoNode::LABEL_BODY_HAND_PRIMARY|PXCGesture::GeoNode::LABEL_FINGER_MIDDLE, &middle);
PXCGesture::GeoNode thumb; //большой палец
gest->QueryNodeData(0,PXCGesture::GeoNode::LABEL_BODY_HAND_PRIMARY|PXCGesture::GeoNode::LABEL_FINGER_THUMB, &thumb);

if (indexNode.positionImage.x>0 && indexNode.positionImage.y) i=1; //проверка на присутствие пальца в кадре
if (middle.positionImage.x>0 && middle.positionImage.y) m=1;
if (ringNode.positionImage.x>0 && ringNode.positionImage.y) r=1;	
if (thumb.positionImage.x>0 && thumb.positionImage.y) t=1;
if (pinkyNode.positionImage.x>0 && pinkyNode.positionImage.y) p=1;

if (i==1 && m==0 && r==0 && t==0 && p==0)  wprintf(L"1\n");
if (i==1 && m==1 && r==0 && t==0 && p==0)  wprintf(L"2\n");
    
2.6.

Дополнительное задание: Реализуйте остальные цифры. Для реализации цифры 10 используйте уровень открытости/закрытости ладони.

< Лекция 2 || Лабораторная работа 1 || Лекция 3 >
Дмитрий Юнушкин
Дмитрий Юнушкин

В лабораторной работе №2 (идентификация лица) сказано:

в FaceTracking.cs: удалим или закомментируем функцию SimplePipelineкласс MyUtilMPipeline и изменим функцию AdvancedPipeline...

Класса MyUtilMPipeline  нет в проекте вообще;

Функции AdvancedPipeline так же нет. Материалов к лабораторной  №2 в начале работы (по ссылке открывается та же страница) тоже нет.Это ошибки или используется другая версия примера?

Анатолий Федоров
Анатолий Федоров
Россия, Москва, Московский государственный университет им. М. В. Ломоносова, 1989
Дмитрий Юнушкин
Дмитрий Юнушкин
Россия, г. Пенза