C++ 如何将Kinect与openni和opencv一起使用
首先,我只需要捕获rgb流,并将其转换为一系列opencv图像。这应该没那么难,但我在网上找到了不止一个代码,但它们并没有在我的电脑上运行。我不知道哪里出了错 你能给我推荐一个教程,一个非常简单的代码,让我了解如何使用Kinect库吗? 一开始我尝试了Kinect sdk,过了一会儿我选择了OPENNI 救救我,谢谢C++ 如何将Kinect与openni和opencv一起使用,c++,opencv,kinect,rgb,openni,C++,Opencv,Kinect,Rgb,Openni,首先,我只需要捕获rgb流,并将其转换为一系列opencv图像。这应该没那么难,但我在网上找到了不止一个代码,但它们并没有在我的电脑上运行。我不知道哪里出了错 你能给我推荐一个教程,一个非常简单的代码,让我了解如何使用Kinect库吗? 一开始我尝试了Kinect sdk,过了一会儿我选择了OPENNI 救救我,谢谢 ps:我正在使用c++和VisualStudio2010AFAIK开箱即用OpenCV支持OpenNI 1.5.x。 如果您尚未安装OpenNI,请先按以下特定顺序安装(这很重要)
ps:我正在使用c++和VisualStudio2010AFAIK开箱即用OpenCV支持OpenNI 1.5.x。 如果您尚未安装OpenNI,请先按以下特定顺序安装(这很重要):
完成后,按generate,wich将生成轻松编译opencv库所需的visual studio项目文件
有关在windows上从源代码构建opencv的更多详细信息,请查看
编译完成后,应使用openni支持构建opencv,并应能够运行以下简单操作:
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(){
cout << "opening device(s)" << endl;
VideoCapture sensor1;
sensor1.open(CV_CAP_OPENNI);
if( !sensor1.isOpened() ){
cout << "Can not open capture object 1." << endl;
return -1;
}
for(;;){
Mat depth1;
if( !sensor1.grab() ){
cout << "Sensor1 can not grab images." << endl;
return -1;
}else if( sensor1.retrieve( depth1, CV_CAP_OPENNI_DEPTH_MAP ) ) imshow("depth1",depth1);
if( waitKey( 30 ) == 27 ) break;//ESC to exit
}
}
#包括“opencv2/core/core.hpp”
#包括“opencv2/highgui/highgui.hpp”
#包括“opencv2/imgproc/imgproc.hpp”
#包括
使用名称空间cv;
使用名称空间std;
int main(){
cout我认为这是将kinect与OpenCV结合使用的最简单、最有效的方法
- 您不必使用with_OPENNI标志重建OpenCV:您只需要安装OPENNI(使用1.3.2.1-4版本进行测试)
- 不进行多余的内存复制或分配:只分配头,然后复制指向数据的指针
该代码允许您连续收集深度图像和彩色图像,但如果您只需要其中一个流,则可以自由选择不打开另一个流
这里是C++ + OpenCV API和MAT对象的代码:
#include <openni2/OpenNI.h>
#include <opencv2/opencv.hpp>
using namespace openni;
main()
{
OpenNI::initialize();
puts( "Kinect initialization..." );
Device device;
if ( device.open( openni::ANY_DEVICE ) != 0 )
{
puts( "Kinect not found !" );
return -1;
}
puts( "Kinect opened" );
VideoStream depth, color;
color.create( device, SENSOR_COLOR );
color.start();
puts( "Camera ok" );
depth.create( device, SENSOR_DEPTH );
depth.start();
puts( "Depth sensor ok" );
VideoMode paramvideo;
paramvideo.setResolution( 640, 480 );
paramvideo.setFps( 30 );
paramvideo.setPixelFormat( PIXEL_FORMAT_DEPTH_100_UM );
depth.setVideoMode( paramvideo );
paramvideo.setPixelFormat( PIXEL_FORMAT_RGB888 );
color.setVideoMode( paramvideo );
puts( "Réglages des flux vidéos ok" );
// If the depth/color synchronisation is not necessary, start is faster :
device.setDepthColorSyncEnabled( false );
// Otherwise, the streams can be synchronized with a reception in the order of our choice :
//device.setDepthColorSyncEnabled( true );
//device.setImageRegistrationMode( openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR );
VideoStream** stream = new VideoStream*[2];
stream[0] = &depth;
stream[1] = &color;
puts( "Kinect initialization completed" );
if ( device.getSensorInfo( SENSOR_DEPTH ) != NULL )
{
VideoFrameRef depthFrame, colorFrame;
cv::Mat colorcv( cv::Size( 640, 480 ), CV_8UC3, NULL );
cv::Mat depthcv( cv::Size( 640, 480 ), CV_16UC1, NULL );
cv::namedWindow( "RGB", CV_WINDOW_AUTOSIZE );
cv::namedWindow( "Depth", CV_WINDOW_AUTOSIZE );
int changedIndex;
while( device.isValid() )
{
OpenNI::waitForAnyStream( stream, 2, &changedIndex );
switch ( changedIndex )
{
case 0:
depth.readFrame( &depthFrame );
if ( depthFrame.isValid() )
{
depthcv.data = (uchar*) depthFrame.getData();
cv::imshow( "Depth", depthcv );
}
break;
case 1:
color.readFrame( &colorFrame );
if ( colorFrame.isValid() )
{
colorcv.data = (uchar*) colorFrame.getData();
cv::cvtColor( colorcv, colorcv, CV_BGR2RGB );
cv::imshow( "RGB", colorcv );
}
break;
default:
puts( "Error retrieving a stream" );
}
cv::waitKey( 1 );
}
cv::destroyWindow( "RGB" );
cv::destroyWindow( "Depth" );
}
depth.stop();
depth.destroy();
color.stop();
color.destroy();
device.close();
OpenNI::shutdown();
}
#包括
#包括
使用名称空间openni;
main()
{
OpenNI::初始化();
puts(“Kinect初始化…”);
装置装置;
if(device.open(openni::ANY_设备)!=0)
{
puts(“未找到Kinect!”);
返回-1;
}
看跌期权(“Kinect已打开”);
视频流的深度、颜色;
创建(设备、传感器和颜色);
color.start();
放置(“相机正常”);
创建(设备、传感器和深度);
depth.start();
放置(“深度传感器正常”);
视频模式;
paramvideo.setResolution(640480);
paramvideo.setFps(30);
paramvideo.setPixelFormat(像素格式深度100μm);
深度设置视频模式(paramvideo);
paramvideo.setPixelFormat(像素_格式_RGB888);
颜色。设置视频模式(paramvideo);
看跌期权(“流动性抵押贷款利率正常”);
//如果不需要深度/颜色同步,则启动速度更快:
device.setDepthColorSyncEnabled(错误);
//否则,流可以按照我们选择的顺序与接收同步:
//device.setDepthColorSyncEnabled(真);
//device.setImageRegistrationMode(openni::图像\u注册\u深度\u到颜色);
视频流**流=新视频流*[2];
流[0]=&深度;
流[1]=&color;
puts(“Kinect初始化完成”);
if(device.getSensorInfo(传感器深度)!=NULL)
{
视频帧参考深度帧、彩色帧;
cv::Mat colorcv(cv::大小(640480),cv_8UC3,空);
cv::Mat depthcv(cv::Size(640480),cv_16UC1,空);
cv::namedWindow(“RGB”,cv_窗口_自动调整大小);
cv::namedWindow(“深度”,cv_窗口_自动调整大小);
int-changedIndex;
while(device.isValid())
{
OpenNI::waitForAnyStream(stream、2和changedIndex);
开关(changedIndex)
{
案例0:
depth.readFrame(&depthFrame);
if(depthFrame.isValid())
{
depthcv.data=(uchar*)depthFrame.getData();
cv::imshow(“深度”,depthcv);
}
打破
案例1:
color.readFrame(&colorFrame);
if(colorFrame.isValid())
{
colorcv.data=(uchar*)colorFrame.getData();
cv::cvtColor(colorcv,colorcv,cv_BGR2RGB);
cv::imshow(“RGB”,彩色cv);
}
打破
违约:
puts(“检索流时出错”);
}
cv::waitKey(1);
}
cv::破坏窗口(“RGB”);
cv::破坏窗口(“深度”);
}
深度。停止();
破坏深度();
color.stop();
color.destroy();
设备。关闭();
OpenNI::shutdown();
}
对于那些喜欢将OpenCV的C API与IplImage结构结合使用的用户:
#include <openni2/OpenNI.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
using namespace openni;
main()
{
OpenNI::initialize();
puts( "Kinect initialization..." );
Device device;
if ( device.open( openni::ANY_DEVICE ) != 0 )
{
puts( "Kinect not found !" );
return -1;
}
puts( "Kinect opened" );
VideoStream depth, color;
color.create( device, SENSOR_COLOR );
color.start();
puts( "Camera ok" );
depth.create( device, SENSOR_DEPTH );
depth.start();
puts( "Depth sensor ok" );
VideoMode paramvideo;
paramvideo.setResolution( 640, 480 );
paramvideo.setFps( 30 );
paramvideo.setPixelFormat( PIXEL_FORMAT_DEPTH_100_UM );
depth.setVideoMode( paramvideo );
paramvideo.setPixelFormat( PIXEL_FORMAT_RGB888 );
color.setVideoMode( paramvideo );
puts( "Réglages des flux vidéos ok" );
// If the depth/color synchronisation is not necessary, start is faster :
device.setDepthColorSyncEnabled( false );
// Otherwise, the streams can be synchronized with a reception in the order of our choice :
//device.setDepthColorSyncEnabled( true );
//device.setImageRegistrationMode( openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR );
VideoStream** stream = new VideoStream*[2];
stream[0] = &depth;
stream[1] = &color;
puts( "Kinect initialization completed" );
if ( device.getSensorInfo( SENSOR_DEPTH ) != NULL )
{
VideoFrameRef depthFrame, colorFrame;
IplImage* colorcv = cvCreateImageHeader( cvSize( 640, 480 ), IPL_DEPTH_8U, 3 );
IplImage* depthcv = cvCreateImageHeader( cvSize( 640, 480 ), IPL_DEPTH_16U, 1 );
cvNamedWindow( "RGB", CV_WINDOW_AUTOSIZE );
cvNamedWindow( "Depth", CV_WINDOW_AUTOSIZE );
int changedIndex;
while( device.isValid() )
{
OpenNI::waitForAnyStream( stream, 2, &changedIndex );
switch ( changedIndex )
{
case 0:
depth.readFrame( &depthFrame );
if ( depthFrame.isValid() )
{
depthcv->imageData = (char*) depthFrame.getData();
cvShowImage( "Depth", depthcv );
}
break;
case 1:
color.readFrame( &colorFrame );
if ( colorFrame.isValid() )
{
colorcv->imageData = (char*) colorFrame.getData();
cvCvtColor( colorcv, colorcv, CV_BGR2RGB );
cvShowImage( "RGB", colorcv );
}
break;
default:
puts( "Error retrieving a stream" );
}
cvWaitKey( 1 );
}
cvReleaseImageHeader( &colorcv );
cvReleaseImageHeader( &depthcv );
cvDestroyWindow( "RGB" );
cvDestroyWindow( "Depth" );
}
depth.stop();
depth.destroy();
color.stop();
color.destroy();
device.close();
OpenNI::shutdown();
}
#包括
#包括
#包括
使用名称空间openni;
main()
{
OpenNI::初始化();
puts(“Kinect初始化…”);
装置装置;
if(device.open(openni::ANY_设备)!=0)
{
金牛