kinect学习笔记1

本文详细介绍了如何在Win7环境下使用Microsoft提供的Kinect for Windows SDK v1.8与OpenCV库,实现从Kinect传感器获取彩色图像与深度图,并在Visual Studio 2010中展示这些图像的方法。通过新建项目,添加c++文件,以及调用SDK提供的API,读者可以学习到如何接入Kinect设备,读取图像数据,并将其以彩色和深度图的形式显示出来。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.youkuaiyun.com/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行的指针					
			//每个字节代表一个颜色信息,直接使用uchar
			uchar *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是不能用的。

至此环境配置完成。

现在就可以运行程序啦~





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值