1

次のコードは、行 240 と列 320 の深さの値を取得する際にうまく機能します。

    capture.retrieve( rawdepth, CV_CAP_OPENNI_DEPTH_MAP); // Mat rawdepth(Size(640,480), CV_16UC1);
    cout << "rows: " << rawdepth.rows << " cols: " << rawdepth.cols << endl;
    cout << "depth is " << rawdepth.at<unsigned short>(rawdepth.rows/2,rawdepth.cols/2) << endl;

Kinect の前に 1 メートルの距離で立った場合、約 1 の値が得られます。900-1100。しかし、この次のコードを追加して、kinect カメラの前に立つと、どちらも異なる結果になります。

        uint16_t* depthdata = (uint16_t*)rawdepth.data;
        cout << "depthdata is " << depthdata[76800] << endl;

kinect を他の方向に向けても、depthdata[76800] は常に 0 になります。

次のコードを使用し、Kinect を平らな壁に向けると、(rawdepth.rows/2,rawdepth.cols/2) は depthdata[78600] と同じ結果になります。

        uint16_t* depthdata = (uint16_t*)rawdepth.data;
        cout << "depthdata is " << depthdata[78600] << endl;

私の質問は、76800 の depthdata が (rawdepth.rows/2, rawdepth.cols/2) と等しくない場合、何ですか? 240*320 から 76800 を得ました。

4

2 に答える 2

2

行列が行揃えされている場合、位置 (x, y) にある要素にアクセスするには、次のようなものを使用します。

    matrix[y*elements_per_row + x]

OpenCV の行列は 32 ビットに揃えられるように設計されているため、各行の最後にパディングが含まれることがよくあります。CvMat には、size_t step各行の幅をバイト単位で示すフィールドがあります。

これを試して、期待する結果が得られるかどうかを確認してください。

    uint8_t* depthdata = (uint8_t*)rawdepth.data;
    uint16_t middle_element = *(uint16_t *)(depthdata + rawdepth.step*240 + sizeof(uint16_t)*320);
    cout << "depthdata is " << middle_element << endl;

ref: OpenCV の cv::Mat と CvMat 行の配置

于 2012-09-08T03:51:14.233 に答える
1

opencv ref マニュアルから:

2 次元配列の場合、上記の式は次のように簡略化されます。

addr(Mi,j) = M.data + M.step[0] ∗ i + M.step[1] ∗ j

M.step[i] >= M.step[i+1] (実際には M.step[i] >= M.step[i+1]*M.size[i+1] ) であることに注意してください。

于 2012-09-08T03:51:32.407 に答える