Kinect необработанная глубина на расстояние в метрах
Я пытаюсь преобразовать карту глубины Kinect в расстояние в метрах. Проблема в том, что для значения карты глубины '1080' и вокруг него расстояние слишком велико, поскольку термин в знаменателе становится очень близким к '0'. и для значений выше '1090' расстояние отрицательно.
if (depthValue < 2047)
{
depthM = 1.0 / (depthValue*-0.0030711016 + 3.3309495161);
}
2 ответа
Правильный ответ - это на самом деле комментарий к вашему вопросу. Указанное число на самом деле является расстоянием в миллиметрах. Чтобы получить это число, вам нужно либо использовать соединение каркаса и вызвать MapFromSkeletonPoint элемента DepthImageFrame, либо сместить необработанное короткое значение вправо с помощью DepthImageFrame.PlayerIndexBitmaskWidth.
Например, Скелет
using (var skeletonFrame= e.OpenSkeletonFrame())
using (var depthFrame = e.OpenDepthImageFrame())
{
skeletonFrame.CopySkeletonDataTo(skeletons);
var skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
foreach (var skeleton in skeletons)
{
if (skeleton.TrackingState != SkeletonTrackingState.Tracked) continue;
var head = skeleton.Joints[JointType.Head];
if (head.TrackingState == JointTrackingState.NotTracked) continue;
var depthImagePoint = depthFrame.MapFromSkeletonPoint(head.Position);
int depthInMillimeters = depthImagePoint.Depth; // TADA!
}
}
Например сдвиг
using (var depthFrame = e.OpenDepthImageFrame())
{
var depthArray = new short[depthFrame.PixelDataLength];
depthFrame.CopyPixelDataTo(depthArray);
for (int i = 0; i < depthArray.Length; i++) {
int depthInMillimeters =
depthArray[i] >> DepthImageFrame.PlayerIndexBitmaskWidth;
// TADAx2!
}
Исходное решение, приведенное ниже, больше не является правильным:
Основано на содержании этой статьи - http://openkinect.org/wiki/Imaging_Information:
if (depthValue <= 2047) {
depthM = 0.1236 * Math.Tan(depthValue / 2842.5 + 1.1863);
}
Старый неактивный вопрос, но в любом случае вот что у меня сработало. У меня есть старая модель kinect (1414 для XBOX360 + сокращение ПК), и недавно я успел сделать некоторый код и измерения:
мои необработанные данные 16 бит, а не 10/11/12/13 бит!!!
так что, вероятно, ваши данные очень похожи. Минимальное измеренное расстояние
~0.95m
максимальное расстояние неизвестно (недостаточно большой площади для тестирования) и минимальное допустимое значение6408 ... ~0.95m
от датчика. Другое допустимое значение15800 ... ~2.5m
от датчика для интерполяциинаивное (линейное) преобразование в метры
float z,m=(2.5-0.9)/(15800.0-6408.0); WORD raw; raw=... raw depth form camera/image; z=0.0; if ((raw>=6408)&&(raw< 0xFFF0)) z=0.9+(float(raw-6408)*m); // here z is range in [m] or 0 for invalid depth
когда у меня будет больше времени, я проверю линейность и уточню
Для этого мне нужно немного программировать для лучшего измерения и настроить рабочую область для более точных измерений расстояния. Более точные константы могут добавлять косинусную коррекцию, если это необходимо. Я не знаю, если устройство / драйвер делает это сам или нет, чтобы измерить его. Когда я доберусь до него, я обновлю свой ответ, но я очень ленив, так что это может быть какое-то время...
[Edit 1] сделал некоторые настройки измерения геометрии и изменения кода
Итак, вот новые более точные выводы:
if (raw==0x0000) z=0.0;
else if (p.raw>=0x8000) p.z=4.0;
else p.z=0.8+(float(p.raw-6576)*0.00012115165336374002280501710376283);
raw
данные уже косинус исправлены водителем или самим Kinect так raw
представляют перпендикулярное расстояние от датчика. raw
данные линейно перпендикулярны расстоянию (по крайней мере, на расстоянии 0,8 - 2,0 м) и после более точного измерения диапазон глубины составляет <0.8 - 4.0> [m]
, Измерения раньше были неточными.
raw = 0
слишком близко значениеraw >= 32768
слишком большое / неизвестное значение или даже что-то еще (есть больше возможностей)