Преобразование Kinect из данных скелета в данные глубины и обратно

0

Я экспериментирую с API-интерфейсом kinect, и то, что я пытаюсь (и не могу) достичь, следующее:

начиная с того, что я получаю данные скелета из kinect и выделяю расстояние правой руки пользователя от kinect

mRightHandPosition = skeletonFrame.SkeletonData[i].SkeletonPositions[NUI_SKELETON_POSITION_HAND_RIGHT];    
distance = sqrt(pow(mRightHandPosition.x, 2) + pow(mRightHandPosition.y, 2) + pow(mRightHandPosition.z, 2));

Я преобразую данные скелета правой руки в данные глубины, чтобы получить положение руки в изображении (глубину/цвет).

FLOAT curRightX = 0, curRightY = 0;
Vector4 pixelInSkeletonSpace;
NuiTransformSkeletonToDepthImage(mRightHandPosition, &curRightX, &curRightY, cDepthResolution);

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

//the position of the depth pixel in the mLockedRect.pBits array 
//i have set the depth sensor resolution to 320x240
int pixelPosition = 2 * ((int)curRightX + (int)curRightY * 320);
USHORT p;
//convert the two consecutive bytes to USHORT
p = (((unsigned short)mLockedRect.pBits[pixelPosition]) << 8) | mLockedRect.pBits[pixelPosition + 1];
//get the pixel in skeleton space
pixelInSkeletonSpace = NuiTransformDepthImageToSkeleton(LONG(curRightX), LONG(curRightY), p, cDepthResolution);
//calculate again the distance (which turns out completely wrong)
distance = sqrt(pow(pixelInSkeletonSpace.x, 2) + pow(pixelInSkeletonSpace.y, 2) + pow(pixelInSkeletonSpace.z, 2));

мне что-то не хватает? заранее спасибо

Теги:
kinect
kinect-sdk

1 ответ

0
Лучший ответ

После многих поисков я узнал, что не так. Вот решение для всех, кто пытается сделать что-то похожее

сначала, чтобы сохранить данные глубины, лучший способ (я нашел)) был следующим

в функции processDepth():

bghr = m_pBackgroundRemovalStream->ProcessDepth(m_depthWidth * m_depthHeight * cBytesPerPixel, LockedRect.pBits, depthTimeStamp);
const NUI_DEPTH_IMAGE_PIXEL* pDepth = reinterpret_cast<const NUI_DEPTH_IMAGE_PIXEL*>(LockedRect.pBits);
memcpy(mLockedBits, pDepth, m_depthWidth * m_depthHeight * sizeof(NUI_DEPTH_IMAGE_PIXEL));

в функции ComposeImage() (или любой функции, которую вы хотите использовать данные глубины):

//transform skeleton data point to depth data
NuiTransformSkeletonToDepthImage(mRightHandPosition, &curRightX, &curRightY, cDepthResolution);

//calculate position of pixel in array
int pixelPosition = (int)curRightX + ((int)curRightY * m_depthWidth);

//get the depth value of the pixel
const USHORT depth = mLockedBits[pixelPosition].depth;

//create a new point in skeleton space using the data we got from the previous transformation
pixelInSkeletonSpace = NuiTransformDepthImageToSkeleton(LONG(curRightX), LONG(curRightY), depth << 3, cDepthResolution);

//calculate estimated distance of right hand from the kinect sensor using our recreated data
FLOAT estimated_distance = sqrt(pow(pixelInSkeletonSpace.x, 2) + pow(pixelInSkeletonSpace.y, 2) + pow(pixelInSkeletonSpace.z, 2));

//calculate the distance of the right hand from the kinect sensor using the skeleton data that we got straight from the sensor
FLOAT actual_distance = sqrt(pow(mRightHandPosition.x, 2) + pow(mRightHandPosition.y, 2) + pow(mRightHandPosition.z, 2));

теперь оценочное значение и фактическое расстояние должны иметь примерно одинаковые значения с некоторой небольшой дисперсией.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню