OpenNI2 comes with improvement. There’s no need to self build openCV to get it work with OpenNI.
Step by step to get Kinect data in a program is: ( those boiler plate codes are mostly adapted from that of FORTH HandTrackingLib provided sample )
- Initialize OpenNI :
OpenNI::initialize(); - Call a device and open it :Device device;
device.open(openni::ANY_DEVICE); - Align the depth and color images so they have the same vantage points. Note that this generates a shift so the further object is to Kinect, the bigger the shift is, therefore at some gaps value may not exist. (I got this explanation from OpenNI documentation, though I tried but failed =( )
device.setImageRegistrationMode(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR ); - Define streams :
VideoStream depth, color; - Check if sensor is OK : (similar to color)
if(device.getSensorInfo(SENSOR_DEPTH) != NULL) - If OK, let the streams start, also check if it starts OK: if(depth.start() != STATUS_OK)
- Now they start streaming, define frames and read data from stream to frames :VideoFrameRef depthFrame, colorFrame;depth.readFrame(&depthFrame);
color.readFrame(&colorFrame); - Check if them are valid:
if(depthFrame.isValid() && colorFrame.isValid()) - If valid, convert to opencv::Mat and show:cv::Mat depth(480,640,CV_16UC1,(void*)depthFrame.getData(), 2*640);
cv::Mat depthNorm;
cv::normalize(depth, depthNorm, 0, 255, CV_MINMAX, CV_8UC1);
imshow(“Depth”, depthNorm);
cv::Mat bgrMat,rgbMat(480,640,CV_8UC3,(void*)colorFrame.getData(),3*640);
cv::cvtColor(rgbMat,bgrMat, CV_RGB2BGR);// opencv expects the image in BGR format
imshow(“Color”, bgrMat); - Remember to stop streams –> destroy streams –> close device –> shutdown openNIdepth.stop();
depth.destroy();
color.stop();
color.destroy();
device.close();
OpenNI::shutdown();
However, in order for the program to work, add those in Property Pages of the project:
- include folders of OpenNI2, OpenCV ( I use v2.4.3) under C/C++ –> General –> Additional Include Directories
- lib folders of OpenNI2, OpenCV under Linker–>General–>Additional Library Directories
- All libraries that project uses, e.g.:
opencv_core243d.lib
opencv_highgui243d.lib
opencv_imgproc243d.lib (or any other opencv libraries that you want to use)
OpenNI2.lib (mandatory) - Very important, copy all files in folder Redist of OpenNI , for example C:\Program Files\OpenNI2\Redist for 64bit, C:\Program Files (x86)\OpenNI2\Redist for 32 bit, into working directory of the project. [Working directory == place that contains files : .vcxproj .vcxproj.filters .vcxproj.user ]
Evaluation:
- Easier to get data than with KinectSDK
- Have a lot of middlewares available to use
- Depth to Color aligment doesn’t work very well
- But KinectSDK has better skeletons
- new KinectSDK 1.7 now also provides hand detection, so everything in a package
- new KinectSDk 1.7 has KinectFusion, pretty cool. I’m wondering what I can do with it.
Thanks FORTH team!
[...] Opening, shutting down device, now kid’s game with help from OpenNI, check here [...]
[...] to get distance from Kinect using OpenNI2? With OpenNI2, not only easy to get streams but also easy to take hand on [...]
[...] Opening, shutting down device, now kid’s game with help from OpenNI, check here [...]
Hi,
im using the same steps to initialize my Asus Xtion, except that I set the registrationmode right after I initialized my depth and rgb streams. Previously i did it the same way as you describe it here but then the rgb and depth images were not registered…
And when I use the Microsoft Kinect, then the alignment does not work at all… The method isImageRegistrationModeSupported(…) returns a 0.
Maybe someone has the same problems…
Cheers,
Tom
Dear Tom,
The isImageRegistrationModeSupported method does not support Kinect. It does support other depth sensors which OpenNI support (PrimeSense sensors). However, there is a guy modifying the .dll files and contribute it here http://community.openni.org/openni/topics/how_can_i_align_with_kinect
I tried his and the isImageRegistrationModeSupported returns 1. However, I still cannot align the two frames together, that is to say calibrate depth and color together.
I found some other guys have done this task extremely well http://www.youtube.com/watch?v=f1ieKe_ts0k&list=UUj_UmpoD8Ph_EcyN_xEXrUQ&index=28
and others you may find on google.
However, this guy works on Linux, so I’ve not tried it yet
Thanks for coming over to my blog, if you have other similar interests, if you can please share with me. Cheers
Dear Toan,
thanks for your quick reply. I tried the dll from the link you posted and it works in my case. So thanks for the link.
If you want to calibrate your Kinect, then follow: http://nicolas.burrus.name/index.php/Research/KinectCalibration
I use those parameters which you can find in section “Mapping depth pixels with color pixels”. They are good enough to start with.
Another question – do you maybe know how to extract the camera matrix (intrinsics) using OpenNI2 from my Asus Xtion? I just found examples for doing that using OpenNI1.
Cheers,
Tom
Dear Tom,
Thanks for the link. I’ve been to that site long ago, but again, found it not really of my interest then, so I thought I would try it later. So have you tried it? How was the result?
About Asus Xtion, I am really sorry that I don’t know much
since I use only Kinect for my work. I think the code of OpenNI is the same. What do you mean by camera matrix? do you mean the data? if so, use getData() like in here http://magicalkinect.wordpress.com/2013/02/19/refine-old-work/
Hello, I am trying your code for my project which is due this week. I was wondering whether I am required to do # include openni? And all those codes I need to palce inside int main() {} right?
Hai sorry to post 2 comments but I have place the code inside my project and there is red line error, starting from OpenNi::initialize. Please help me
#include”math.h”
#include”conio.h”
#include”stdio.h”
#include
#include
#include
int main()
{
OpenNI::initialize();
Device device;
device.open(openni::ANY_DEVICE);
device.setImageRegistrationMode(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR );
VideoStream depth, color;
if(device.getSensorInfo(SENSOR_DEPTH) != NULL)
VideoFrameRef depthFrame, colorFrame;depth.readFrame(&depthFrame);
color.readFrame(&colorFrame);
if(depthFrame.isValid() && colorFrame.isValid())
cv::Mat depth(480,640,CV_16UC1,(void*)depthFrame.getData(), 2*640);
cv::Mat depthNorm;
cv::normalize(depth, depthNorm, 0, 255, CV_MINMAX, CV_8UC1);
imshow(“Depth”, depthNorm);
cv::Mat bgrMat,rgbMat(480,640,CV_8UC3,(void*)colorFrame.getData(),3*640);
cv::cvtColor(rgbMat,bgrMat, CV_RGB2BGR);// opencv expects the image in BGR format
imshow(“Color”, bgrMat);
depth.stop();
depth.destroy();
color.stop();
color.destroy();
device.close();
OpenNI::shutdown();
}
hi there,
have you configured the project to work with the library? You will need to put the “include”, “lib” folders in settings, also link the “bin” folder to System Path, then include the headers and use the code.
best regards,
T