通过在OpenCV中使用指针来检索深度

时间:2012-09-08 03:18:12

标签: c++ arrays opencv kinect openni

以下代码可以很好地检索第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米处,它会给出大约的值。 900-1100。但是当我添加以下代码时,我站在kinect摄像头前,两者都会产生不同的结果。

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

depthdata [76800]总是产生0,即使我将kinect移向另一个方向。

如果我使用下面的代码,并将Kinect面对平面墙,(rawdepth.rows / 2,rawdepth.cols / 2)给出与depthdata相同的结果[78600]。

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

我的问题是,如果76800的深度数据不等于(rawdepth.rows / 2,rawdepth.cols / 2),我想知道,是什么?我从240 * 320获得了76800。

2 个答案:

答案 0 :(得分: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's cv::Mat & CvMat row alignment

答案 1 :(得分:1)

来自opencv参考手册:

在二维数组的情况下,上述公式简化为:

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

注意M.step [i]&gt; = M.step [i + 1](事实上,M.step [i]> = M.step [i + 1] * M.size [i + 1])。