kinect学习笔记1

来源:互联网 发布:js遍历所有a标签 编辑:程序博客网 时间:2024/05/20 11:34

6月回校才真正开始着手导师分配的kinect项目任务。在学习过程中先做一下简单的记录,有时间再完善。

1.kinect传感器构造与功能学习;
2.在官网下载kinect SDK v1.8
—— http://www.microsoft.com/en-us/kinectforwindows/develop/

并安装到默认路径C:\Program Files\Microsoft SDKs\Kinect


3.点击Developer Toolkit Browser v1.8.0后,可以参看实用的例程文档,

我下载学习了samples:c++中的ColorBasics-D2D例程,在vs2010中打开学习了一下代码之后,就可以接入kinect测试。

也可以在接入kinect后点击browser里的三角运行按钮直接看应用程序运行效果。

3.1.接入kinect,需要插入电源和usb接口,之后会自动安装驱动,成功后xbox360前面的灯是绿色。

3.2.运行程序,便可以看到kinect捕捉到的彩色图像。

4.学习编写简单的功能程序

主要参看博文:http://blog.csdn.net/zouxy09/article/details/8163265

博主共发相关文档8篇,每一篇都非常实用,我主要学习了利用kinect结合opencv显示彩色图和深度图显示的功能程序。

4.1新建

新建项目:MyFirstKinectApp,并添加c++文件,命名为MyFirstKinectApp.cpp,我稍微改写了博主笔记四和笔记五的代码,

