Следующий фрагмент кода хорошо работает при извлечении значения глубины в строке 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;
Глубина данных [76800] всегда дает 0, даже если я перемещаю kinect в другом направлении.
Если я использую следующий код и сталкиваю Kinect с плоской стеной, (rawdepth.rows / 2, rawdepth.cols / 2) дает тот же результат, что и deepdata [78600].
uint16_t* depthdata = (uint16_t*)rawdepth.data;
cout << "depthdata is " << depthdata[78600] << endl;
У меня вопрос, если глубина данных на 76800 не равна (rawdepth.rows / 2, rawdepth.cols / 2), мне интересно, что это? Я получил 76800 от 240 * 320.
Если матрица выровнена по строке, то для доступа к элементу в позиции (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;
Из руководства по работе с opencv:
В случае двумерного массива приведенная выше формула сводится к:
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]).