#include <mil.h>
#include <Windows.h>
#include "KinectCamera.h"
#if USE_REAL_CAMERA
#if (KINECT_CAMERA_VERSION == 1)
#pragma comment(lib, "Kinect10.lib")
#if _MSC_VER < 1600
#define static_assert(a, b)
#endif
#include "NuiApi.h"
static const NUI_IMAGE_RESOLUTION KINECT_COLOR_IMAGE_RESOLUTION = NUI_IMAGE_RESOLUTION_640x480;
static const NUI_IMAGE_RESOLUTION KINECT_DEPTH_IMAGE_RESOLUTION = NUI_IMAGE_RESOLUTION_640x480;
static const MIL_INT KINECT_COLOR_NB_FRAMES = 2;
static const MIL_INT KINECT_DEPTH_NB_FRAMES = 2;
static const MIL_INT KINECT_IR_NB_FRAMES = 2;
CKinectCamera::CKinectCamera(MIL_ID MilSystem)
: CKinectCameraBase(MilSystem)
{
if(FAILED(NuiCreateSensorByIndex(0, &m_pNuiSensor)))
m_SensorStatus = KINECT_CAMERA_NOT_OK;
}
CKinectCamera::~CKinectCamera()
{
CloseDown();
}
void CKinectCamera::ShutdownCamera()
{
if(m_pNuiSensor)
m_pNuiSensor->NuiShutdown();
if(m_pNuiSensor)
{
m_pNuiSensor->Release();
m_pNuiSensor = NULL;
}
}
MIL_INT CKinectCamera::InitCamera(ColorStreamTypeEnum ColorStreamType, bool UseDepth)
{
if(m_SensorStatus == KINECT_CAMERA_NOT_OK)
return m_SensorStatus;
m_ColorStreamType = ColorStreamType;
if(FAILED(m_pNuiSensor->NuiSetForceInfraredEmitterOff(!UseDepth)))
return KINECT_CAMERA_NOT_OK;
if(FAILED(m_pNuiSensor->NuiInitialize(NUI_INITIALIZE_FLAG_USES_COLOR + (UseDepth ? NUI_INITIALIZE_FLAG_USES_DEPTH : 0))))
return KINECT_CAMERA_NOT_OK;
if(FAILED(m_pNuiSensor->NuiImageStreamOpen(m_ColorStreamType == enColor? NUI_IMAGE_TYPE_COLOR : NUI_IMAGE_TYPE_COLOR_INFRARED,
KINECT_COLOR_IMAGE_RESOLUTION,
0,
KINECT_COLOR_NB_FRAMES,
m_NextColorFrameEvent,
&m_ColorStreamHandle)))
return KINECT_CAMERA_NOT_OK;
if(UseDepth)
{
if(FAILED(m_pNuiSensor->NuiImageStreamOpen(NUI_IMAGE_TYPE_DEPTH,
KINECT_DEPTH_IMAGE_RESOLUTION,
0,
KINECT_DEPTH_NB_FRAMES,
m_NextDepthFrameEvent,
&m_DepthStreamHandle)))
return KINECT_CAMERA_NOT_OK;
if(FAILED(NuiImageStreamSetImageFrameFlags(m_DepthStreamHandle, NUI_IMAGE_STREAM_FLAG_ENABLE_NEAR_MODE)))
return KINECT_CAMERA_NOT_OK;
}
return KINECT_CAMERA_OK;
}
void CKinectCamera::ProcessKinectBufferColor(MIL_DIG_HOOK_FUNCTION_PTR HookHandlerPtr, void* UserDataPtr)
{
if(m_ColorStreamType == enColor)
ProcessKinectBuffer(m_ColorStreamHandle, HookHandlerPtr, UserDataPtr, 3, 8+M_UNSIGNED, M_BGR32 + M_PACKED);
else
ProcessKinectBuffer(m_ColorStreamHandle, HookHandlerPtr, UserDataPtr, 1, 16+M_UNSIGNED, M_NULL);
}
void CKinectCamera::ProcessKinectBufferDepth(MIL_DIG_HOOK_FUNCTION_PTR HookHandlerPtr, void* UserDataPtr)
{
ProcessKinectBuffer(m_DepthStreamHandle, HookHandlerPtr, UserDataPtr, 1, 16+M_UNSIGNED, M_NULL);
}
void CKinectCamera::ProcessKinectBuffer(HANDLE NuiImageStream,
MIL_DIG_HOOK_FUNCTION_PTR HookHandlerPtr,
void* UserDataPtr,
MIL_INT NbBands,
MIL_INT Type,
MIL_INT Attribute)
{
NUI_IMAGE_FRAME NuiImageFrame;
NUI_LOCKED_RECT NuiLockedRect;
NUI_SURFACE_DESC NuiSurfaceDesc;
if(FAILED(m_pNuiSensor->NuiImageStreamGetNextFrame(NuiImageStream, 0, &NuiImageFrame)))
return;
NuiImageFrame.pFrameTexture->GetLevelDesc(0, &NuiSurfaceDesc);
NuiImageFrame.pFrameTexture->LockRect(0, &NuiLockedRect, NULL, 0);
MIL_ID MilKinectImage = MbufCreateColor(GetMilSystem(),
NbBands,
NuiSurfaceDesc.Width,
NuiSurfaceDesc.Height,
Type,
M_IMAGE + M_PROC + Attribute,
M_HOST_ADDRESS + M_PITCH_BYTE,
NuiLockedRect.Pitch,
(void**)(&NuiLockedRect.pBits),
M_NULL);
(*HookHandlerPtr)(0, MilKinectImage, UserDataPtr);
MbufFree(MilKinectImage);
NuiImageFrame.pFrameTexture->UnlockRect(0);
m_pNuiSensor->NuiImageStreamReleaseFrame(NuiImageStream, &NuiImageFrame);
}
#elif (KINECT_CAMERA_VERSION == 2)
#if _MSC_VER < 1700
#error Visual Studio 2012 or higher is required to use the Kinect 2.0 SDK
#endif
#pragma comment(lib, "Kinect20.lib")
#include "Kinect.h"
static const MIL_INT KINECT_COLOR_NB_FRAMES = 2;
static const MIL_INT KINECT_DEPTH_NB_FRAMES = 2;
static const MIL_INT KINECT_IR_NB_FRAMES = 2;
CKinectOneCamera::CKinectOneCamera(MIL_ID MilSystem)
: CKinectCameraBase(MilSystem)
{
if (FAILED(GetDefaultKinectSensor(&m_pKinectSensor)))
m_SensorStatus = KINECT_CAMERA_NOT_OK;
}
CKinectOneCamera::~CKinectOneCamera()
{
CloseDown();
}
void CKinectOneCamera::ShutdownCamera()
{
if (m_pKinectSensor)
m_pKinectSensor->Close();
if (m_pKinectSensor)
{
m_pKinectSensor->Release();
m_pKinectSensor = NULL;
}
}
MIL_INT CKinectOneCamera::InitCamera(ColorStreamTypeEnum ColorStreamType, bool UseDepth)
{
if (m_SensorStatus == KINECT_CAMERA_NOT_OK)
return m_SensorStatus;
m_ColorStreamType = ColorStreamType;
if (ColorStreamType == enColor)
{
IColorFrameSource* pColorFrameSource = NULL;
if (FAILED(m_pKinectSensor->get_ColorFrameSource(&pColorFrameSource)))
return KINECT_CAMERA_NOT_OK;
if (FAILED(pColorFrameSource->OpenReader(&m_ColorFrameReader)))
return KINECT_CAMERA_NOT_OK;
WAITABLE_HANDLE NextColorFrameWaitableEvent;
if (FAILED(m_ColorFrameReader->SubscribeFrameArrived(&NextColorFrameWaitableEvent)))
return KINECT_CAMERA_NOT_OK;
m_NextColorFrameEvent = (HANDLE)NextColorFrameWaitableEvent;
}
else if (ColorStreamType == enIR)
{
IInfraredFrameSource* pInfraredFrameSource = NULL;
if (FAILED(m_pKinectSensor->get_InfraredFrameSource(&pInfraredFrameSource)))
return KINECT_CAMERA_NOT_OK;
if (FAILED(pInfraredFrameSource->OpenReader(&m_IRFrameReader)))
return KINECT_CAMERA_NOT_OK;
WAITABLE_HANDLE NextColorFrameWaitableEvent;
if (FAILED(m_IRFrameReader->SubscribeFrameArrived(&NextColorFrameWaitableEvent)))
return KINECT_CAMERA_NOT_OK;
m_NextColorFrameEvent = (HANDLE)NextColorFrameWaitableEvent;
}
if (UseDepth)
{
IDepthFrameSource* pDepthFrameSource = NULL;
if (FAILED(m_pKinectSensor->get_DepthFrameSource(&pDepthFrameSource)))
return KINECT_CAMERA_NOT_OK;
if (FAILED(pDepthFrameSource->OpenReader(&m_DepthFrameReader)))
return KINECT_CAMERA_NOT_OK;
WAITABLE_HANDLE NextDepthFrameWaitableEvent;
if (FAILED(m_DepthFrameReader->SubscribeFrameArrived(&NextDepthFrameWaitableEvent)))
return KINECT_CAMERA_NOT_OK;
m_NextDepthFrameEvent = (HANDLE)NextDepthFrameWaitableEvent;
}
if (FAILED(m_pKinectSensor->Open()))
return KINECT_CAMERA_NOT_OK;
return KINECT_CAMERA_OK;
}
template void CKinectOneCamera::ProcessKinectBuffer<IColorFrameReader, IColorFrameArrivedEventArgs, IColorFrameReference, IColorFrame> (IColorFrameReader* FrameReader, HANDLE NextFrameEvent, MIL_DIG_HOOK_FUNCTION_PTR HookHandlerPtr, void* UserDataPtr, MIL_INT NbBands, MIL_INT Type, MIL_INT Attribute);
template void CKinectOneCamera::ProcessKinectBuffer<IInfraredFrameReader, IInfraredFrameArrivedEventArgs, IInfraredFrameReference, IInfraredFrame> (IInfraredFrameReader* FrameReader, HANDLE NextFrameEvent, MIL_DIG_HOOK_FUNCTION_PTR HookHandlerPtr, void* UserDataPtr, MIL_INT NbBands, MIL_INT Type, MIL_INT Attribute);
template void CKinectOneCamera::ProcessKinectBuffer<IDepthFrameReader, IDepthFrameArrivedEventArgs, IDepthFrameReference, IDepthFrame> (IDepthFrameReader* FrameReader, HANDLE NextFrameEvent, MIL_DIG_HOOK_FUNCTION_PTR HookHandlerPtr, void* UserDataPtr, MIL_INT NbBands, MIL_INT Type, MIL_INT Attribute);
template <>
void CKinectOneCamera::GetFrameData<IColorFrame>(IColorFrame* pFrame, void** ppFrameData)
{
UINT nBufferSize;
pFrame->AccessRawUnderlyingBuffer(&nBufferSize, reinterpret_cast<BYTE**>(ppFrameData));
}
template <class IFrame>
void CKinectOneCamera::GetFrameData(IFrame* pFrame, void** ppFrameData)
{
UINT nBufferSize;
pFrame->AccessUnderlyingBuffer(&nBufferSize, reinterpret_cast<UINT16**>(ppFrameData));
}
void CKinectOneCamera::ProcessKinectBufferColor(MIL_DIG_HOOK_FUNCTION_PTR HookHandlerPtr, void* UserDataPtr)
{
if (m_ColorStreamType == enColor)
ProcessKinectBuffer<IColorFrameReader, IColorFrameArrivedEventArgs, IColorFrameReference, IColorFrame>(m_ColorFrameReader, (HANDLE)m_NextColorFrameEvent, HookHandlerPtr, UserDataPtr, 3, 8 + M_UNSIGNED, M_YUV16 + M_PACKED);
else
ProcessKinectBuffer<IInfraredFrameReader, IInfraredFrameArrivedEventArgs, IInfraredFrameReference, IInfraredFrame>(m_IRFrameReader, (HANDLE)m_NextColorFrameEvent, HookHandlerPtr, UserDataPtr, 1, 16 + M_UNSIGNED, M_NULL);
}
void CKinectOneCamera::ProcessKinectBufferDepth(MIL_DIG_HOOK_FUNCTION_PTR HookHandlerPtr, void* UserDataPtr)
{
ProcessKinectBuffer<IDepthFrameReader, IDepthFrameArrivedEventArgs, IDepthFrameReference, IDepthFrame>(m_DepthFrameReader, (HANDLE)m_NextDepthFrameEvent, HookHandlerPtr, UserDataPtr, 1, 16 + M_UNSIGNED, M_NULL);
}
template <class IFrameReader, class IFrameArrivedEventArgs, class IFrameReference, class IFrame>
void CKinectOneCamera::ProcessKinectBuffer(IFrameReader* pFrameReader,
HANDLE NextFrameEvent,
MIL_DIG_HOOK_FUNCTION_PTR HookHandlerPtr,
void* UserDataPtr,
MIL_INT NbBands,
MIL_INT Type,
MIL_INT Attribute)
{
IFrameArrivedEventArgs* pFrameEventArgs = NULL;
pFrameReader->GetFrameArrivedEventData((WAITABLE_HANDLE)NextFrameEvent, &pFrameEventArgs);
IFrameReference* pFrameRef = NULL;
pFrameEventArgs->get_FrameReference(&pFrameRef);
IFrame* pFrame = NULL;
HRESULT hr = pFrameRef->AcquireFrame(&pFrame);
if (SUCCEEDED(hr))
{
IFrameDescription* pFrameDescription = NULL;
pFrame->get_FrameDescription(&pFrameDescription);
void* pFrameData = NULL;
GetFrameData(pFrame, &pFrameData);
int Width;
int Height;
unsigned int BytesPerPixels;
pFrameDescription->get_Width(&Width);
pFrameDescription->get_Height(&Height);
pFrameDescription->get_BytesPerPixel(&BytesPerPixels);
MIL_ID MilKinectImage = MbufCreateColor(GetMilSystem(),
NbBands,
Width,
Height,
Type,
M_IMAGE + M_PROC + Attribute,
M_HOST_ADDRESS + M_PITCH_BYTE,
BytesPerPixels * Width,
(void**)(&pFrameData),
M_NULL);
(*HookHandlerPtr)(0, MilKinectImage, UserDataPtr);
MbufFree(MilKinectImage);
pFrame->Release();
}
pFrameRef->Release();
}
#endif
#endif