2

kniectを使用してOpenCV 3.2.1でVS2010を実行しています。

ここからチュートリアルを使用しています

int main( int argc, char* argv[] ){

VideoCapture capture(CV_CAP_OPENNI); // or CV_CAP_OPENNI
for(;;)
{
    Mat depthMap;
    Mat bgrImage;

    capture.grab();

    capture.retrieve( depthMap, CV_CAP_OPENNI_DEPTH_MAP ); // Depth values in mm (CV_16UC1)
    capture.retrieve( bgrImage, CV_CAP_OPENNI_BGR_IMAGE );

    cout << "rows: " << depthMap.rows << " cols: " << depthMap.cols << endl;
    cout << "depth: " << depthMap.at<int>(0,0) << endl;

    imshow("RGB image", bgrImage);

    if( waitKey( 30 ) >= 0 )
        break;
}h
return 0;

コードを実行すると、次の結果が得られます。

約1メートル離れた壁の近く:

rows: 480 cols: 640
depth: 1157
rows: 480 cols: 640
depth: 1157
rows: 480 cols: 640
depth: 1157
rows: 480 cols: 640
depth: 1157 

(Kinect を壁に向け、1 メートルほど離れたところに配置)

rows: 480 cols: 640
depth: 83690629
rows: 480 cols: 640
depth: 83690629
rows: 480 cols: 640
depth: 83690629
rows: 480 cols: 640
depth: 83690629
rows: 480 cols: 640
depth: 83690629

これらの値は実際には 2 ピクセルであると言われました。私は本当に理解していません。

したがって、これまでの私の理解は次のとおりです。

深度フレームを取得し、depthMap というマトリックス内に格納しました。マトリックスのサイズは 640*480 になりました。コード depthMap.at(0,0) を使用して、行 0、列 0 から最初の深度値を取得しています。これは、私が期待している最大値の 10000 から大きく外れています

これらの値を利用できるように、これらの値をミリメートルに変換するにはどうすればよいですか? ありがとうございました

4

4 に答える 4

1

デプスマップデータは、単一チャネルの符号なし16ビットです。に置き換えintてみてくださいCV_16UC1

于 2012-06-12T08:02:00.137 に答える
1

深度値は 11 ビットで格納され、16 ビット変数にカプセル化されます。したがって、マトリックスにアクセスするときは、正しい要素のデータ型を指定する必要があります。前に答えたように、使用できますが、すべてのコンパイラで 16 ビット長になるdepthMap.at<unsigned short>(i,j)ことを確認する必要があります。代わりにデータ型unsigned shortを使用することを好みます。uint16_t

さらに、選択した openni PIXEL_FORMAT に応じて、マトリックス内に格納される深度値は次のようになります。

  • ミリ単位 - openni::PIXEL_FORMAT_DEPTH_1_MM
  • 10 分の 1 ミリ単位 - openni::PIXEL_FORMAT_DEPTH_100_UM

void openni::VideoMode::setPixelFormat(PixelFormat)関数 http://www.openni.ru/wp-content/doxygen/html/classopenni_1_1_video_mode.html#af7fd37bba526fced9c7dbbbf1ab419eaで pixel_format を設定できます

より正確なデータ ( PIXEL_FORMAT_DEPTH_100_UM) がミリメートル単位で必要な場合は、浮動小数点数にキャストして 10 で割ることができます。

uint16_t redValue = depthMap.at<uint16_t>(i,j);
float myVal = ( (float) redValue ) / 10.0f;
于 2016-09-21T09:59:10.377 に答える
1

私は現在 kinect (+OpenNi + OpenCv) を使用していますが、あなたがまだ問題に取り組んでいるかどうかはわかりません。

まったく同じコードを試してみましたが、depthMap.at<unsigned short>(i,j)非常にうまく機能し、値が mm で表示されました (kinect から 50 cm 離れている場合は 502)。

問題は、深さの値がどのように配信されるかについての手がかりがなく、インターネットで矛盾した情報をたくさん見たことです。なぜ2ピクセルになるのですか?なぜ Hex に変換するのですか?

ここで基本的な原則を理解するのに苦労しているのは私ではないと確信しています。それで、誰かがキネクトの深さについて確かな文書を持っていますか??

(stephane Magnenat/Nicolas Burrus の式について読みました: 11 ビットの生データを kinect し、いくつかの幾何学的要素を追加するなど... しかし、OpenNi は既にそれを処理し、そのままの深さを提供しますか??)

お気軽にコメントください。乾杯。

于 2012-06-27T18:42:37.307 に答える
0

正しいデータ型、デバッグ モード、行列を持つブレークポイントを確認し、ファイルのデータ型を確認します。

于 2015-11-18T23:49:25.683 に答える