首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用CL NUI Kinect驱动程序,将深度颜色转换为实际相对距离

使用CL NUI Kinect驱动程序,将深度颜色转换为实际相对距离
EN

Stack Overflow用户
提问于 2011-01-22 04:11:12
回答 2查看 3.2K关注 0票数 5

我正在使用Kinect驱动程序CL NUI,并试图获得项目的相对深度。

该库提供了一种在屏幕上获取表示对象深度的图像的方法。下面是一个示例:

有没有一种简单的方法可以从像素颜色转换到图像深度?例如,最接近的颜色可以是深度0,而最远的颜色可以是深度1。

有人知道怎么做吗?

我找到了这些关于如何将深度数据转换为颜色的计算,我想要的是相反的:

代码语言:javascript
复制
float RawDepthToMeters(int depthValue)
{
    if (depthValue < 2047)
    {
        return float(1.0 / (double(depthValue) * -0.0030711016 + 3.3309495161));
    }
    return 0.0f;
}

Vec3f DepthToWorld(int x, int y, int depthValue)
{
    static const double fx_d = 1.0 / 5.9421434211923247e+02;
    static const double fy_d = 1.0 / 5.9104053696870778e+02;
    static const double cx_d = 3.3930780975300314e+02;
    static const double cy_d = 2.4273913761751615e+02;

    Vec3f result;
    const double depth = RawDepthToMeters(depthValue);
    result.x = float((x - cx_d) * depth * fx_d);
    result.y = float((y - cy_d) * depth * fy_d);
    result.z = float(depth);
    return result;
}

Vec2i WorldToColor(const Vec3f &pt)
{
    static const Matrix4 rotationMatrix(
                            Vec3f(9.9984628826577793e-01f, 1.2635359098409581e-03f, -1.7487233004436643e-02f),
                            Vec3f(-1.4779096108364480e-03f, 9.9992385683542895e-01f, -1.2251380107679535e-02f),
                            Vec3f(1.7470421412464927e-02f, 1.2275341476520762e-02f, 9.9977202419716948e-01f));
    static const Vec3f translation(1.9985242312092553e-02f, -7.4423738761617583e-04f, -1.0916736334336222e-02f);
    static const Matrix4 finalMatrix = rotationMatrix.Transpose() * Matrix4::Translation(-translation);

    static const double fx_rgb = 5.2921508098293293e+02;
    static const double fy_rgb = 5.2556393630057437e+02;
    static const double cx_rgb = 3.2894272028759258e+02;
    static const double cy_rgb = 2.6748068171871557e+02;

    const Vec3f transformedPos = finalMatrix.TransformPoint(pt);
    const float invZ = 1.0f / transformedPos.z;

    Vec2i result;
    result.x = Utility::Bound(Math::Round((transformedPos.x * fx_rgb * invZ) + cx_rgb), 0, 639);
    result.y = Utility::Bound(Math::Round((transformedPos.y * fy_rgb * invZ) + cy_rgb), 0, 479);
    return result;
}

我的矩阵数学很弱,我不确定如何反转计算。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-01-25 03:41:58

我找到了解决方案。

深度值存储在CLNUIDevice.GetCameraDepthFrameRAW图像中。此图像的颜色是从11位深度值创建的。即,RGB颜色有24位(如果是ARGB,则为32位)。要获得深度,您需要截断不必要的位,如下所示:

代码语言:javascript
复制
    private int colorToDepth(Color c) {
        int colorInt = c.ToArgb();

        return (colorInt << 16) >> 16;
    }

您使用16,因为对于16位的位置,11位数字是0填充的。也就是说,你有一个看起来像这样的数字: 1111 1111 0000 0### ########,其中1是alpha通道,0是填充,'#‘是实际值。向左16位移位后,您将得到0000 0### ######## 0000 0000,您希望将我的移位向右推16次: 0000 0000 0000 0### ##### ####

票数 3
EN

Stack Overflow用户

发布于 2011-01-24 08:53:04

如果我错了,请纠正我,但据我所知,您的代码从Kinect接收深度数组,使用DepthToWorld将其转换为“世界”对象(具有x,y,z坐标),然后使用WorldToColor将其转换为彩色2D数组。在此基础上,您尝试检索每个像素相对于Kinect的距离(以米为单位)。对吗?

那么,为什么不直接从Kinect中获取初始深度数组,然后在每个像素上调用RawDepthToMeters函数呢?

反转您的代码之前所做的操作会造成巨大的性能损失……

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4763320

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档