7

Kinect を脇に置かずに、OpenCV を使用して特定のデータセットを操作しています。そして、指定された深度データを対応するRGBにマップしたいと思います(実際の色と深度を取得できるように)

私は OpenCV と C++ を使用しており、Kinect を所有していないため、残念ながら公式の Kinect API から MapDepthFrameToColorFrame メソッドを利用できません。

指定されたカメラの固有値と歪み係数から、深さをワールド座標にマッピングし、ここで提供されているアルゴリズムに基づいて RGB に戻すことができました

Vec3f depthToW( int x, int y, float depth ){
    Vec3f result;
    result[0] = (float) (x - depthCX) * depth / depthFX;
    result[1] = (float) (y - depthCY) * depth / depthFY;
    result[2] = (float) depth;
    return result;
}

Vec2i wToRGB( const Vec3f & point ) {
    Mat p3d( point );
    p3d = extRotation * p3d + extTranslation;

    float x = p3d.at<float>(0, 0);
    float y = p3d.at<float>(1, 0);
    float z = p3d.at<float>(2, 0);

    Vec2i result;
    result[0] = (int) round( (x * rgbFX / z) + rgbCX );
    result[1] = (int) round( (y * rgbFY / z) + rgbCY );
    return result;
}

void map( Mat& rgb, Mat& depth ) {
    /* intrinsics are focal points and centers of camera */
    undistort( rgb, rgb, rgbIntrinsic, rgbDistortion );
    undistort( depth, depth, depthIntrinsic, depthDistortion );

    Mat color = Mat( depth.size(), CV_8UC3, Scalar(0) );
    ushort * raw_image_ptr;

    for( int y = 0; y < depth.rows; y++ ) {
        raw_image_ptr = depth.ptr<ushort>( y );

        for( int x = 0; x < depth.cols; x++ ) {
            if( raw_image_ptr[x] >= 2047 || raw_image_ptr[x] <= 0 )
                continue;

            float depth_value = depthMeters[ raw_image_ptr[x] ];
            Vec3f depth_coord = depthToW( y, x, depth_value );
            Vec2i rgb_coord   = wToRGB( depth_coord );
            color.at<Vec3b>(y, x) = rgb.at<Vec3b>(rgb_coord[0], rgb_coord[1]);
        }
    }

しかし、結果はずれているようです。データセットは 3 つの異なる Kinect から取得され、それぞれが異なる方向にずれているため、翻訳を手動で設定することはできません。以下にその 1 つを示します (左: 歪みのない RGB、中央: 歪みのない深さ、右: RGB を深さにマッピング)

ここに画像の説明を入力

私の質問は、この時点で何をすべきかということです。デプスをワールドに、またはワールドを RGB に投影しようとしているときに、手順を間違えましたか? ステレオカメラの経験がある人は、私の失敗を指摘できますか?

4

4 に答える 4

0

OpenCV には、深度ストリームをカラー ビデオ ストリームに合わせる機能がありません。しかし、「Kinect for Windows SDK」に名前が付けられた特別な機能があることは知っています。MapDepthFrameToColorFrame

たとえば、コードはありませんが、これが開始点として適切であることを願っています。

Upd: これ 、KinectSDK を OpenCV へのインターフェイス (私のコードではありません) を使用して、カラー画像を深度にマッピングする同じ例です。

于 2013-06-10T05:15:24.557 に答える
0

はい、RGB と深度の間の変換を考慮していませんでした。しかし、この行列を計算するには、cvStereoCalibrate() メソッドを使用します。このメソッドは、RGB と深度の両方のイメージ シーケンスをチェッカーボード コーナーと共に渡すだけです。詳細については、OpecvCV のドキュメントを参照して ください cameraMatrix2、InputOutputArray distCoeffs2、Size imageSize、OutputArray R、OutputArray T、OutputArray E、OutputArray F、TermCriteria 基準、int フラグ)

そして、この背後にあるメソッド全体のアイデアは次のとおりです。

color uv <- 色の正規化 <- 色空間 <- DtoC 変換 <- 深度空間 <- 深度の正規化 <- 深度 uv (uc,vc) <- <- ExtrCol * (pc) <- ステレオ キャリブレーション MAT <- ExtrDep^- 1 * (pd) <- <(ud - cx)*d / fx, (vd-cy)*d/fy, d> <- (ud, vd)

RGB に歪みを追加したい場合は、http: //docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.htmlの手順に従うだけです。

于 2016-09-20T17:33:38.387 に答える
0

ソリューションで両方のカメラ間の外部要因を考慮していないようです。

于 2016-07-14T12:24:09.683 に答える