Reputation: 31
I have VS2010 running with OpenCV 3.2.1 with kniect.
i'm using the tutorial from here
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;
after running the code I get the following results:
close to the wall about a meter away:
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 facing the wall, just over a meter away)
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
I have been told that these values are in fact two pixels? which I really don't understand.
So here is my understanding so far:
I grabbed a depth frame and stored it inside a matrix called depthMap. the size of the matrix is now 640*480. I am using the code depthMap.at(0,0) to grab the first depth value from row 0, column 0. but instead of getting back a result on millimetres i get back 83690629! which is way off the max value of 10000 which i'm expecting
How can I convert these values into millimetres so I can make use of them? thank you
Upvotes: 2
Views: 8483
Reputation: 105
the depth values are stored in 11 bit, encapsulated in a 16 bit variable.
Thus, when you access your matrix you must provide the correct element data-type.
As answered before, you can use depthMap.at<unsigned short>(i,j)
but you must be sure that unsigned short
will be 16 bit long in all compilers.
I prefer to use uint16_t
data type instead.
Furthermore, depending on the openni PIXEL_FORMAT that you have selected, the depth value stored inside the matrix can be:
you can set the pixel_format with void openni::VideoMode::setPixelFormat(PixelFormat)
function
http://www.openni.ru/wp-content/doxygen/html/classopenni_1_1_video_mode.html#af7fd37bba526fced9c7dbbbf1ab419ea
if you want the more accurated data (PIXEL_FORMAT_DEPTH_100_UM
) in millimiters, you can cast it to float and divide it by 10:
uint16_t redValue = depthMap.at<uint16_t>(i,j);
float myVal = ( (float) redValue ) / 10.0f;
Upvotes: 1
Reputation: 1170
check for the correct datatype, debug mode and then breakpoint having the matrix, then check the file datatype
Upvotes: 0
Reputation: 19
I'm currently working with the kinect (+OpenNi + OpenCv) and I don't know if you're still stuggling with your issue.
I tried the exact same code but with depthMap.at<unsigned short>(i,j)
and it worked very well, giving me the value in mm (502 when I'm 50 cm away from the kinect)
The problem is : I don't have a clue about how the depth value is delivered and I saw a lot of contradictory informations on the internet. Why would it be 2 pixels? Why convert to Hex?
I'm sure I'm not the one to struggle with understanding the underlying principles here. So, does someone has some solid documentation abour the kinect depth??
(I read about stephane Magnenat/Nicolas Burrus formulas : kinect raw data on 11 bits, adding some geometrical stuff and so on... But does OpenNi deal with that already and provide the depth as is??)
Feel free to comment. Cheers.
Upvotes: 1
Reputation: 1776
The depth map data is a single channel unsigned 16Bit.
Try to replace int
to CV_16UC1
Upvotes: 1