#include <iostream> #include <NuiApi.h>#include <opencv2/opencv.hpp>using namespace std;using namespace cv;void getColorImage(HANDLE &colorEvent, HANDLE &colorStreamHandle, Mat &colorImage);void getDepthImage(HANDLE &depthEvent, HANDLE &depthStreamHandle, Mat &depthImage);int main(int argc, char *argv[]){Mat colorImage;//用cv创建的代表单帧的变量。colorImage.create(480, 640, CV_8UC3);Mat depthImage;depthImage.create(240, 320, CV_8UC3);//2、定义事件句柄 //创建读取下一帧的信号事件句柄,控制KINECT是否可以开始读取下一帧数据HANDLE colorEvent = CreateEvent( NULL, TRUE, FALSE, NULL );HANDLE depthEvent = CreateEvent( NULL, TRUE, FALSE, NULL );HANDLE colorStreamHandle = NULL; //保存图像数据流的句柄,用以提取数据HANDLE depthStreamHandle = NULL; //保存图像数据流的句柄,用以提取数据//1、初始化NUI HRESULT hr = NuiInitialize(NUI_INITIALIZE_FLAG_USES_COLOR | NUI_INITIALIZE_FLAG_USES_DEPTH); if (FAILED(hr)) { cout<<"NuiInitialize failed"<<endl; return hr; }  //3、打开KINECT设备的彩色图信息通道,并用colorStreamHandle保存该流的句柄,以便于以后读取hr = NuiImageStreamOpen(NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, 0, 4, colorEvent, &colorStreamHandle); if( FAILED( hr ) )//判断是否提取正确 { cout<<"Could not open color image stream video"<<endl; NuiShutdown(); return hr; }namedWindow("colorImage", CV_WINDOW_AUTOSIZE);hr = NuiImageStreamOpen(NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX, NUI_IMAGE_RESOLUTION_320x240, NULL, 2, depthEvent, &depthStreamHandle);if( FAILED( hr ) )//判断是否提取正确 { cout<<"Could not open color image stream video"<<endl; NuiShutdown(); return hr; }namedWindow("depthImage", CV_WINDOW_AUTOSIZE);//4、开始读取彩色图数据 while(1) { if(WaitForSingleObject(colorEvent, 0)==0) getColorImage(colorEvent, colorStreamHandle, colorImage); if(WaitForSingleObject(depthEvent, 0)==0) getDepthImage(depthEvent, depthStreamHandle, depthImage); imshow("colorImage", colorImage); imshow("depthImage", depthImage); if(cvWaitKey(1)==27) break; }//7、关闭NUI链接 NuiShutdown(); return 0;}void getColorImage(HANDLE &colorEvent, HANDLE &colorStreamHandle, Mat &colorImage){const NUI_IMAGE_FRAME *colorFrame = NULL; NuiImageStreamGetNextFrame(colorStreamHandle, 0, &colorFrame); INuiFrameTexture *pTexture = colorFrame->pFrameTexture;   NUI_LOCKED_RECT LockedRect; pTexture->LockRect(0, &LockedRect, NULL, 0);   if( LockedRect.Pitch != 0 ) { for (int i=0; i<colorImage.rows; i++) {uchar *ptr = colorImage.ptr<uchar>(i);  //第i行的指针//每个字节代表一个颜色信息,直接使用ucharuchar *pBuffer = (uchar*)(LockedRect.pBits) + i * LockedRect.Pitch;for (int j=0; j<colorImage.cols; j++) { ptr[3*j] = pBuffer[4*j];  //内部数据是4个字节,0-1-2是BGR,第4个现在未使用 ptr[3*j+1] = pBuffer[4*j+1]; ptr[3*j+2] = pBuffer[4*j+2]; } } } else { cout<<"捕捉色彩图像出现错误"<<endl; }pTexture->UnlockRect(0); NuiImageStreamReleaseFrame(colorStreamHandle, colorFrame );}void getDepthImage(HANDLE &depthEvent, HANDLE &depthStreamHandle, Mat &depthImage){const NUI_IMAGE_FRAME * depthFrame = NULL; NuiImageStreamGetNextFrame(depthStreamHandle, 0, &depthFrame); INuiFrameTexture * pTexture = depthFrame->pFrameTexture;NUI_LOCKED_RECT LockedRect;pTexture->LockRect(0, &LockedRect, NULL, 0); if( LockedRect.Pitch != 0 ) { for (int i=0; i<depthImage.rows; i++) {uchar *ptr =depthImage.ptr<uchar>(i);  //第i行的指针//深度图像数据含有两种格式,这里像素的低12位表示一个深度值,高4位未使用;//注意这里需要转换,因为每个数据是2个字节,存储的同上面的颜色信息不一样,uchar *pBufferRun = (uchar*)(LockedRect.pBits) + i * LockedRect.Pitch;USHORT * pBuffer = (USHORT*) pBufferRun;for (int j=0; j<depthImage.cols; j++) { ptr[j] = 255 - (uchar)(256 * pBuffer[j]/0x0fff);  //直接将数据归一化处理} } } else { cout<<"捕捉深度图像出现错误"<<endl; }pTexture->UnlockRect(0);NuiImageStreamReleaseFrame(depthStreamHandle, depthFrame); }

这样就能简单地同时显示彩色和深度图,必须说明,我改写的很少,博主的代码可读性很高,风格很清晰,并且博文有相关代码解释,有利于尽快入门。

4.2环境配置

我的开发平台:Win7 x86 + VS2010 + Kinect for Windows SDK v1.8 + OpenCV2.3.1

在项目-属性-配置属性-vc++目录中,包含目录中添加:

$(KINECTSDK10_DIR)\inc

D:\OpenCV2.3.1\build\include

D:\OpenCV2.3.1\build\include\opencv

D:\OpenCV2.3.1\build\include\opencv2

//简直太神奇!在包含目录中竟然是大小写区分的!!!刚刚才发现……涨姿势……

在库目录中添加:

$(KINECTSDK10_DIR)\lib\x86

D:\OpenCV2.3.1\build\x86\vc10\lib

在链接器-输入中,附加依赖库加:

opencv_highgui231d.lib
opencv_core231d.lib
opencv_video231d.lib
opencv_imgproc231d.lib
Kinect10.lib//这个很重要千万不要丢掉,否则kinect是不能用的。

至此环境配置完成。

现在就可以运行程序啦~





0 0