1.开发工具:Visual Studio 2010 + OpenCV2.3.0
使用的是Kinect SDK for Windows 1.7 版本
2.获取彩色图像代码
/*******************************************************************************
文件名称 : GetColorImageFromKinect.cpp 实现文件
文件描述 : 从Kinect获得彩色图像
版权声明 : Copyright (C) 2010-2013
作 者 :
创建时间 : 2013-07-05 17:26:15
修改历史 : 2013-07-05 17:26:15 1.00 初始版本
*******************************************************************************/
#include "stdafx.h"
#include <iostream>
#include "NuiSensorChooser.h"
#include <cv.h>
#include <highgui.h>
using namespace std;
using namespace cv;
//彩色图像处理相关时间和帧句柄
HANDLE g_pColorStreamHandle = INVALID_HANDLE_VALUE;
HANDLE g_hNextColorFrameEvent = INVALID_HANDLE_VALUE;
NuiSensorChooser* g_pSensorChooser = NULL; //kinect选择类
INuiSensor* g_pNuiSensor = NULL; //当前的kinect
HRESULT CreateFirstConnected();
void Update();
/*******************************************************************************
函数名称 : _tmain
函数描述 : 入口函数
输入参数 : N/A
输出参数 : N/A
返 回 值 : N/A
作 者 :
*******************************************************************************/
int _tmain(int argc, _TCHAR* argv[])
{
// new传感器选择类,找到一个有效的传感器
g_pSensorChooser = new NuiSensorChooser();
//news失败,则返回
if (!g_pSensorChooser)
{
return -1;
}
//如果有传感器冲突,解决冲突,并返回解决情况
DWORD dwChangeFlags;
HRESULT hr = g_pSensorChooser->TryResolveConflict(&dwChangeFlags);
if (SUCCEEDED(hr))
{
//连接Kinect并创建指定的传感器
if( !SUCCEEDED(CreateFirstConnected()))
{
return -1;
}
//处理kinect获得数据流
while(true)
{
Update();
if (waitKey(30) == 27)
{
break;
}
}
}
//释放内存
delete g_pSensorChooser;
g_pSensorChooser = NULL;
//关闭彩色事件
if (g_hNextColorFrameEvent != INVALID_HANDLE_VALUE)
{
CloseHandle(g_hNextColorFrameEvent);
}
SafeRelease(g_pNuiSensor);
return 0;
}
/*******************************************************************************
函数名称 : CreateFirstConnected
函数描述 : 连接Kinect并创建指定的传感器
输入参数 : N/A
输出参数 : N/A
返 回 值 : N/A
作 者 :
*******************************************************************************/
HRESULT CreateFirstConnected()
{
//初始化传感器类型,比如获得彩色图像,深度和骨骼
HRESULT hr = g_pSensorChooser->GetSensor(NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX | NUI_INITIALIZE_FLAG_USES_COLOR, &g_pNuiSensor);
if (SUCCEEDED(hr) && NULL != g_pNuiSensor)
{
//创建关联彩色图像事件
g_hNextColorFrameEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// 打开彩色图像流
hr = g_pNuiSensor->NuiImageStreamOpen(NUI_IMAGE_TYPE_COLOR,NUI_IMAGE_RESOLUTION_640x480,
NULL,4,g_hNextColorFrameEvent,&g_pColorStreamHandle);
}
else
{
ResetEvent(g_hNextColorFrameEvent);
}
if (NULL == g_pNuiSensor || FAILED(hr))
{
cout<<"No ready Kinect found!"<<endl;
return E_FAIL;
}
g_pNuiSensor->NuiSkeletonTrackingDisable();
return hr;
}
/*******************************************************************************
函数名称 : Update
函数描述 : 流更新并处理
输入参数 : N/A
输出参数 : N/A
返 回 值 : N/A
作 者 :
*******************************************************************************/
void Update()
{
if (NULL == g_pNuiSensor)
{
return;
}
Mat image;
image.create(480,640,CV_8UC4);
Mat colorImage;
colorImage.create(480,640,CV_8UC3);
//处理彩色图像
if ( WAIT_OBJECT_0 == WaitForSingleObject(g_hNextColorFrameEvent, 0) )
{
//彩色图像流程处理
HRESULT hr = S_OK;
NUI_IMAGE_FRAME imageFrame;
// 得到彩色图像帧信息
hr = g_pNuiSensor->NuiImageStreamGetNextFrame(g_pColorStreamHandle, 0, &imageFrame);
if (FAILED(hr))
{
return;
}
INuiFrameTexture * pTexture = imageFrame.pFrameTexture;
NUI_LOCKED_RECT LockedRect;
pTexture->LockRect(0, &LockedRect, NULL, 0);
if( LockedRect.Pitch != 0 )
{
//拷贝数据(方法1)
memcpy(image.data, LockedRect.pBits, LockedRect.size);
//方法2
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];
}
}
}
// 解锁
pTexture->UnlockRect(0);
// 释放
g_pNuiSensor->NuiImageStreamReleaseFrame(g_pColorStreamHandle, &imageFrame);
imshow("1",image);
imshow("2",colorImage);
}
}
将kinect彩色图像数据,有两种方法。见代码
3.提供NuiSensorChooser.h和NuiSensorChooser.cpp代码(是SDK里面例子的)
NuiSensorChooser.h
//------------------------------------------------------------------------------
// <copyright file="NuiSensorChooser.h" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
#pragma once
#include <Windows.h>
#include <string>
#include <vector>
#include <NuiApi.h>
/// <summary>
/// Sensor change type
/// </summary>
#define NUISENSORCHOOSER_NONE_CHANGED_FLAG 0x00000000
#define NUISENSORCHOOSER_SENSOR_CHANGED_FLAG 0x00000001
#define NUISENSORCHOOSER_STATUS_CHANGED_FLAG 0x00000002
/// <summary>
/// Sensor chooser status
/// </summary>
enum ChooserStatus
{
/// <summary>
/// Chooser has not been started or it has been stopped
///