Kinect 原始深度到距离(以米为单位)

发布于 2024-12-26 03:31:53 字数 216 浏览 2 评论 0原文

我正在尝试将 Kinect 深度图转换为以米为单位的距离。问题在于,对于深度图值“1080”及其附近,距离太大,因为分母中的项变得非常接近“0”。对于“1090”以上的值,距离为负值。

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

I am trying to convert Kinect depth map to distance in meters. The problem is that for depthmap value '1080' and around it, distance is too large because the term in denominator becomes very close to '0'. and for values above '1090', distance is negative.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寻找我们的幸福 2025-01-02 03:31:53

正确的答案实际上是对你的问题的评论。给出的数字实际上是以毫米为单位的距离。要获得此数字,您需要使用骨架关节并调用 DepthImageFrame 的 MapFromSkeletonPoint 或将原始短值右移 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!
    }
}

例如 shift

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);
}

The correct answer is actually a comment on your question. The number given is actually a distance in millimetres. To get this number, you either need to use a skeleton joint and call DepthImageFrame's MapFromSkeletonPoint or shift the raw short value right by DepthImageFrame.PlayerIndexBitmaskWidth.

E.g. Skeleton

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!
    }
}

E.g. shift

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!
}

The original solution below is no longer correct:

Based on the contents of this article - http://openkinect.org/wiki/Imaging_Information:

if (depthValue <= 2047) {
   depthM = 0.1236 * Math.Tan(depthValue / 2842.5 + 1.1863);
}
滥情哥ㄟ 2025-01-02 03:31:53

老不活跃的问题,但无论如何,这对我有用我有一个旧型号的kinect(1414用于XBOX360 + PC还原),最近有时间制作一些代码和测量:

  1. 我的原始数据不是16位10/11/12/13 位!!!

    所以您的数据可能非常相似。测量的最小距离为 ~0.95m 最大距离未知(没有足够大的区域用于测试),最小有效值为距传感器 6408 ... ~0.95m 。另一个有效值是15800 ... ~2.5m,来自用于插值的传感器

  2. 朴素(线性)转换为米

    浮点 z,m=(2.5-0.9)/(15800.0-6408.0);
    字原;
    
    raw=...原始深度形式相机/图像;
    z=0.0;
    if ((raw>=6408)&(raw<0xFFF0)) 
     z=0.9+(浮点数(raw-6408)*m);
    // 这里 z 的范围为 [m] 或 0 表示无效深度
    
  3. 当我有更多时间时,我会检查线性度并使其更精确< /p>

    为此,我需要进行一些编程以实现更好的测量,并设置工作区域以实现更精确的距离测量。如果需要,更精确的常数可能会添加余弦校正。我不知道设备/驱动程序是否自己制作或不需要测量它。当我到达时会更新我的答案,但我很懒,所以可能需要一段时间......

[编辑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 表示距传感器的垂直距离。 原始数据与垂直距离呈线性关系(至少在 0.8 - 2.0 m 范围内),经过更精确的测量后,深度范围为 <0.8 - 4.0> 。 [m]。之前的测量不准确。

raw = 0 值太接近

raw >= 32768 太远/未知值甚至其他东西(还有更多可能性)

old inactive question but anyway here is what worked for me I have an old model of kinect (1414 for XBOX360 + PC reduction) and recently had time to make some code and measurements:

  1. my raw data is 16 bit not 10/11/12/13 bit !!!

    so probably your data is very similar. Min distance measured is ~0.95m max distance unknown (have not big enough area for testing) and min valid value is 6408 ... ~0.95m from sensor . Another valid value is 15800 ... ~2.5m from sensor for interpolation

  2. naive (linear) transformation to meters

    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. when I will have more time then I will check the linearity and make it more precise

    to do that I need to make some programing for better measurement and setup working area for more precise distance measurements. More precise constants maybe add cosine correction if its needed. I do not know if device/driver make it itself or not have to measure it. When I get to it will update my answer but I am very lazy so it can be a while ...

[Edit 1] made some geometry measurement setup and code changes
so here are new more precise conclusions:

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 data is already cosine corrected by driver or kinect itself so raw represent perpendicular distance from sensor. raw data is linear to perpendicular distance (at least on 0.8 - 2.0 m range) and after more precise measurement the depth range is <0.8 - 4.0> [m]. Measurements before was inaccurate.

raw = 0 is too close value

raw >= 32768 is too far / unknown value or even something else (there are more possibilities)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文