Kinect необработанная глубина на расстояние в метрах - PullRequest
3 голосов
/ 11 января 2012

Я пытаюсь преобразовать карту глубины Kinect в расстояние в метрах.Проблема заключается в том, что для значения карты глубины «1080» и вокруг него расстояние слишком велико, поскольку термин в знаменателе становится очень близким к «0».а для значений выше '1090' расстояние отрицательно.

if (depthValue < 2047) 
{
  depthM = 1.0 / (depthValue*-0.0030711016 + 3.3309495161);
}

Ответы [ 2 ]

5 голосов
/ 13 марта 2012

Правильный ответ - на самом деле комментарий к вашему вопросу. Указанное число на самом деле является расстоянием в миллиметрах. Чтобы получить это число, вам нужно либо использовать скелетное соединение и вызвать 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);
}
3 голосов
/ 09 ноября 2013

старый неактивный вопрос, но в любом случае вот что у меня сработало. У меня есть старая модель kinect (1414 для XBOX360 + сокращение ПК), и недавно я успел сделать код и измерения:

  1. мои необработанные данные 16 бит, а не 10/11/12/13 бит !!!

    , поэтому, вероятно, ваши данные очень похожи.Минимальное измеренное расстояние равно ~0.95m максимальное неизвестное расстояние (недостаточно большой площади для тестирования), а минимальное допустимое значение равно 6408 ... ~0.95m от датчика.Другое допустимое значение - 15800 ... ~2.5m от датчика для интерполяции

  2. наивное (линейное) преобразование в метры

    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
    
  3. когда у меня будет больше времени, я проверю линейность и уточню

    , чтобы сделать это, мне нужно выполнить некоторое программирование для лучшего измерения и настроить рабочую область для более точного расстоянияизмерения.Более точные константы могут добавлять косинусную коррекцию, если это необходимо.Я не знаю, если устройство / драйвер делает это сам или нет, чтобы измерить его.Когда я доберусь до него, я обновлю свой ответ, но я очень ленив, так что это может занять какое-то время ...

[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 - слишком далеко / неизвестное значение или даже что-то еще (есть больше возможностей)

...