个人

来源:互联网 发布:聚宝盆时时彩软件 编辑:程序博客网 时间:2024/04/25 22:02
// kinectstudy1.cpp : 定义控制台应用程序的入口点。
//


#include "stdafx.h"
#include <windows.h>
#include <iostream> 
#include <NuiApi.h>
#include <opencv2/opencv.hpp>




using namespace std;
using namespace cv;


int main(int argc, char *argv[])
{
Mat image;
image.create(480, 640, CV_8UC3);
//一般的图像文件格式使用的是 Unsigned 8bits吧,CvMat矩阵对应的参数类型就是CV_8UC1,CV_8UC2,CV_8UC3。
//(最后的1、2、3表示通道数,譬如RGB3通道就用CV_8UC3)


    //1、初始化NUI 
    HRESULT hr = NuiInitialize(NUI_INITIALIZE_FLAG_USES_COLOR); //NuiINitialize(DWORD dwFlags)括号中的参数是初始化nui中的哪些参数,这里是彩色图像数据;
//NUI_INITIALIZE_FLAG_USES_COLOR|NUI_INITIALIZE_FLAG_USES_SKELETON|NUI_INITIALIZE_FLAG_USES_DEPTH|NUI_INITIALIZE_FLAG_USES_AUDIO|NUI_INITIALIZE_FLAG_USES_COLOR以及最后一个NUI_INITIALIZE_DEFAULT_HARDWARE_THREAD初始化默认的硬件线程。
//在使用kinect的数据之前必须对其进行初始化。可以使用|符号,初始化集中将要用到的数据。

//hresult 》判断函数的执行结果
    if (FAILED(hr)) 
    { 
        cout<<"NuiInitialize failed"<<endl; 
        return hr; 
    } 


    //2、定义事件句柄 
//创建读取下一帧的信号事件句柄,控制KINECT是否可以开始读取下一帧数据
    HANDLE nextColorFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );//创建一个windows时间对象,创建成功则返回事件的句柄。
//CreatEven函数需要4个参数;设定为NULL的安全描述符;一个设定为TRUE的布尔值,因为应用程序将重置事件消息;一个未指定的事件消息初始状态的布尔值;一个空字符串,因为事件未命名。
    HANDLE colorStreamHandle = NULL; //保存图像数据流的句柄,用以提取数据 
 
    //3、打开KINECT设备的彩色图信息通道,并用colorStreamHandle保存该流的句柄,以便于以后读取
hr = NuiImageStreamOpen(NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_1280x960, 
0, 2, nextColorFrameEvent, &colorStreamHandle); 
//用这个函数打开kinect的彩色或深度图像的访问通道;包含6个参数:NUI_IMAGE_TYPE、NUI_IMAGE_RESOLUTION、DWORD dwImageFrameFlags、DWORD dwFrameLimit、HANDLE hNextFrameEvent、HANDLE *phStreamHandle;
//第一个参数选择 NUI_IMAGE_TYPE_COLOR 时,第二个参数还可以选择NUI_IMAGE_RESOLUTION_640x480;
//第一个参数选择 NUI_IMAGE_TYPE_DEPTH 时,第二个参数可选640x320;320x240;80x60
//第一个参数选择 NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX 时,第二个参数可以选择320x240;80x60
//第三个参数为0第四个为2不做解释API有说明。
    if( FAILED( hr ) )//判断是否提取正确 
    { 
        cout<<"Could not open color image stream video"<<endl; 
        NuiShutdown(); 
        return hr; 
    }
namedWindow("colorImage", CV_WINDOW_AUTOSIZE);
 
    //4、开始读取彩色图数据 
    while(1) 
    { 
        const NUI_IMAGE_FRAME * pImageFrame = NULL; 


//4.1、无限等待新的数据,等到后返回
        if (WaitForSingleObject(nextColorFrameEvent, INFINITE)==0) //第一个参数表示有数据就执行,第二个参数表示等待的时间,INFINITE表示无限等待;
        { 
//4.2、从刚才打开数据流的流句柄中得到该帧数据,读取到的数据地址存于pImageFrame
            hr = NuiImageStreamGetNextFrame(colorStreamHandle, 0, &pImageFrame); 
//这个函数表示从刚才打开的数据流的流句柄中得到该帧数据,读取的数据地址存放于pImageFrame(之前已经定义了);第二个参数表示延时的时间,为0表示立刻拿去数据。
if (FAILED(hr))
{
cout<<"Could not get color image"<<endl; 
NuiShutdown();
return -1;
}


INuiFrameTexture * pTexture = pImageFrame->pFrameTexture;//一个容纳图像帧数据的对象;
NUI_LOCKED_RECT LockedRect;//给缓冲区上锁;


//4.3、提取数据帧到LockedRect,它包括两个数据对象:pitch每行字节数,pBits第一个字节地址
//并锁定数据,这样当我们读数据的时候,kinect就不会去修改它
            pTexture->LockRect(0, &LockedRect, NULL, 0); 
//4.4、确认获得的数据是否有效
            if( LockedRect.Pitch != 0 ) 
            { 
//4.5、将数据转换为OpenCV的Mat格式
for (int i=0; i<image.rows; i++) 
                {
uchar *ptr = image.ptr<uchar>(i);  //第i行的指针

//每个字节代表一个颜色信息,直接使用uchar
                    uchar *pBuffer = (uchar*)(LockedRect.pBits) + i * LockedRect.Pitch;
                    for (int j=0; j<image.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]; 
                    } 

                imshow("colorImage", image); //显示图像 
            } 
            else 
            { 
                cout<<"Buffer length of received texture is bogus\r\n"<<endl; 
            }


//5、这帧已经处理完了,所以将其解锁
pTexture->UnlockRect(0);
            //6、释放本帧数据,准备迎接下一帧 
            NuiImageStreamReleaseFrame(colorStreamHandle, pImageFrame ); 
        } 
        if (cvWaitKey(20) == 27) 
            break; 
    } 
    //7、关闭NUI链接 
    NuiShutdown(); 
return 0;
}
0 0