5

私は Kinect ドライバー、CL NUI で遊んでいて、アイテムの相対的な深さを取得しようとしています。

ライブラリは、画面上のオブジェクトの深さを表す画像を取得する方法を提供します。次に例を示します。
Kinect 深度イメージ

ピクセルの色から画像の深度に変換する簡単な方法はありますか? たとえば、最も近い色が深度 0 で、最も遠い色が深度 1 である可能性があります。

誰もそれを行う方法を知っていますか?

深度データを色に変換する方法についてこれらの計算を見つけました。私が欲しいのは逆です:

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

Matrix Math が弱く、計算を逆にする方法がわかりません。

4

2 に答える 2

3

私は解決策を見つけました。

深度値はCLNUIDevice.GetCameraDepthFrameRAW画像に保存されます。この画像の色は、11ビットの深さの値から作成されます。IEには、RGBカラー用に24ビットがあります(ARGBの場合は32ビット)。深さを取得するには、次のように不要なビットを切り捨てる必要があります。

    private int colorToDepth(Color c) {
        int colorInt = c.ToArgb();

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

11ビットの数値は16ビットの場所に0が埋め込まれているため、16を使用します。IEには、次のような数値があります。1111 1111 0000 0 ### #### ####ここで、1はアルファチャネル、ゼロはパディング、「#」は実際の値です。左16をビットシフトすると、0000 0 ### #### #### 0000 0000が残ります。これは、右へのシフトを16回押し戻します:0000 0000 0000 0 ### ##### ####

于 2011-01-24T19:41:57.810 に答える
0

私が間違っている場合は修正してください。ただし、コードが Kinect から深度配列を受け取り、それを を使用して「ワールド」オブジェクト (x、y、z 座標)DepthToWorldに変換し、それを を使用してカラー 2D 配列に変換することを理解していますWorldToColor。そこから、Kinect に対する各ピクセルの距離 (メートル単位) を取得しようとしています。右?

それでは、Kinect から取得した初期深度配列を取得して、RawDepthToMeters各ピクセルで関数を呼び出してみませんか?

直前にコードによって実行された操作を逆にすると、パフォーマンスが大幅に低下します...

于 2011-01-24T00:53:04.317 に答える