ã¯ããã«
æè¿ãMicrosoftã¯KinectããŒã«ãããã®ããŒã¿çã§ããMicrosoft Research Kinect SDKããªãªãŒã¹ããŸããã ããŒã«ã«ã¯ãããããŒãã¡ã€ã«ãã©ã€ãã©ãªãããã³C ++ã¢ããªã±ãŒã·ã§ã³ã§ã®äœ¿çšäŸãå«ãŸããŠããŸãã ãã ããSDKèªäœãååšããã ãã§ã¯ãããããããäŸãããã¥ã¡ã³ãããªããšããåé¡ã¯è§£æ±ºããŸããã Microsoftã.NETéçºè
ã«ããéç¹ã眮ããŠããããšã¯æ³šç®ã«å€ããŸãããããã£ãŠãããšãã°å
¬åŒãã©ãŒã©ã ã§ã¯ããããã¯ã®å€§éšåã¯CïŒã«é¢é£ããŠãããKinectã®APIã®èª¬æãèŠã€ããããšããGoogleæ€çŽ¢ã¯ãããã€ãã®ãªã³ã¯ã®ã¿ãæäŸããŠããŸã-å
¬åŒããã¥ã¡ã³ããžã®ãªã³ã¯ã§ãã
ãã®èšäºã§ã¯ãMicrosoft Kinectã䜿çšããããã®ãªãã·ã§ã³ãããã³äžèšã®C ++ã¢ããªã±ãŒã·ã§ã³ã§wxWidgetsã©ã€ãã©ãªãšçµã¿åããããœãããŠã§ã¢ããŒã«ã«ã€ããŠèª¬æããŸãã
ã¯ããã«
éå§ããã«ã¯ãå°ãªããšãéçºããŒã«ãããŠã³ããŒãããå¿
èŠããããŸãã ããã¯ã
Microsoft Research Kinect SDKããŒãžã§å®è¡ã§ããŸãã
ãŸããwxWidgetsã©ã€ãã©ãªãå¿
èŠã§ãã
å
¬åŒWebãµã€ããŸãã¯
SVNãªããžããªããããŠã³ããŒãããããšãã§ã
ãŸã ïŒç§ã¯SVN HEADã奜ã¿
ãŸã -å
¬åŒãªãªãŒã¹ã«ã¯ãªãå€ãã®æ°ããæçšãªãã®ãå«ãŸããŠããŸããããã°ãé »ç¹ã«è¡šç€ºãããŸãïŒã
ãæãããåŽã奜ã¿ãç¡æã®ããŒã«ã®ã¿ã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãéçºããããšã«ç±å¿ãªå Žåã¯ã
Visual C ++ 2010 Express ãããã³
Windows 7 ïŒãŸãã¯ãã以éïŒ
çšã®
Microsoft Windows SDKãããŠã³ããŒããããããªãã§Visual C ++ Expressã§wxWidgetsãæ§ç¯ããã»ãšãã©ã®å Žå倱æããŸãã
wxWidgetsã®åé
Visual StudioãšKinect SDKã®ã€ã³ã¹ããŒã«ããã»ã¹ã¯èæ
®ããŸãããã€ã³ã¹ããŒã«ãŠã£ã¶ãŒãã®[次ãž]ãã¿ã³ãæ°åã¯ãªãã¯ããã ãã§ããããããwxWidgetsãã«ãããã»ã¹ããã詳现ã«èŠãŠãããŸãã ã¢ããªã±ãŒã·ã§ã³éçºã®æ¬¡ã®ã¹ãããã¯ããã«äŸåããŸãã
wxWidgetsãœãŒã¹ã³ãŒããããŠã³ããŒãããŠå¥ã®ãã©ã«ããŒã«è§£åãããã
WXWINç°å¢
å€æ°ãè¿œå ãããã®å€ã«wxWidgetsãœãŒã¹ã³ãŒããã©ã«ããŒãžã®ãã¹ã
æå®ããå¿
èŠããããŸãã
SVNã®ãœãŒã¹ã³ãŒãã䜿çšããå Žåã
ïŒ
WXWINïŒ
/ include / msw / setup0.hãã¡ã€ã«ã
ïŒ
WXWINïŒ
/ include / msw / setup.hã«ã³ããŒããå¿
èŠããããŸãã
ããã©ã«ãã§ã¯ãwxWidgetsã«ã¯ããã€ãã®æ§æããããŸãïŒå³1ïŒã
- ãããã°ãã
- ãªãªãŒã¹
- DLLãããã°
- DLLãªãªãŒã¹
æåã®2ã€ã®æ§æã§ã¯ãéçã©ã€ãã©ãªã®åœ¢åŒã§wxWidgetsãæ§ç¯ã§ããŸããåŸè
ã®å Žå-åçã«ããŒããããããã€ãã®ã¢ãžã¥ãŒã«ã®åœ¢åŒã§ã

éçã©ã€ãã©ãªã®æ§ç¯
éçã©ã€ãã©ãªïŒãããã°ããã³ãªãªãŒã¹æ§æïŒãçµã¿ç«ãŠãåã«ããœãªã¥ãŒã·ã§ã³å
ã®ãã¹ãŠã®ãããžã§ã¯ãã®ããããã£ã§ã
C / C ++->ã³ãŒãçæ->ã©ã³ã¿ã€ã ã©ã€ãã©ãªãã©ã¡ãŒã¿ãŒããããããã«ãã¹ã¬ãããããã°ãšãã«ãã¹ã¬ããã«èšå®ããŸãïŒå³2ïŒã

ãããã®ã³ã³ãã€ã«ãªãã·ã§ã³ãèšå®ãããšãã¢ããªã±ãŒã·ã§ã³ãšäžç·ã«ãšã³ããŠãŒã¶ãŒãã·ã³ã«Visual C ++ Redistributableãã€ã³ã¹ããŒã«ããå¿
èŠããªããªããŸãã ã³ã³ãã€ã«ãªãã·ã§ã³ãèšå®ãããããœãªã¥ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã çµæãšããŠãlib / vc_libãµããã£ã¬ã¯ããªã«ããã€ãã®.libãã¡ã€ã«ãäœæããå¿
èŠããããŸããããã¯ãåŸã§ã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšãããŸãã
åçã©ã€ãã©ãªãæ§ç¯ãã
åçã©ã€ãã©ãªãæ§ç¯ããã«ã¯ãã³ã³ãã€ã©èšå®ã§äœãå€æŽããå¿
èŠã¯ãããŸããã ãã ããå¥ã®åé¡ããããŸãããœãªã¥ãŒã·ã§ã³ã«ã¯äŸåé¢ä¿ããªãããããã«ãããã»ã¹ãæ°ååèµ·åããå¿
èŠããããŸãã äžéšã®ã©ã€ãã©ãªããªã³ã¯ãããšãšã©ãŒãçºçããŸãã ã¢ã»ã³ããªåŸãlib / vc_dllãµããã£ã¬ã¯ããªã«ããã€ãã®.DLLããã³.LIBãã¡ã€ã«ãäœæããå¿
èŠããããŸãã
ã©ã€ãã©ãªã®ããŒãžã§ã³ãåéïŒãããã°ïŒããã³ãããã°ããã³æé©åïŒãªãªãŒã¹ïŒããå¿
èŠãããããšã«æ³šæããŠãã ããã
ãã¹ãã¢ããªã±ãŒã·ã§ã³ãäœæãã
ãããã£ãŠãçŸæç¹ã§ã¯æ¬¡ã®ãšããã§ãã
- Visual Studio 2010
- Microsoft Research Kinect SDK
- ã³ã³ãã€ã«ãããwxWidgetsã©ã€ãã©ãª
ã¢ããªã±ãŒã·ã§ã³ã®äœæãéå§ã§ããŸãã
ãã¹ãã¢ããªã±ãŒã·ã§ã³ã«ã¯æ¬¡ã®ãã®ããããŸãã
- ã¢ããªã±ãŒã·ã§ã³ã¯ã©ã¹ïŒ
wxApp
ããwxApp
ïŒ - ã¡ã€ã³ãã©ãŒã ã¯ã©ã¹ïŒ
wxFrame
ããwxFrame
ïŒ - Canvasã¯ã©ã¹ïŒKinectã»ã³ãµãŒããã®ç»åã衚瀺ãã
wxWindow
ãã掟çããã³ã³ãããŒã«ïŒ
KinectTestApp.h#ifndef _KINECTTESTAPP_H_
#define _KINECTTESTAPP_H_
#include "wx/image.h"
#include "KinectTestMainFrame.h"
class KinectTestApp: public wxApp
{
DECLARE_CLASS( KinectTestApp )
DECLARE_EVENT_TABLE()
public :
KinectTestApp();
void Init();
virtual bool OnInit();
virtual int OnExit();
};
DECLARE_APP(KinectTestApp)
#endif
KinectTestApp.cpp...
bool KinectTestApp::OnInit()
{
#if wxUSE_LIBPNG
wxImage::AddHandler( new wxPNGHandler);
#endif
#if wxUSE_LIBJPEG
wxImage::AddHandler( new wxJPEGHandler);
#endif
KinectTestMainFrame* mainWindow = new KinectTestMainFrame( NULL );
mainWindow->Show( true );
return true ;
}
KinectTestMainFrame.hclass KinectTestMainFrame: public wxFrame, public wxThreadHelper
{
DECLARE_CLASS( KinectTestMainFrame )
DECLARE_EVENT_TABLE()
public :
KinectTestMainFrame();
KinectTestMainFrame( wxWindow* parent,
wxWindowID id = SYMBOL_KINECTTESTMAINFRAME_IDNAME,
const wxString& caption = SYMBOL_KINECTTESTMAINFRAME_TITLE,
const wxPoint& pos = SYMBOL_KINECTTESTMAINFRAME_POSITION,
const wxSize& size = SYMBOL_KINECTTESTMAINFRAME_SIZE,
long style = SYMBOL_KINECTTESTMAINFRAME_STYLE );
bool Create( wxWindow* parent,
wxWindowID id = SYMBOL_KINECTTESTMAINFRAME_IDNAME,
const wxString& caption = SYMBOL_KINECTTESTMAINFRAME_TITLE,
const wxPoint& pos = SYMBOL_KINECTTESTMAINFRAME_POSITION,
const wxSize& size = SYMBOL_KINECTTESTMAINFRAME_SIZE,
long style = SYMBOL_KINECTTESTMAINFRAME_STYLE );
~KinectTestMainFrame();
void Init();
void CreateControls();
wxBitmap GetBitmapResource( const wxString& name );
wxIcon GetIconResource( const wxString& name );
virtual wxThread::ExitCode Entry();
wxGridBagSizer* m_MainSizer;
wxListBox* m_DeviceListBox;
KinectCanvas* m_Canvas;
};
#endif
KinectTestMainFrame.cpp...
void KinectTestMainFrame::CreateControls()
{
KinectTestMainFrame* itemFrame1 = this ;
m_MainSizer = new wxGridBagSizer(0, 0);
m_MainSizer->SetEmptyCellSize(wxSize(10, 20));
itemFrame1->SetSizer(m_MainSizer);
wxArrayString m_DeviceListBoxStrings;
m_DeviceListBox = new wxListBox( itemFrame1,
ID_DEVICE_LISTBOX, wxDefaultPosition,
wxDefaultSize, m_DeviceListBoxStrings,
wxLB_SINGLE );
m_MainSizer->Add(m_DeviceListBox,
wxGBPosition(0, 0), wxGBSpan(1, 1),
wxGROW|wxGROW|wxALL, 5);
m_Canvas = new KinectCanvas( itemFrame1,
ID_KINECT_CANVAS, wxDefaultPosition,
wxSize(320, 240), wxSIMPLE_BORDER );
m_MainSizer->Add(m_Canvas, wxGBPosition(0, 1),
wxGBSpan(1, 1), wxALIGN_CENTER_HORIZONTAL|
wxALIGN_CENTER_VERTICAL|wxALL, 5);
m_MainSizer->AddGrowableCol(1);
m_MainSizer->AddGrowableRow(0);
}
...
wxThread::ExitCode KinectTestMainFrame::Entry()
{
return NULL;
}
KinectCanvas.h...
class KinectCanvas: public wxWindow
{
DECLARE_DYNAMIC_CLASS( KinectCanvas )
DECLARE_EVENT_TABLE()
public :
KinectCanvas();
KinectCanvas(wxWindow* parent,
wxWindowID id = ID_KINECTCANVAS,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxSize(100, 100),
long style = wxSIMPLE_BORDER);
bool Create(wxWindow* parent,
wxWindowID id = ID_KINECTCANVAS,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxSize(100, 100),
long style = wxSIMPLE_BORDER);
~KinectCanvas();
void Init();
void CreateControls();
void OnPaint( wxPaintEvent& event );
wxImage * GetCurrentImage() const { return m_CurrentImage ; }
void SetCurrentImage(wxImage * value ) { m_CurrentImage = value ; }
wxBitmap GetBitmapResource( const wxString& name );
wxIcon GetIconResource( const wxString& name );
wxImage * m_CurrentImage;
};
#endif
Kinectcanvas.cpp...
IMPLEMENT_DYNAMIC_CLASS( KinectCanvas, wxWindow )
BEGIN_EVENT_TABLE( KinectCanvas, wxWindow )
EVT_PAINT( KinectCanvas::OnPaint )
END_EVENT_TABLE()
...
void KinectCanvas::OnPaint( wxPaintEvent& event )
{
wxAutoBufferedPaintDC dc( this );
if (!m_CurrentImage)
{
dc.SetBackground(wxBrush(GetBackgroundColour(), wxSOLID));
dc.Clear();
dc.DrawLabel(_( "No image" ), wxRect(dc.GetSize()),
wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL);
}
else
{
wxBitmap bmp(*m_CurrentImage);
dc.DrawBitmap(bmp,
(dc.GetSize().GetWidth()-bmp.GetWidth())/2,
(dc.GetSize().GetHeight()-bmp.GetHeight())/2);
}
}
äžèšã®ãœãŒã¹ã³ãŒãã«ã¯ãããã€ãã®ç©ºã®ã¡ãœãããšãæ確ã§ã¯ãªãããã€ãã®ã¡ãœããããããŸãïŒããšãã°ã
GetIconResource()
ã
GetBitmapResource()
ã
Init()
ïŒã ããã¯ãã¹ãŠã
DialogBlocksãã©ãŒã ãã¶ã€ããã¢ããªã±ãŒã·ã§ã³ãã¬ãŒã ã¯ãŒã¯ã®äœæã«äœ¿çšãããããã§ãã ããã¯ææã®ããŒã«ã§ãããè©Šçšçã®æ©èœã§ã¢ããªã±ãŒã·ã§ã³ãäœæã§ããŸãã
ã¢ããªã±ãŒã·ã§ã³ããã«ãããåã«ãwxWidgetsãã«ããªãã·ã§ã³ãšäžèŽããããã«ãããžã§ã¯ãèšå®ãå€æŽããå¿
èŠããããŸãã ã€ãŸããéçwxWidgetsã©ã€ãã©ãªã䜿çšããå Žåã¯ã
C / C ++->ã³ãŒãçæ->ã©ã³ã¿ã€ã ã©ã€ãã©ãªãã©ã¡ãŒã¿ãŒã®ãããžã§ã¯ãããããã£ã§ããããã°ãšãªãªãŒã¹ã®æ§æã«åãå€ãèšå®ããå¿
èŠããããŸãã wxWidgetsãã€ãããã¯ã©ã€ãã©ãªã䜿çšããå¿
èŠãããå Žåã¯ã
C / C ++->ããªããã»ããµ->ããªããã»ããµå®çŸ©ãã©ã¡ãŒã¿ã®ãããžã§ã¯ãèšå®ã§ã
WXUSINGDLL
ãã¯ããè¿œå ããå¿
èŠããããŸãã ãã®ãã¯ãã¯ãåçãªwxWidgetsã©ã€ãã©ãªã®æ§ç¯ã«ã䜿çšãããããããããžã§ã¯ããšwxWidgetsã®èšå®ã¯äžèŽããŸãïŒå³3ïŒã

ãŸããã¢ããªã±ãŒã·ã§ã³ã®ãããã°ããŒãžã§ã³ã§ã¯ããªãœãŒã¹ã³ã³ãã€ã©èšå®ã®ããªããã»ããµãã£ã¬ã¯ãã£ãã«ãã¯ã
wxUSE_NO_MANIFEST=1
ãè¿œå ããå¿
èŠããããŸãã ããã¯ãwxWidgetsãªãœãŒã¹ãã¡ã€ã«ïŒ
ïŒ
WXWINïŒ
/ include / msw / wx.rc ïŒã§æå®ããããããã§ã¹ãããã³Visual Studioãã¢ããªã±ãŒã·ã§ã³ã«èªåçã«è¿œå ãããããã§ã¹ããšç«¶åããªãããšãä¿èšŒããããã§ãã
äžèšã®æé ãå®è¡ããåŸãã¢ããªã±ãŒã·ã§ã³ããã«ãã§ããŸãã ãã®çµæã次ã®ãããªçµæãåŸãããŸãïŒå³4ïŒã

Microsoft Research Kinect SDKã䜿çšãã
Kinect SDKãã€ã³ã¹ããŒã«ãããšãç°å¢å€æ°ïŒ
MSRKINECTSDKïŒ
ãã·ã¹ãã ã«è¡šç€ºãããSDKãã€ã³ã¹ããŒã«ããããã©ã«ããŒãžã®ãã¹ãå«ãŸããŸãã ãã®ãã©ã«ããŒã«ã¯ãããããŒãã¡ã€ã«ãå«ãincãµããã£ã¬ã¯ããªãšãã©ã€ãã©ãªãå«ãlibããããŸãã ããããŒãã¡ã€ã«ãžã®ãã¹ã¯ããã¹ãã¢ããªã±ãŒã·ã§ã³ã®ã³ã³ãã€ã©ãŒèšå®ããªã³ã«ãŒèšå®ãžã®ã©ã€ãã©ãªãŒãžã®ãã¹ã«è¿œå ããå¿
èŠããããŸãã
ããã€ã¹ã®ãªã¹ããååŸãã
çŸæç¹ã§ã¯ãåéããããã¹ãŠã®äŸåé¢ä¿ãšã¢ããªã±ãŒã·ã§ã³ãã³ãã¬ãŒãããããŸãã ããã§ãKinect SDKã䜿çšããŠã³ãŒããçŽæ¥æžãå§ããããšãã§ããŸãã
Kinect SDKã«ã¯ã1å°ã®ã³ã³ãã¥ãŒã¿ãŒã«æ¥ç¶ãããè€æ°ã®Kinectããã€ã¹ãæäœã§ããæ©èœããããŸãã ããã¯ãã¢ããªã±ãŒã·ã§ã³ãéçºããéã®ããæ®éçãªãœãªã¥ãŒã·ã§ã³ã§ãã å¿
èŠãªããã€ã¹ã®æ°ã¯äºåã«ããããŸããã ãããã£ãŠããã®ç¹å®ã®APIã䜿çšããããšãããæãŸããã§ãããã
ããã€ã¹ã®ãªã¹ããååŸããã«ã¯ã
MSR_NuiGetDeviceCount()
é¢æ°ã䜿çšããŸãããã®é¢æ°ã¯ãæŽæ°å€æ°ãžã®ãã€ã³ã¿ãŒããã©ã¡ãŒã¿ãŒãšããŠåãåããæåãããšã䜿çšå¯èœãªã»ã³ãµãŒã®æ°ãæžã蟌ãŸããŸãã
NUIAPI HRESULT MSR_NuiGetDeviceCount(
int * pCount
);
Kinectããã€ã¹ã«ã¯ããããåºæã®èå¥åããããããã¯
INuiInstance::MSR_NuiGetPropsBlob()
ã¡ãœããã䜿çšããŠååŸã§ããŸãã ãã®ã¡ãœããã¯ãã©ã¡ãŒã¿ãŒãšããŠåãåããŸãã
- ããããã£èå¥åïŒSDKã®ããŒã¿çã§ã¯ãå€ã1ã€ã ãæã€ããšãã§ããŸã
INDEX_UNIQUE_DEVICE_NAME
ïŒ - çµæãæžã蟌ãŸããå€æ°ãžã®ãã€ã³ã¿ãŒ
- çµæã®èšé²ã«äœ¿çšã§ããã¡ã¢ãªã®éïŒããšãã°ãè¡ã®é·ãïŒã SDKã®ããŒã¿çã¯ãã®ãã©ã¡ãŒã¿ãŒã䜿çšããŸããã
virtual bool MSR_NuiGetPropsBlob(
MsrNui::NUI_PROPSINDEX Index,
void * pBlob,
DWORD * pdwInOutSize
);
æ°ãã«ç¿åŸããç¥èã掻çšããŠãã¢ããªã±ãŒã·ã§ã³ã§ããã€ã¹ã®ãªã¹ãã®åä¿¡ãå®è£
ã§ããŸãã
wxKinectHelper.h#pragma once
#include <vector>
interface INuiInstance;
class KinectHelper
{
protected :
typedef std::pair<INuiInstance *, HANDLE> InstanceInfo;
typedef std::vector<InstanceInfo> InstanceVector;
public :
KinectHelper();
virtual ~KinectHelper();
size_t GetDeviceCount();
wxString GetDeviceName(size_t index);
bool IsDeviceOK(size_t deviceIndex);
protected :
InstanceVector m_Instances;
void Finalize();
InstanceInfo * GetInstanceByIndex(size_t index);
};
wxKinectHelper.cpp#include <wx/wx.h>
#include "msr_nuiapi.h"
#include "KinectHelper.h"
KinectHelper::KinectHelper()
{
}
KinectHelper::~KinectHelper()
{
Finalize();
}
size_t KinectHelper::GetDeviceCount()
{
int result(0);
if (FAILED(MSR_NUIGetDeviceCount(&result))) return 0;
return (size_t)result;
}
KinectHelper::InstanceInfo * KinectHelper::GetInstanceByIndex(size_t index)
{
INuiInstance * instance = NULL;
for (InstanceVector::iterator i = m_Instances.begin();
i != m_Instances.end(); i++)
{
instance = (*i).first;
if (instance->InstanceIndex() == ( int )index) return &(*i);
}
if (!instance)
{
if (!FAILED(MSR_NuiCreateInstanceByIndex(( int )index, &instance)))
{
InstanceInfo info;
info.first = instance;
info.second = NULL;
m_Instances.push_back(info);
return &(m_Instances.at(m_Instances.size()-1));
}
}
return NULL;
}
void KinectHelper::Finalize()
{
for (InstanceVector::const_iterator i = m_Instances.begin();
i != m_Instances.end(); i++)
{
if ((*i).first && (*i).second)
{
(*i).first->NuiShutdown();
MSR_NuiDestroyInstance((*i).first);
}
}
}
wxString KinectHelper::GetDeviceName(size_t index)
{
BSTR result;
DWORD size;
InstanceInfo * info = GetInstanceByIndex(index);
if (info != NULL)
{
INuiInstance * instance = info->first;
if (instance != NULL && instance->MSR_NuiGetPropsBlob(
MsrNui::INDEX_UNIQUE_DEVICE_NAME, &result, &size))
{
wxString name = result;
SysFreeString(result);
return name;
}
}
return wxT( "Unknown Kinect Sensor" );
}
bool KinectHelper::IsDeviceOK(size_t deviceIndex)
{
return GetInstanceByIndex(deviceIndex) != NULL;
}
InstanceInfo
æ§é ã«ã¯ã
INuiInstance
ã€ã³ã¹ã¿ã³ã¹ãžã®ãã€ã³ã¿ãå«ãŸããŠããŸããããã«ãããããã€ã¹ã®ååãšãã€ã¡ãŒãžããã£ããã£ãããã¹ããªãŒã ãžã®ãã³ãã«ãååŸã§ããŸãïŒåŸè¿°ïŒã
wxKinectHelper
ã¯ã©ã¹ã«ã¯ã
InstanceInfo
æ§é ã®ãã¯ãã«ãšãããã€ã¹ã®æ°ãšåããã€ã¹ã®ååãååŸããããã®ã¡ãœãããå«ãŸããŠããŸãã
wxKinectHelper
ã¯ã©ã¹ã®ãã¹ãã©ã¯ã¿ã§ã
Finalize()
ã¡ãœãããåŒã³åºãããéããŠãããã¹ãŠã®ç»åãã£ããã£ã¹ã¬ãããéãããã
INuiInstance
ãã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ãåé€ãããŸãã
次ã«ãããã€ã¹ã®ãªã¹ããååŸããæ©èœãã¢ããªã±ãŒã·ã§ã³ã«è¿œå ããå¿
èŠããããŸãã
wxKinectHelperMainFrame.h...
class KinectTestMainFrame: public wxFrame, public wxThreadHelper
{
...
void ShowDevices();
...
KinectHelper * m_KinectHelper;
}
...
wxKinectHelperMainFrame.cpp...
void KinectTestMainFrame::ShowDevices()
{
size_t count = m_KinectHelper->GetDeviceCount();
m_DeviceListBox->Clear();
for (size_t i = 0; i < count; ++i)
{
int item = m_DeviceListBox->Append(
m_KinectHelper->GetDeviceName(i));
m_DeviceListBox->SetClientData(item, ( void *)i);
}
}
ãã®çµæãã¢ããªã±ãŒã·ã§ã³ãèµ·åããåŸãå©çšå¯èœãªKinectããã€ã¹ã®ãªã¹ããååŸããŸãïŒå³5ïŒïŒ

Kinectã§ç»åãååŸãã
ããã€ã¹ããç»åã®ãã£ããã£ãéå§ããåã«ãåæåããå¿
èŠããããŸãã ããã¯
INuiInstance::NuiInitialize()
ã¡ãœããã䜿çšããŠè¡ãããŸãããã®ã¡ãœããã¯ã䜿çšããäºå®ã®ããã€ã¹ãµãã·ã¹ãã ïŒæ·±åºŠã»ã³ãµãŒãã«ã¡ã©ããŸãã¯ãããªäžã®ãã¬ãŒã€ãŒã®æ€çŽ¢ïŒã®ãªã¹ããèšè¿°ããããããã¹ã¯ããã©ã¡ãŒã¿ãŒãšããŠåãåããŸãã
HRESULT NuiInitialize(
DWORD dwFlags,
);
Kinectã§ç»åãåä¿¡ããã«ã¯ãç»åãã£ããã£ã¹ããªãŒã ãåæåããå¿
èŠããããŸãã ãããã®ç®çã®ããã«ã
INuiInstance:: NuiImageStreamOpen()
ã¡ãœããã䜿çšãããŸãã
- ç»åã¿ã€ãïŒã«ã©ãŒç»åã深床ãããã¡ãªã©ïŒ
- 解å床ïŒ80x60ãã1280x1024ïŒ
- ç»ååŠçãã©ã°ïŒSDKã®ããŒã¿çã§ã¯äœ¿çšãããŸããïŒ
- ãã£ãã·ã¥ããããã¬ãŒã ã®æ°ïŒ
NUI_IMAGE_STREAM_FRAME_LIMIT_MAXIMUM
ã®æ倧å€ã¯çŸåš4ã§ãïŒ - æ°ãããã¬ãŒã ãåä¿¡ããããšãã«çºçããã€ãã³ããžã®ãã³ãã«ïŒãªãã·ã§ã³ã®ãã©ã¡ãŒã¿ãŒããã ãã
NULL
ãæž¡ããšããã£ããã£ã¹ããªãŒã ãéå§ãããªãããšãå€æããŸããïŒ - é¢æ°ãæ£åžžã«å®äºãããšãã«ç»åãã£ããã£ã¹ããªãŒã ãžã®ãã³ãã«ãæžã蟌ãŸããå€æ°ãžã®ãã€ã³ã¿ãŒã
ããã€ã¹ããã®ç»åã®ãã£ããã£ãåæ¢ããã«ã¯ã
INuiInstance::NuiShutdown()
ã¡ãœãããåŒã³åºãå¿
èŠãããã
INuiInstance
ã€ã³ã¹ã¿ã³ã¹ã§ã®äœæ¥ãçµäºã
INuiInstance
ã
MSR_NuiDestroyInstance()
é¢æ°ã䜿çšããŠã
INuiInstance
ãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒãæž¡ããã©ã¡ãŒã¿ãŒã«ã¡ã¢ãªã解æŸ
INuiInstance
å¿
èŠããããŸãã
深床ãããã¡ã®ååŸ
深床ãããã¡ã®åä¿¡ãéå§ããã«ã¯ã
INuiInstance:: NuiImageStreamOpen()
ã¡ãœãããåŒã³åºããŠã
NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX
ãŸãã¯
NUI_IMAGE_TYPE_DEPTH
ãã©ã°ãå«ãå€ãæåã®ãã©ã¡ãŒã¿ãŒãšããŠ
NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX
å¿
èŠããããŸãã åŸç¶ã®åŠçã«æé©ãªãããã¡ãŒã¯ã
NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX
ãã©ã°ã䜿çšããŠ
NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX
ã ãœãŒã¹ã³ãŒãã§ã¯ãåæ§ã®åŒã³åºãã¯æ¬¡ã®ããã«ãªããŸãã
if (FAILED(info->first->NuiImageStreamOpen(NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX,
NUI_IMAGE_RESOLUTION_320x240, 0,
3,
hDepthFrameEvent,
&info->second))) { /* Handle error here */ }
äžèšã®åŒã³åºãã®çµæãå€æ°
info->second
ã¯ãç»åãã£ããã£ã¹ããªãŒã ãžã®ãã³ãã«ããããŸãã
hDepthFrameEvent
ã€ãã³ã
hDepthFrameEvent
ã¯ã
CreateEvent()
é¢æ°ã䜿çšããŠäœæã§ããŸãã
æ°ããç»åãå©çšå¯èœã«ãªããšã
hDepthFrameEvent
ã€ãã³ãã
hDepthFrameEvent
ãŸãã ãã®ã€ãã³ãã®åŸ
æ©ã¯ã
WaitForMultipleObjects()
ãŸãã¯
WaitForSingleObject()
é¢æ°ã䜿çšããŠå®è£
ã§ããŸãã
ãã©ã¡ãŒã¿ãŒãšããŠæž¡ãå¿
èŠããã
NuiImageStreamGetNextFrame()
ã¡ãœããã䜿çšããŠãããã€ã¹ãããããã¡ãŒèªäœãååŸã§ããŸãã
- ãã£ããã£ã¹ããªãŒã èšè¿°å
- ããªç§ã®ãããã¡ãŒåŸ
æ©æé
- åä¿¡ãããããã¡ãŒã«é¢ããæ
å ±ãæžã蟌ãŸããNUI_IMAGE_FRAMEæ§é äœãžã®ãã€ã³ã¿ãŒ
virtual HRESULT NuiImageStreamGetNextFrame(
_In_ HANDLE hStream,
_In_ DWORD dwMillisecondsToWait,
_Deref_out_ CONST NUI_IMAGE_FRAME **ppcImageFrame
);
çµæã®
NUI_IMAGE_FRAME
ã€ã³ã¹ã¿ã³ã¹
NUI_IMAGE_FRAME
ã¯ãçŸåšã
NuiImageBuffer *pFrameTexture
æãé¢å¿ããã
NuiImageBuffer *pFrameTexture
ã
ãããã¡ããŒã¿ãçŽæ¥æäœããã«ã¯ã
LockRect()
ã¡ãœãããåŒã³åºãå¿
èŠããããŸãã
LockRect()
ã¡ãœããã«
LockRect()
4ã€ã®ãã©ã¡ãŒã¿ãŒãããããã®ãã¡2ã€ã¯ããŒã¿çã®APIã§äœ¿çšãããŸãã
æåã®ãã©ã¡ãŒã¿ãŒãšããŠã0ã2çªç®ã®ãã©ã¡ãŒã¿ãŒãšããŠ
KINECT_LOCKED_RECT
æ§é äœãžã®ãã€ã³ã¿ãŒã«æž¡ãå¿
èŠããããŸãããã®ãã€ã³ã¿ãŒã«ã¯ãé¢æ°ãæ£åžžã«å®äºããåŸããããã¡ãŒãæäœããããã®ããŒã¿ãæžã蟌ãŸããŸãã
NULL
ã3çªç®ã®ãã©ã¡ãŒã¿ãŒãšããŠã0ã4çªç®ã®ãã©ã¡ãŒã¿ãŒãšããŠæž¡ã
NULL
ã
STDMETHODIMP LockRect(
UINT Level,
KINECT_LOCKED_RECT* pLockedRect,
CONST RECT* pRectUsuallyNull,
DWORD Flags
);
ããã«ã
KINECT_LOCKED_RECT
æ§é äœã§ã¯ã深床ããŒã¿ãçŽæ¥å«ã
pBits
ãã£ãŒã«ãã«é¢å¿ããããŸãã ãããã¡å
ã®åãã¯ã»ã«ã«ã¯ã2ãã€ããå²ãåœãŠãããŸãã
å
¬åŒãã©ãŒã©ã ã®FAQããå€æãããšãããŒã¿åœ¢åŒã¯æ¬¡ã®ãšããã§ãã
â¢
NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX
ãã©ã°ã䜿çšããå Žåã12åã®æäžäœãããã深床å€ã«å²ãåœãŠãããæ®ãã®3ãããããã¬ãŒã€ãŒã€ã³ããã¯ã¹ã«å²ãåœãŠãããæäžäœãããã¯äœ¿çšãããŸããã
â¢
NUI_INITIALIZE_FLAG_USES_DEPTH
ãã©ã°ã䜿çšããå Žåãäžäœ12ãããã深床å€ã«å²ãåœãŠãããæ®ãã¯äœ¿çšãããŸããã
ã°ã¬ãŒã®æ¿æ·¡ã§ç»åãååŸããã«ã¯ã0ã255ã®ç¯å²ã®å€ãååŸããããã«æ·±åºŠå€ãæ£èŠåããå¿
èŠããããŸãã次ã®ããã«å®è¡ã§ããŸãã
USHORT RealDepth = (s & 0xfff8) >> 3;
BYTE l = 255 - (BYTE)(256*RealDepth/0x0fff);
RGBQUAD q;
q.rgbRed = q.rgbBlue = q.rgbGreen = l;
return q;
åä¿¡ããã€ã¡ãŒãžã䜿çšããŠäœæ¥ãå®äºããã«ã¯ããããã¡ã«å²ãåœãŠãããã¡ã¢ãªã解æŸããå¿
èŠããããŸãã ããã¯ãã¹ããªãŒã èšè¿°åãš
NUI_IMAGE_FRAME
ã€ã³ã¹ã¿ã³ã¹ãžã®ãã€ã³ã¿ãŒã
NUI_IMAGE_FRAME
ãšããŠåã
NuiImageStreamReleaseFrame()
ã¡ãœããã䜿çšããŠ
NuiImageStreamReleaseFrame()
ã§ã
NUI_IMAGE_FRAME
ã
ç§ãã¡ãä»æã£ãŠãããã®ãèŠçŽããŸãããïŒ
- ãã£ããã£ãéå§ããã«ã¯ã
NuiInitialize()
ã¡ãœããã䜿çšããŠããã€ã¹ãåæåããå¿
èŠããããŸãã - 次ã«ã
NuiImageStreamOpen()
ã¡ãœããã䜿çšããŠãã£ããã£ã¹ããªãŒã ãéå§ããå¿
èŠããããŸãã - æ°ããç»åãåä¿¡ããããšããã®èšè¿°åã
NuiImageStreamOpen()
æž¡ãããã€ãã³ããçºçããŸãã - ã€ãã³ããåŒã³åºãããåŸã
NuiImageStreamGetNextFrame()
ã¡ãœããã䜿çšããŠãã¬ãŒã ãååŸã§ããŸãã - 次ã«ã
NuiImageBuffer::LockRect()
ã¡ãœããã䜿çšããŠãããã¡ãŒããã£ããã£ããŸãã - ãã®åŸããããã¡ãééããŠåãã¯ã»ã«ã®è²ãååŸãã深床å€ãæ£èŠåããŸãã
NuiImageStreamReleaseFrame()
ã¡ãœããã䜿çšããŠãããã¡ãNuiImageStreamReleaseFrame()
ãŸãã- ããã€ã¹ããã®ç»åã®ãã£ããã£ãåæ¢ããã«ã¯ã
NuiShutdown()
ã¡ãœããã䜿çšããŠNuiShutdown()
解é€ããå¿
èŠããããŸãã
ã§ã¯ãããããã¹ãŠãã©ã®ããã«å®è·µã§ããããèŠãŠã¿ãŸãããã
wxKinectHelper.hclass KinectHelper
{
...
const wxSize & GetFrameSize();
BYTE * CreateDataBuffer();
void FreeDataBuffer(BYTE * data);
size_t GetDataBufferLength();
bool StartGrabbing(size_t deviceIndex, HANDLE hDepthFrameEvent);
bool ReadKinectFrame(size_t deviceIndex, BYTE * data);
bool IsDeviceOK(size_t deviceIndex);
bool IsGrabbingStarted(size_t deviceIndex);
static RGBQUAD Nui_ShortToQuad_Depth( USHORT s );
protected :
InstanceVector m_Instances;
wxSize m_FrameSize;
...
};
wxKinectHelper.cpp...
void ReadLockedRect(KINECT_LOCKED_RECT & LockedRect, int w, int h, BYTE * data)
{
if ( LockedRect.Pitch != 0 )
{
BYTE * pBuffer = (BYTE*) LockedRect.pBits;
// draw the bits to the bitmap
USHORT * pBufferRun = (USHORT*) pBuffer;
for ( int y = 0 ; y < h ; y++ )
{
for ( int x = 0 ; x < w ; x++ )
{
RGBQUAD quad = KinectHelper::Nui_ShortToQuad_Depth( *pBufferRun );
pBufferRun++;
int offset = (w * y + x) * 3;
data[offset + 0] = quad.rgbRed;
data[offset + 1] = quad.rgbGreen;
data[offset + 2] = quad.rgbBlue;
}
}
}
}
...
BYTE * KinectHelper::CreateDataBuffer()
{
size_t length = GetDataBufferLength();
BYTE * result = (BYTE*)CoTaskMemAlloc(length);
memset(result, 0, length);
return result;
}
size_t KinectHelper::GetDataBufferLength()
{
return m_FrameSize.GetWidth() * m_FrameSize.GetHeight() * 3;
}
void KinectHelper::FreeDataBuffer(BYTE * data)
{
CoTaskMemFree((LPVOID)data);
}
void KinectHelper::Finalize()
{
for (InstanceVector::const_iterator i = m_Instances.begin();
i != m_Instances.end(); i++)
{
if ((*i).first && (*i).second)
{
(*i).first->NuiShutdown();
MSR_NuiDestroyInstance((*i).first);
}
}
}
bool KinectHelper::StartGrabbing(size_t deviceIndex, HANDLE hDepthFrameEvent)
{
do
{
InstanceInfo * info = GetInstanceByIndex(deviceIndex);
if (!info || !info->first) break ;
if (FAILED(info->first->NuiInitialize(
NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX))) break ;
if (FAILED(info->first->NuiImageStreamOpen(
NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX,
NUI_IMAGE_RESOLUTION_320x240, 0,
3,
hDepthFrameEvent,
&info->second))) break ;
}
while ( false );
return false ;
}
bool KinectHelper::IsDeviceOK(size_t deviceIndex)
{
return GetInstanceByIndex(deviceIndex) != NULL;
}
bool KinectHelper::IsGrabbingStarted(size_t deviceIndex)
{
InstanceInfo * info = GetInstanceByIndex(deviceIndex);
return (info != NULL && info->first != NULL && info->second != NULL);
}
bool KinectHelper::ReadKinectFrame(size_t deviceIndex, BYTE * data)
{
do
{
if (deviceIndex < 0) break ;
InstanceInfo * info = GetInstanceByIndex((size_t)deviceIndex);
if (!info || !info->second) break ;
const NUI_IMAGE_FRAME * pImageFrame;
if (FAILED(NuiImageStreamGetNextFrame(
info->second, 200, &pImageFrame))) break ;
NuiImageBuffer * pTexture = pImageFrame->pFrameTexture;
KINECT_LOCKED_RECT LockedRect;
pTexture->LockRect( 0, &LockedRect, NULL, 0 );
ReadLockedRect(LockedRect, m_FrameSize.GetWidth(),
m_FrameSize.GetHeight(), data);
NuiImageStreamReleaseFrame(info->second, pImageFrame);
return true ;
}
while ( false );
return false ;
}
RGBQUAD KinectHelper::Nui_ShortToQuad_Depth( USHORT s )
{
USHORT RealDepth = (s & 0xfff8) >> 3;
BYTE l = 255 - (BYTE)(256*RealDepth/0x0fff);
RGBQUAD q;
q.rgbRed = q.rgbBlue = q.rgbGreen = l;
return q;
}
KinectTestMainFrame.hclass KinectTestMainFrame: public wxFrame, public wxThreadHelper
{
...
void OnDEVICELISTBOXSelected( wxCommandEvent& event );
...
void ShowDevices();
void StopGrabbing();
HANDLE m_NewDepthFrameEvent;
KinectHelper * m_KinectHelper;
BYTE * m_pDepthBuffer;
wxImage * m_CurrentImage;
int m_SelectedDeviceIndex;
};
KinectTestMainFrame.cpp...
BEGIN_EVENT_TABLE( KinectTestMainFrame, wxFrame )
EVT_LISTBOX( ID_DEVICE_LISTBOX, KinectTestMainFrame::OnDEVICELISTBOXSelected )
END_EVENT_TABLE()
...
void KinectTestMainFrame::Init()
{
m_NewDepthFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_KinectHelper = new KinectHelper;
m_pDepthBuffer = m_KinectHelper->CreateDataBuffer();
m_CurrentImage = new wxImage(
m_KinectHelper->GetFrameSize().GetWidth(),
m_KinectHelper->GetFrameSize().GetHeight(),
m_pDepthBuffer, true );
m_SelectedDeviceIndex = -1;
m_MainSizer = NULL;
m_DeviceListBox = NULL;
m_Canvas = NULL;
}
...
KinectTestMainFrame::~KinectTestMainFrame()
{
StopGrabbing();
wxDELETE(m_CurrentImage);
m_KinectHelper->FreeDataBuffer(m_pDepthBuffer);
wxDELETE(m_KinectHelper);
}
...
wxThread::ExitCode KinectTestMainFrame::Entry()
{
while (!GetThread()->TestDestroy())
{
int mEventIndex = WaitForMultipleObjects(
1, &m_NewDepthFrameEvent, FALSE, 100);
switch (mEventIndex)
{
case 0:
{
wxCriticalSectionLocker lock (m_CS);
m_KinectHelper->ReadKinectFrame(
m_SelectedDeviceIndex, m_pDepthBuffer);
m_Canvas->Refresh();
}
break ;
default :
break ;
}
}
return NULL;
}
...
void KinectTestMainFrame::OnDEVICELISTBOXSelected( wxCommandEvent& event )
{
do
{
StopGrabbing();
size_t deviceIndex =
(size_t)m_DeviceListBox->GetClientData( event .GetInt());
if (deviceIndex < 0 || deviceIndex >
m_KinectHelper->GetDeviceCount()) break ;
m_SelectedDeviceIndex = deviceIndex;
if (!m_KinectHelper->IsDeviceOK(deviceIndex)) break ;
if (!m_KinectHelper->IsGrabbingStarted(deviceIndex))
{
m_KinectHelper->StartGrabbing(
deviceIndex, m_NewDepthFrameEvent);
if (CreateThread() != wxTHREAD_NO_ERROR) break ;
m_Canvas->SetCurrentImage(m_CurrentImage);
GetThread()->Run();
}
}
while ( false );
}
void KinectTestMainFrame::StopGrabbing()
{
if (GetThread())
{
if (GetThread()->IsAlive())
{
GetThread()->Delete();
}
if (m_kind == wxTHREAD_JOINABLE)
{
if (GetThread()->IsAlive())
{
GetThread()->Wait();
}
wxDELETE(m_thread);
}
else
{
m_thread = NULL;
}
}
}
ã¢ããªã±ãŒã·ã§ã³
wxKinectHelper
ãšã
wxKinectHelper
ãªããžã§ã¯ãã¯ã解å床ïŒ320x240x24ïŒã«å¿ããŠã深床ãããã¡ãŒã«ã¡ã¢ãªãå²ãåœãŠãŸãã 次ã«ãå²ãåœãŠãããã¡ã¢ãªé åãRGBãããã¡ãšããŠ
m_CurrentImage
ãªããžã§ã¯ãã«è»¢éãããŸãã
䜿çšå¯èœãªããã€ã¹ã®ãªã¹ãã§ããã€ã¹ã
m_CurrentImage
ãããšãããã€ã¹ããã®ç»åãã£ããã£ã¹ããªãŒã ãéå§ããã
m_CurrentImage
ãªããžã§ã¯ã
m_CurrentImage
ãã£ã³ãã¹ã«é¢é£ä»ããããŸãã
Entry()
ã¡ãœããã¯ãããã€ã¹ããã®æ°ããã€ã¡ãŒãžãåŸ
ã¡ãŸãã ç»åãå©çšå¯èœã«ãªããšãRGBãããã¡ãæ°ããå€ã§æºãããããã£ã³ãã¹ãåæç»ãããŸãã
ãã®çµæãã¢ããªã±ãŒã·ã§ã³ãèµ·åããŠãªã¹ãå
ã®ããã€ã¹åãã¯ãªãã¯ãããšã次ã®ãããªãã®ã衚瀺ãããŸãïŒå³6ïŒã

ã«ã¡ã©ããã«ã©ãŒç»åãååŸãã
ããã€ã¹ã®ã«ã¡ã©ããç»åãååŸããã«ã¯ã
NuiInitialize()
ã¡ãœãããåŒã³åºããšãã«
NUI_INITIALIZE_FLAG_USES_COLOR
ãã©ã°ãæå®ãã
NuiInitialize()
ã¡ãœãããåŒã³åºããšãã«å°ãªããšã640x480ã®è§£å床ãæå®ããå¿
èŠããããŸãã
ãã®çµæãã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
if (FAILED(info->first->NuiInitialize(
NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX|
NUI_INITIALIZE_FLAG_USES_COLOR))) break ;
if (FAILED(info->first->NuiImageStreamOpen(NUI_IMAGE_TYPE_COLOR,
NUI_IMAGE_RESOLUTION_640x480, 0,
3,
hDepthFrameEvent,
&info->second))) break ;
ãããã£ãŠã
KINECT_LOCKED_RECT
æ§é ã®ããŒã¿ã¯RGBA圢åŒã«å«ãŸããŠããŸãïŒSDKã§å©çšå¯èœãª
RGBQUAD
æ§é ã¯ãããŒã¿ã«ã¢ã¯ã»ã¹ããã®ã«éåžžã«é©ããŠããŸãïŒã ãããã£ãŠãRGBãããã¡ãŒãååŸããã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
if ( LockedRect.Pitch != 0 )
{
BYTE * pBuffer = (BYTE*) LockedRect.pBits;
for ( int y = 0 ; y < h ; y++ )
{
for ( int x = 0 ; x < w ; x++ )
{
RGBQUAD * quad = ((RGBQUAD*)pBuffer) + x;
int offset = (w * y + x) * 3;
data[offset + 0] = quad->rgbRed;
data[offset + 1] = quad->rgbGreen;
data[offset + 2] = quad->rgbBlue;
}
pBuffer += LockedRect.Pitch;
}
}
ãã¬ã€ã€ãŒã®äœçœ®ã®è¿œè·¡ïŒã¹ã±ã«ãã³ãã©ããã³ã°ïŒ
ãã¬ã€ã€ãŒã®ãã¹ã±ã«ãã³ãã®ã»ã°ã¡ã³ããååŸããŠè¡šç€ºããã¢ã«ãŽãªãºã ã¯ãéåžžã®ç»åãšã¯ç°ãªããŸãã
ã¹ã±ã«ãã³ã»ã°ã¡ã³ããååŸããå¯èœæ§ãæå¹ã«ããã«ã¯ã
NuiInitialize()
ã¡ãœãããå€
NUI_INITIALIZE_FLAG_USES_SKELETON
ãå«ããã©ã°ãæž¡ãã次ã«
NuiSkeletonTrackingEnable()
ã¡ãœãããåŒã³åºãå¿
èŠããããŸãã 2çªç®ã®ãã©ã¡ãŒã¿ãŒãšããŠãäžé£ã®ãã©ã°ïŒSDKã®ããŒã¿çã§ã¯ãã®ãã©ã¡ãŒã¿ãŒãç¡èŠãããããã0ãæž¡ãããšãã§ããŸãïŒã
ã¹ã±ã«ãã³ã»ã°ã¡ã³ãã®åä¿¡ãããŒãå®äºããã«ã¯ã
NuiSkeletonTrackingDisable()
ã¡ãœãããåŒã³åºãå¿
èŠããããŸãã
ã³ãŒãã§ã¯ã次ã®ããã«ãªããŸãã
if (FAILED(info->first->NuiSkeletonTrackingEnable(hSkeletonFrameEvent, 0)))
{ /* error */ };
ãã©ã¡ãŒã¿ãŒãšããŠ
NuiSkeletonGetNextFrame()
ã¡ãœããã䜿çšããŠããã¬ãŒã€ãŒã®äœçœ®ã«é¢ããæ
å ±ãå«ãããŒã¿ãããã¡ãŒãååŸã§ããŸãã
- ãããã¡ãŒåŸ
æ©æéïŒããªç§ïŒ
NUI_SKELETON_FRAME
æ§é äœãžã®ãã€ã³ã¿ãŒãé¢æ°ãæ£åžžã«å®äºããå ŽåãããŒã¿ãããã¡ãŒãžã®ãã€ã³ã¿ãŒãå«ãŸããŸãã
NuiSkeletonGetNextFrame()
ã¡ãœãããåŒã³åºããåŸãNUI_SKELETON_FRAMEæ§é äœã®ã€ã³ã¹ã¿ã³ã¹ãååŸããŸãã ãã£ãšè©³ããèŠãŠã¿ãŸãããã
struct _NUI_SKELETON_FRAME {
LARGE_INTEGER liTimeStamp;
DWORD dwFrameNumber;
DWORD dwFlags;
Vector4 vFloorClipPlane;
Vector4 vNormalToGravity;
NUI_SKELETON_DATA SkeletonData[NUI_SKELETON_COUNT];
} NUI_SKELETON_FRAME;
liTimeStamp
ã¹ã±ã«ãã³ã»ã°ã¡ã³ããååŸããã深床ãããã¡ãåä¿¡ããæ¥ä»\æéãdwFlag
ã¯ãã©ã°ãå«ãããããã¹ã¯ã§ããvFloorClipPlane
åºäžã®ãã¹ãŠãã¯ãªããããããã«äœ¿çšãããåºåº§æšïŒã©ã€ãã©ãªå
ã§èšç®ïŒãvNormalToGravity
æ³ç·ãã¯ãã«ãdwFrameNumber
ãã¬ãŒã çªå·ãSkeletonData
- NUI_SKELETON_DATA
æ§é ã®é
åãåæ§é ã«ã¯ã1人ã®ãã¬ãŒã€ãŒã®ã¹ã±ã«ãã³ã»ã°ã¡ã³ãã«é¢ããããŒã¿ãå«ãŸããŸãã
NUI_SKELETON_FRAME
æ§é äœã®èª¬æãã
NUI_SKELETON_FRAME
ããã«ãéãããæ°ã®ãã¬ãŒã€ãŒããµããŒããããŠããŸãïŒçŸåšã®SDKããŒãžã§ã³ã§ã¯ã
NUI_SKELETON_COUNT
ã®å€ã¯6ã§ãïŒã
ããã§ã
NUI_SKELETON_DATA
æ§é ãæ€èšã
NUI_SKELETON_DATA
ã
struct _NUI_SKELETON_DATA {
NUI_SKELETON_TRACKING_STATE eTrackingState;
DWORD dwTrackingID;
DWORD dwEnrollmentIndex;
DWORD dwUserIndex;
Vector4 Position;
Vector4 SkeletonPositions[NUI_SKELETON_POSITION_COUNT];
NUI_SKELETON_POSITION_TRACKING_STATE
eSkeletonPositionTrackingState[NUI_SKELETON_POSITION_COUNT];
DWORD dwQualityFlags;
} NUI_SKELETON_DATA;
eTrackingState
- NUI_SKELETON_TRACKING_STATE
åæããã®å€ã ãã¬ãŒã€ãŒãèŠã€ãããªãã£ãããšããã¬ãŒã€ãŒã®åº§æšã ããèŠã€ãã£ãïŒã¹ã±ã«ãã³ã»ã°ã¡ã³ããªãïŒããŸãã¯åº§æšãšã¹ã±ã«ãã³ã»ã°ã¡ã³ããèŠã€ãã£ãããšã瀺ããŸããdwEnrollmentIndex
ããã¥ã¡ã³ãïŒpã20ïŒããå€æãããšãçŸåšã®ããŒãžã§ã³ã§ã¯äœ¿çšãããŠããŸãããdwUserIndex
çŸåšã®SDKããŒãžã§ã³ã§ã¯ãåžžã«XUSER_INDEX_NONE
ãšçãããªãXUSER_INDEX_NONE
ãdwTrackingID
远跡ããããã¬ãŒã€ãŒã®çªå·ãPosition
-ãã¬ã€ã€ãŒã®åº§æšãSkeletonPositions
ã¹ã±ã«ãã³ã»ã°ã¡ã³ãã®ãžã§ã€ã³ãã®åº§æšã®ãªã¹ãeSkeletonPositionTrackingState
ã¹ã±ã«ãã³ã»ã°ã¡ã³ãã®ã¢ãŒãã£ãã¥ã¬ãŒã·ã§ã³ãèŠã€ãã£ããã©ããã瀺ããã©ã°ã®ãªã¹ãã
NUI_SKELETON_DATA
æ§é äœã®èª¬æãã
NUI_SKELETON_DATA
ããã«ããµããŒãããããžã§ã€ã³ããžã§ã€ã³ãã®æ°ã¯ã
NUI_SKELETON_POSITION_COUNT
çããæ°ã«ãã£ãŠå¶éãããŸãã
次ã«ãäžèšã®APIã䜿çšããŠãã¬ãŒã€ãŒã®åº§æšãååŸããå®è£
ãæ€èšããŸãã
KinectHelper.h...
struct KinectStreams
{
HANDLE hDepth;
HANDLE hColor;
HANDLE hSkeleton;
KinectStreams() : hDepth(NULL), hColor(NULL), hSkeleton(NULL) {}
};
...
KinectHelper.cppvoid KinectHelper::Finalize()
{
for (InstanceVector::const_iterator i = m_Instances.begin();
i != m_Instances.end(); i++)
{
if ((*i).first)
{
...
if ((*i).second.hSkeleton != NULL)
{
(*i).first->NuiSkeletonTrackingDisable();
}
MSR_NuiDestroyInstance((*i).first);
}
}
}
bool KinectHelper::StartGrabbing(size_t deviceIndex,
HANDLE hDepthFrameEvent,
HANDLE hColorFrameEvent,
HANDLE hSkeletonFrameEvent)
{
do
{
if (hDepthFrameEvent == NULL &&
hColorFrameEvent == NULL &&
hSkeletonFrameEvent == NULL) break ;
InstanceInfo * info = GetInstanceByIndex(deviceIndex);
if (!info || !info->first) break ;
if (FAILED(info->first->NuiInitialize(
NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX |
NUI_INITIALIZE_FLAG_USES_COLOR |
NUI_INITIALIZE_FLAG_USES_SKELETON))) break ;
...
if (hSkeletonFrameEvent != NULL)
{
if (FAILED(info->first->NuiSkeletonTrackingEnable(
hSkeletonFrameEvent, 0))) break ;
info->second.hSkeleton = hSkeletonFrameEvent;
}
}
while ( false );
return false ;
}
void * KinectHelper::ReadSkeletonFrame(size_t deviceIndex)
{
do
{
if (deviceIndex < 0) break ;
InstanceInfo * info = GetInstanceByIndex((size_t)deviceIndex);
if (!info || !info->second.hColor) break ;
NUI_SKELETON_FRAME * frame = new NUI_SKELETON_FRAME;
if (FAILED(info->first->NuiSkeletonGetNextFrame(200, frame))) break ;
return frame;
}
while ( false );
return NULL;
}
ãã¬ã€ã€ãŒã¹ã±ã«ãã³ã¬ã³ããªã³ã°
çŸæç¹ã§ã¯ã次ã®æ¹æ³ã«é¢ããæ
å ±ããããŸãã
- ãã¬ã€ã€ãŒã®äœçœ®ãååŸããããã«ããã€ã¹ãåæåããŸã
- ãã¬ã€ã€ãŒã®ãã£ããã£äœçœ®ã®ã¹ããªãŒã ãéå§ããŸã
- ãã¬ã€ã€ãŒã®ã¹ã±ã«ãã³ã»ã°ã¡ã³ãã®åº§æšãå«ããããã¡ãŒãååŸããŸã
- ãããã¡å
ã®ç®çã®ããŒã¿ãååŸããŸã
- ãã¬ãŒã€ãŒã®äœçœ®ãååŸãããããŒãåæ¢ããŸãã
ããã§ãã¢ããªã±ãŒã·ã§ã³ã§åä¿¡ããããŒã¿ãäœããã®æ¹æ³ã§è¡šç€ºããå¿
èŠããããŸãã
NUI_SKELETON_FRAME
ããŒã¿ã䜿çšããŠäœããè¡ãåã«ãããããååŠçã«éä¿¡ããå¿
èŠããããŸãã ååŠçã¯
NuiTransformSmooth()
ã¡ãœããã«ãã£ãŠå®è¡ãããŸã-
NuiTransformSmooth()
ãçªç¶ã®åããé¿ããããã«ãã»ã°ã¡ã³ãã®åº§æšããã£ã«ã¿ãªã³ã°ããŸãã ãã©ã¡ãŒã¿ãŒãšããŠã
NuiTransformSmooth()
ã¡ãœããã¯ã
NUI_SKELETON_FRAME
æ§é äœãžã®ãã€ã³ã¿ãŒãããã³ãªãã·ã§ã³ã§ãååŠçãã©ã¡ãŒã¿ãŒãå«ã
NUI_TRANSFORM_SMOOTH_PARAMETERS
ãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒã
NUI_TRANSFORM_SMOOTH_PARAMETERS
ãŸãã
HRESULT NuiTransformSmooth(
NUI_SKELETON_FRAME *pSkeletonFrame,
CONST NUI_TRANSFORM_SMOOTH_PARAMETERS *pSmoothingParams
);
ã¹ã±ã«ãã³ã»ã°ã¡ã³ãã衚瀺ããã«ã¯ããããã®åº§æšãç»å座æšã«å€æããå¿
èŠããããŸãã ããã¯ããã©ã¡ãŒã¿ãŒãšããŠ
NuiTransformSkeletonToDepthImageF()
ã¡ãœããã䜿çšããŠ
NuiTransformSkeletonToDepthImageF()
ã§ããŸãã
Vector4
æ§é ã®åœ¢åŒã§ã®ã¹ã±ã«ãã³ã»ã°ã¡ã³ãã®ãžã§ã€ã³ããã€ã³ãã®åº§æšã- X座æšãæžã蟌ãŸããå€æ°ãžã®ãã€ã³ã¿ãŒã
- Y座æšãæžã蟌ãŸããå€æ°ãžã®ãã€ã³ã¿ãŒã
VOID NuiTransformSkeletonToDepthImageF(
Vector4 vPoint,
_Out_ FLOAT *pfDepthX,
_Out_ FLOAT *pfDepthY
);
ãã¹ãŠã®ã¢ãŒãã£ãã¥ã¬ãŒã·ã§ã³ãã€ã³ãã®åº§æšãåãåã£ãããéåžžã®ã°ã©ãã£ãã¯ããªããã£ãã䜿çšããŠãããããã£ã³ãã¹ã«è¡šç€ºã§ããŸãã
ã¹ã±ã«ãã³ã»ã°ã¡ã³ãã衚瀺ããããã®å®éã®ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
SkeletonPainter.h#pragma once
#include <wx/wx.h>
class SkeletonPainterImpl;
class SkeletonPainter
{
public :
SkeletonPainter();
~SkeletonPainter();
void DrawSkeleton(wxDC & dc, void * data);
private :
SkeletonPainterImpl * m_Impl;
};
SkeletonPainter.cpp#include "SkeletonPainter.h"
#if defined(__WXMSW__)
#include "SkeletonPainterImplMSW.h"
#endif
SkeletonPainter::SkeletonPainter()
{
#if defined(__WXMSW__)
m_Impl = new SkeletonPainterImplMSW;
#else
m_Impl = NULL;
#endif
}
SkeletonPainter::~SkeletonPainter()
{
wxDELETE(m_Impl);
}
void SkeletonPainter::DrawSkeleton(wxDC & dc, void * data)
{
if (m_Impl)
{
m_Impl->DrawSkeleton(dc, data);
}
}
SkeletonPainterImpl.h#pragma once
#include <wx/wx.h>
class SkeletonPainterImpl
{
public :
virtual ~SkeletonPainterImpl() {}
virtual void DrawSkeleton(wxDC & dc, void * data) = 0;
};
SkeletonPainterImplMSW.h#pragma once
#include "SkeletonPainterImpl.h"
#include "msr_nuiapi.h"
class SkeletonPainterImplMSW : public SkeletonPainterImpl
{
public :
~SkeletonPainterImplMSW();
void DrawSkeleton(wxDC & dc, void * data);
private :
void Nui_DrawSkeleton(wxDC & dc, NUI_SKELETON_DATA * data, size_t index);
void Nui_DrawSkeletonSegment(wxDC & dc, wxPoint * points, int numJoints, ... );
static wxPen m_SkeletonPen[6];
};
SkeletonPainterImplMSW.cpp#include "SkeletonPainterImplMSW.h"
wxPen SkeletonPainterImplMSW::m_SkeletonPen[6] =
{
wxPen(wxColor(255, 0, 0), wxSOLID),
...
};
SkeletonPainterImplMSW::~SkeletonPainterImplMSW()
{
}
void SkeletonPainterImplMSW::DrawSkeleton(wxDC & dc, void * data)
{
do
{
NUI_SKELETON_FRAME * frame =
reinterpret_cast<NUI_SKELETON_FRAME*>(data);
if (!frame) break ;
int skeletonCount(0);
for ( int i = 0 ; i < NUI_SKELETON_COUNT ; i++ )
{
if ( frame->SkeletonData[i].eTrackingState ==
NUI_SKELETON_TRACKED )
{
skeletonCount++;
}
}
if (!skeletonCount) break ;
NuiTransformSmooth(frame, NULL);
for (size_t i = 0 ; i < NUI_SKELETON_COUNT ; i++ )
{
if (frame->SkeletonData[i].eTrackingState ==
NUI_SKELETON_TRACKED)
{
Nui_DrawSkeleton(dc, &frame->SkeletonData[i], i );
}
}
}
while ( false );
}
void SkeletonPainterImplMSW::Nui_DrawSkeleton(wxDC & dc,
NUI_SKELETON_DATA * data, size_t index)
{
wxPoint points[NUI_SKELETON_POSITION_COUNT];
float fx(0), fy(0);
wxSize imageSize = dc.GetSize();
for (size_t i = 0; i < NUI_SKELETON_POSITION_COUNT; i++)
{
NuiTransformSkeletonToDepthImageF(
data->SkeletonPositions[i], &fx, &fy);
points[i].x = ( int ) ( fx * imageSize.GetWidth() + 0.5f );
points[i].y = ( int ) ( fy * imageSize.GetHeight() + 0.5f );
}
Nui_DrawSkeletonSegment(dc,points,4,
NUI_SKELETON_POSITION_HIP_CENTER,
NUI_SKELETON_POSITION_SPINE,
NUI_SKELETON_POSITION_SHOULDER_CENTER,
NUI_SKELETON_POSITION_HEAD);
Nui_DrawSkeletonSegment(dc,points,5,
NUI_SKELETON_POSITION_SHOULDER_CENTER,
NUI_SKELETON_POSITION_SHOULDER_LEFT,
NUI_SKELETON_POSITION_ELBOW_LEFT,
NUI_SKELETON_POSITION_WRIST_LEFT,
NUI_SKELETON_POSITION_HAND_LEFT);
Nui_DrawSkeletonSegment(dc,points,5,
NUI_SKELETON_POSITION_SHOULDER_CENTER,
NUI_SKELETON_POSITION_SHOULDER_RIGHT,
NUI_SKELETON_POSITION_ELBOW_RIGHT,
NUI_SKELETON_POSITION_WRIST_RIGHT,
NUI_SKELETON_POSITION_HAND_RIGHT);
Nui_DrawSkeletonSegment(dc,points,5,
NUI_SKELETON_POSITION_HIP_CENTER,
NUI_SKELETON_POSITION_HIP_LEFT,
NUI_SKELETON_POSITION_KNEE_LEFT,
NUI_SKELETON_POSITION_ANKLE_LEFT,
NUI_SKELETON_POSITION_FOOT_LEFT);
Nui_DrawSkeletonSegment(dc,points,5,
NUI_SKELETON_POSITION_HIP_CENTER,
NUI_SKELETON_POSITION_HIP_RIGHT,
NUI_SKELETON_POSITION_KNEE_RIGHT,
NUI_SKELETON_POSITION_ANKLE_RIGHT,
NUI_SKELETON_POSITION_FOOT_RIGHT);
}
void SkeletonPainterImplMSW::Nui_DrawSkeletonSegment(wxDC & dc,
wxPoint * points, int numJoints, ...)
{
va_list vl;
va_start(vl,numJoints);
wxPoint segmentPositions[NUI_SKELETON_POSITION_COUNT];
for ( int iJoint = 0; iJoint < numJoints; iJoint++)
{
NUI_SKELETON_POSITION_INDEX jointIndex =
va_arg(vl,NUI_SKELETON_POSITION_INDEX);
segmentPositions[iJoint].x = points[jointIndex].x;
segmentPositions[iJoint].y = points[jointIndex].y;
}
dc.SetPen(*wxBLUE_PEN);
dc.DrawLines(numJoints, segmentPositions);
va_end(vl);
}
ã¢ããªã±ãŒã·ã§ã³ã§
SkeletonPainter
ã¯ã©ã¹ã䜿çšãããšã次ã®ããã«ãªããŸãã
KinectTestMainFrame.h...
class KinectTestMainFrame: public wxFrame, public wxThreadHelper
{
...
HANDLE m_NewSkeletonFrameEvent;
wxImage m_SkeletonImage;
...
};
...
KinectTestMainFrame.cpp...
wxThread::ExitCode KinectTestMainFrame::Entry()
{
HANDLE eventHandles[3];
eventHandles[0] = m_NewDepthFrameEvent;
eventHandles[1] = m_NewColorFrameEvent;
eventHandles[2] = m_NewSkeletonFrameEvent;
SkeletonPainter painter;
while (!GetThread()->TestDestroy())
{
int mEventIndex = WaitForMultipleObjects(
_countof(eventHandles), eventHandles, FALSE, 100);
switch (mEventIndex)
{
...
case 2:
{
void * frame = m_KinectHelper->ReadSkeletonFrame(
m_SelectedDeviceIndex);
if (frame)
{
wxBitmap bmp(
m_SkeletonImage.GetWidth(),
m_SkeletonImage.GetHeight());
wxMemoryDC dc(bmp);
painter.DrawSkeleton(dc, frame);
m_KinectHelper->ReleaseSkeletonFrame(frame);
dc.SelectObject(wxNullBitmap);
m_SkeletonImage = bmp.ConvertToImage();
m_SkeletonCanvas->Refresh();
}
}
break ;
default :
break ;
}
}
return NULL;
}
äžèšã®ã¢ã¯ã·ã§ã³ã®çµæã次ã®ãããªçµæãåŸãããŸãïŒå³7ïŒã

ã¢ããªã±ãŒã·ã§ã³å
ã®ãã©ãããã©ãŒã åºæã®ã³ãŒããåãé€ã
äžèšã®äŸã¯ããããžã§ã¯ããã¯ãã¹ãã©ãããã©ãŒã ã©ã€ãã©ãªã䜿çšããŠãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ãéçºããGUIã³ãŒãã®äžéšãWindowså°çšã®APIã䜿çšããŠèšè¿°ãããŠããããšãé€ããŠããã¹ãŠã®äººã«é©ããŠããŸãã
libfreenectã
OpenNIãªã©ãKinectãæäœããããã®ãµãŒãããŒãã£ã©ã€ãã©ãªãããã€ããããŸããããã§ã«ãã®æ®µéã§ãã¢ããªã±ãŒã·ã§ã³ã³ãŒããMicrosoftã®SDKã®äœ¿çšã«çµã³ä»ããããŠããç¶æ³ããããŸããã
ãã®è¿·æãªèª€è§£ã解決ããã«ã¯ãå¥ã®ã°ã©ããŒã¯ã©ã¹ã®ããã€ã¹ããç»åãåä¿¡ããããšã«é¢é£ããã³ãŒããåé€ãã
KinectHelper
ã¯ã©ã¹ã®æ©èœãããã€ã¹ã®ãªã¹ãã®åä¿¡ãšã°ã©ããŒã€ã³ã¹ã¿ã³ã¹ã®äœæã«å¶éããŸãã
KinectGrabberBase.h#pragma once
#include <wx/wx.h>
class KinectGrabberBase
{
public :
KinectGrabberBase(wxEvtHandler * handler);
virtual ~KinectGrabberBase();
virtual bool GrabDepthFrame(unsigned char * data) = 0;
virtual bool GrabColorFrame(unsigned char * data) = 0;
virtual void * GrabSkeletonFrame() = 0;
virtual bool Start() = 0;
virtual bool Stop() = 0;
virtual bool IsStarted() = 0;
const wxSize & GetDepthFrameSize();
const wxSize & GetColorFrameSize();
protected :
wxSize m_DepthFrameSize;
wxSize m_ColorFrameSize;
wxEvtHandler * m_Handler;
};
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_LOCAL_EVENT_TYPE(KINECT_DEPTH_FRAME_RECEIVED, -1)
DECLARE_LOCAL_EVENT_TYPE(KINECT_COLOR_FRAME_RECEIVED, -1)
DECLARE_LOCAL_EVENT_TYPE(KINECT_SKELETON_FRAME_RECEIVED, -1)
END_DECLARE_EVENT_TYPES()
KinectGrabberBase.cpp#include "KinectGrabberBase.h"
DEFINE_EVENT_TYPE(KINECT_DEPTH_FRAME_RECEIVED)
DEFINE_EVENT_TYPE(KINECT_COLOR_FRAME_RECEIVED)
DEFINE_EVENT_TYPE(KINECT_SKELETON_FRAME_RECEIVED)
...
KinectGrabberMSW.h#pragma once
#include "KinectGrabberBase.h"
#include "MSR_NuiApi.h"
class KinectGrabberMSW : public KinectGrabberBase, public wxThreadHelper
{
...
private :
virtual wxThread::ExitCode Entry();
BYTE * CreateDepthDataBuffer();
BYTE * CreateColorDataBuffer();
size_t GetDepthDataBufferLength();
size_t GetColorDataBufferLength();
void FreeDataBuffer(BYTE * data);
bool ReadDepthFrame();
bool ReadColorFrame();
bool ReadSkeletonFrame();
void ReadDepthLockedRect(KINECT_LOCKED_RECT & LockedRect,
int w, int h, BYTE * data);
void ReadColorLockedRect(KINECT_LOCKED_RECT & LockedRect,
int w, int h, BYTE * data);
static RGBQUAD Nui_ShortToQuad_Depth( USHORT s );
void ResetEvents();
void StopThread();
bool CopyLocalBuffer(BYTE * src, BYTE * dst, size_t count);
HANDLE m_NewDepthFrameEvent;
HANDLE m_NewColorFrameEvent;
HANDLE m_NewSkeletonFrameEvent;
HANDLE m_DepthStreamHandle;
HANDLE m_ColorStreamHandle;
BYTE * m_DepthBuffer;
BYTE * m_ColorBuffer;
INuiInstance * m_Instance;
size_t m_DeviceIndex;
NUI_SKELETON_FRAME m_SkeletonFrame;
};
KinectGrabberMSW.cpp#include "KinectGrabberMSW.h"
KinectGrabberMSW::KinectGrabberMSW(wxEvtHandler * handler, size_t deviceIndex)
: KinectGrabberBase(handler), m_DeviceIndex(deviceIndex), m_Instance(NULL)
{
m_DepthBuffer = CreateDepthDataBuffer();
m_ColorBuffer = CreateColorDataBuffer();
ResetEvents();
do
{
if (FAILED(MSR_NuiCreateInstanceByIndex(( int )m_DeviceIndex, &m_Instance))) break ;
if (FAILED(m_Instance->NuiInitialize(
NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX |
NUI_INITIALIZE_FLAG_USES_COLOR |
NUI_INITIALIZE_FLAG_USES_SKELETON))) break ;
}
while ( false );
}
...
void * KinectGrabberMSW::GrabSkeletonFrame()
{
do
{
if (!GetThread() || !GetThread()->IsAlive() ||
!m_Instance || !m_NewSkeletonFrameEvent) break ;
return &m_SkeletonFrame;
}
while ( false );
return NULL;
}
bool KinectGrabberMSW::Start()
{
do
{
if (!m_Instance) break ;
if (GetThread() && GetThread()->IsAlive()) break ;
if (CreateThread() != wxTHREAD_NO_ERROR) break ;
m_NewDepthFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_NewColorFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_NewSkeletonFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
if (FAILED(m_Instance->NuiImageStreamOpen(
NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX,
NUI_IMAGE_RESOLUTION_320x240, 0,
3,
m_NewDepthFrameEvent,
&m_DepthStreamHandle))) break ;
if (FAILED(m_Instance->NuiImageStreamOpen(NUI_IMAGE_TYPE_COLOR,
NUI_IMAGE_RESOLUTION_640x480, 0,
4,
m_NewColorFrameEvent,
&m_ColorStreamHandle))) break ;
if (FAILED(m_Instance->NuiSkeletonTrackingEnable(
m_NewSkeletonFrameEvent, 0))) break ;
GetThread()->Run();
return true ;
}
while ( false );
return false ;
}
...
wxThread::ExitCode KinectGrabberMSW::Entry()
{
HANDLE eventHandles[3];
eventHandles[0] = m_NewDepthFrameEvent;
eventHandles[1] = m_NewColorFrameEvent;
eventHandles[2] = m_NewSkeletonFrameEvent;
while (!GetThread()->TestDestroy())
{
int mEventIndex = WaitForMultipleObjects(
_countof(eventHandles), eventHandles, FALSE, 100);
switch (mEventIndex)
{
case 0: ReadDepthFrame(); break ;
case 1: ReadColorFrame(); break ;
case 2: ReadSkeletonFrame(); break ;
default :
break ;
}
}
return NULL;
}
...
void KinectGrabberMSW::StopThread()
{
if (GetThread())
{
if (GetThread()->IsAlive())
{
GetThread()->Delete();
}
if (m_kind == wxTHREAD_JOINABLE)
{
if (GetThread()->IsAlive())
{
GetThread()->Wait();
}
wxDELETE(m_thread);
}
else
{
m_thread = NULL;
}
}
wxYield();
}
bool KinectGrabberMSW::ReadDepthFrame()
{
do
{
if (m_DeviceIndex < 0 || !m_Instance) break ;
const NUI_IMAGE_FRAME * pImageFrame;
if (FAILED(NuiImageStreamGetNextFrame(
m_DepthStreamHandle, 200, &pImageFrame))) break ;
NuiImageBuffer * pTexture = pImageFrame->pFrameTexture;
KINECT_LOCKED_RECT LockedRect;
pTexture->LockRect( 0, &LockedRect, NULL, 0 );
ReadDepthLockedRect(LockedRect,
m_DepthFrameSize.GetWidth(),
m_DepthFrameSize.GetHeight(),
m_DepthBuffer);
NuiImageStreamReleaseFrame(m_DepthStreamHandle, pImageFrame);
if (m_Handler)
{
wxCommandEvent e(KINECT_DEPTH_FRAME_RECEIVED, wxID_ANY);
e.SetInt(m_DeviceIndex);
m_Handler->AddPendingEvent(e);
}
return true ;
}
while ( false );
return false ;
}
bool KinectGrabberMSW::ReadColorFrame()
{
do
{
if (m_DeviceIndex < 0 || !m_Instance) break ;
const NUI_IMAGE_FRAME * pImageFrame;
if (FAILED(NuiImageStreamGetNextFrame(
m_ColorStreamHandle, 200, &pImageFrame))) break ;
NuiImageBuffer * pTexture = pImageFrame->pFrameTexture;
KINECT_LOCKED_RECT LockedRect;
pTexture->LockRect( 0, &LockedRect, NULL, 0 );
ReadColorLockedRect(LockedRect,
m_ColorFrameSize.GetWidth(),
m_ColorFrameSize.GetHeight(),
m_ColorBuffer);
NuiImageStreamReleaseFrame(m_ColorStreamHandle, pImageFrame);
if (m_Handler)
{
wxCommandEvent e(KINECT_COLOR_FRAME_RECEIVED, wxID_ANY);
e.SetInt(m_DeviceIndex);
m_Handler->AddPendingEvent(e);
}
return true ;
}
while ( false );
return false ;
}
bool KinectGrabberMSW::ReadSkeletonFrame()
{
do
{
if (m_DeviceIndex < 0 || !m_Instance) break ;
if (FAILED(m_Instance->NuiSkeletonGetNextFrame(200, &m_SkeletonFrame))) break ;
if (m_Handler)
{
wxCommandEvent e(KINECT_SKELETON_FRAME_RECEIVED, wxID_ANY);
e.SetInt(m_DeviceIndex);
m_Handler->AddPendingEvent(e);
}
return true ;
}
while ( false );
return false ;
}
void KinectGrabberMSW::ReadDepthLockedRect(KINECT_LOCKED_RECT & LockedRect, int w, int h, BYTE * data)
{
if ( LockedRect.Pitch != 0 )
{
BYTE * pBuffer = (BYTE*) LockedRect.pBits;
USHORT * pBufferRun = (USHORT*) pBuffer;
for ( int y = 0 ; y < h ; y++ )
{
for ( int x = 0 ; x < w ; x++ )
{
RGBQUAD quad = KinectGrabberMSW::Nui_ShortToQuad_Depth( *pBufferRun );
pBufferRun++;
int offset = (w * y + x) * 3;
data[offset + 0] = quad.rgbRed;
data[offset + 1] = quad.rgbGreen;
data[offset + 2] = quad.rgbBlue;
}
}
}
}
void KinectGrabberMSW::ReadColorLockedRect(KINECT_LOCKED_RECT & LockedRect, int w, int h, BYTE * data)
{
if ( LockedRect.Pitch != 0 )
{
BYTE * pBuffer = (BYTE*) LockedRect.pBits;
for ( int y = 0 ; y < h ; y++ )
{
for ( int x = 0 ; x < w ; x++ )
{
RGBQUAD * quad = ((RGBQUAD*)pBuffer) + x;
int offset = (w * y + x) * 3;
data[offset + 0] = quad->rgbRed;
data[offset + 1] = quad->rgbGreen;
data[offset + 2] = quad->rgbBlue;
}
pBuffer += LockedRect.Pitch;
}
}
}
...
KinectHelper.h#pragma once
class KinectGrabberBase;
class KinectHelper
{
public :
KinectHelper();
~KinectHelper();
size_t GetDeviceCount();
wxString GetDeviceName(size_t index);
KinectGrabberBase * CreateGrabber(wxEvtHandler * handler, size_t index);
};
KinectHelper.cpp...
wxString KinectHelper::GetDeviceName(size_t index)
{
BSTR result;
DWORD size;
INuiInstance * instance(NULL);
wxString name = wxT( "Unknown Kinect Sensor" );
if (!FAILED(MSR_NuiCreateInstanceByIndex(index, &instance)))
{
if (instance != NULL)
{
if (instance->MSR_NuiGetPropsBlob(
MsrNui::INDEX_UNIQUE_DEVICE_NAME,
&result, &size))
{
name = result;
SysFreeString(result);
}
MSR_NuiDestroyInstance(instance);
}
}
return name;
}
KinectGrabberBase * KinectHelper::CreateGrabber(wxEvtHandler * handler, size_t index)
{
#if defined(__WXMSW__)
return new KinectGrabberMSW(handler, index);
#else
return NULL;
#endif
}
...
RGBãããã¡ã®ã¡ã¢ãªã®å²ãåœãŠãšãå¥ã®ã¹ããªãŒã ã§ç»åããã£ããã£ããããã®ã³ãŒãã¯ããã©ãŒã ã¯ã©ã¹ããåé€ã§ããŸãã ããã§ããã©ãŒã ã¯ã©ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
KinectTestMainFrame.hclass KinectTestMainFrame: public wxFrame
{
...
void OnDepthFrame(wxCommandEvent & event );
void OnColorFrame(wxCommandEvent & event );
void OnSkeletonFrame(wxCommandEvent & event );
...
wxImage m_CurrentImage;
int m_SelectedDeviceIndex;
wxImage m_ColorImage;
wxImage m_SkeletonImage;
KinectGrabberBase * m_Grabber;
...
};
KinectTestMainFrame.cpp...
BEGIN_EVENT_TABLE( KinectTestMainFrame, wxFrame )
...
EVT_COMMAND (wxID_ANY, KINECT_DEPTH_FRAME_RECEIVED, \
KinectTestMainFrame::OnDepthFrame)
EVT_COMMAND (wxID_ANY, KINECT_COLOR_FRAME_RECEIVED, \
KinectTestMainFrame::OnColorFrame)
EVT_COMMAND (wxID_ANY, KINECT_SKELETON_FRAME_RECEIVED, \
KinectTestMainFrame::OnSkeletonFrame)
END_EVENT_TABLE()
...
void KinectTestMainFrame::OnDEVICELISTBOXSelected( wxCommandEvent& event )
{
do
{
size_t deviceIndex =
(size_t)m_DeviceListBox->GetClientData( event .GetInt());
if (deviceIndex < 0 ||
deviceIndex > m_KinectHelper->GetDeviceCount()) break ;
m_SelectedDeviceIndex = deviceIndex;
StartGrabbing();
}
while ( false );
}
void KinectTestMainFrame::StartGrabbing()
{
StopGrabbing();
m_Grabber = m_KinectHelper->CreateGrabber( this , m_SelectedDeviceIndex);
m_CurrentImage = wxImage(
m_Grabber->GetDepthFrameSize().GetWidth(),
m_Grabber->GetDepthFrameSize().GetHeight());
m_ColorImage = wxImage(
m_Grabber->GetColorFrameSize().GetWidth(),
m_Grabber->GetColorFrameSize().GetHeight());
m_SkeletonImage = wxImage(
m_Grabber->GetDepthFrameSize().GetWidth(),
m_Grabber->GetDepthFrameSize().GetHeight());
m_DepthCanvas->SetCurrentImage(&m_CurrentImage);
m_ColorCanvas->SetCurrentImage(&m_ColorImage);
m_SkeletonCanvas->SetCurrentImage(&m_SkeletonImage);
if (!m_Grabber->Start())
{
StopGrabbing();
}
}
...
void KinectTestMainFrame::OnDepthFrame(wxCommandEvent & event )
{
do
{
if (!m_Grabber) break ;
m_Grabber->GrabDepthFrame(m_CurrentImage.GetData());
m_DepthCanvas->Refresh();
}
while ( false );
}
void KinectTestMainFrame::OnColorFrame(wxCommandEvent & event )
{
do
{
if (!m_Grabber) break ;
m_Grabber->GrabColorFrame(m_ColorImage.GetData());
m_ColorCanvas->Refresh();
}
while ( false );
}
void KinectTestMainFrame::OnSkeletonFrame(wxCommandEvent & event )
{
do
{
if (!m_Grabber) break ;
SkeletonPainter painter;
wxBitmap bmp(m_SkeletonImage.GetWidth(), m_SkeletonImage.GetHeight());
wxMemoryDC mdc(bmp);
painter.DrawSkeleton(mdc, m_Grabber->GrabSkeletonFrame());
mdc.SelectObject(wxNullBitmap);
m_SkeletonImage = bmp.ConvertToImage();
m_SkeletonCanvas->Refresh();
}
while ( false );
}
ã³ãŒããããããããã«ãã°ã©ããŒã¯ã©ã¹ã¯æ°ãããã¬ãŒã ãåä¿¡ãããšã
wxEvtHandler
ãªããžã§ã¯ãã«éç¥ãéä¿¡ããŸãïŒwxWidgetsã®
wxFrame
ã¯ã©ã¹ã¯
wxFrame
ãã掟çã
wxEvtHandler
ïŒã ãã©ãŒã ã«ã¯ãã°ã©ããŒããã®éç¥ãåä¿¡ãããšãã«åŒã³åºãããã€ãã³ããã³ãã©ãŒããããŸãã
KinectGrabberBase::GrabSkeletonFrame()
ã¡ãœããã
void*
è¿ãçç±ãéåžžã«åçŽã§ã-ããŸããŸãªSDKïŒéå
¬åŒã®ãã®ãå«ãïŒã䜿çšããŠç»åãã£ããã£ãå®è£
ããå Žåãããããã¹ãŠã®SDKããã¬ãŒã€ãŒã®äœçœ®ã«é¢ããæ
å ±ãåãåããšããäºå®ã§ã¯ãããŸããåäžã®ããŒã¿æ§é ã®åœ¢åŒã ãããã«ããŠãã座æšã¯åŸåŠçã®ããã«éä¿¡ããå¿
èŠããããŸãã ãã®å Žåãã°ã©ããŒãããã€ã³ã¿ãŒãåãåãã³ãŒãã¯ããããã©ã®ã¿ã€ãã®ããŒã¿ã«å€æãããå¿
èŠãããããèªåã§ç¥ã£ãŠããŸãã ã°ã©ãã£ã«ã«ã€ã³ã¿ãŒãã§ã€ã¹ã¯ãã°ã©ããŒã®å
éšæ§é ã«ã€ããŠç¥ãå¿
èŠã¯ãããŸããã
çµè«ãšããŠ
çµè«ãšããŠãMicrosoft SDKã¯ããŒã¿ç¶æ
ã§ãããKinect管çæ©èœã¯å®å
šã«ã¯å®è£
ãããŠããŸããããéåžžã«äœ¿çšå¯èœã§ãïŒããšãã°ãlibfreenectã§ã¯ãããã€ã¹äžã®LEDãšå
¬åŒSDKãããã¥ã¡ã³ãã«ãã£ãŠå€æã§ããŸãããã§ããŸããïŒã ã©ã€ãã©ãªã¯é©ãã»ã©å®å®ããŠåäœããŸãã éçºè
ãã¡ã¢ãªãªãŒã¯ãé¿ããããã«æ³šæãæã£ãããšã¯æ³šç®ã«å€ããŸãã ããšãã°ãçµäºæã«ã¹ããªãŒã ãéããã®ãå¿ããå ŽåãVisual Studioãããã¬ãŒã¯ã¡ã¢ãªãªãŒã¯ãå ±åããŸãããã»ãšãã©ã®å Žåããã¹ãŠãæ£ããçµäºããã©ã€ãã©ãªãã¢ã³ããŒãããããšã¡ã¢ãªããåé€ãããŸãã
ãã¹ãã¢ããªã±ãŒã·ã§ã³ãšã©ã€ãã©ãªã®ãœãŒã¹ã³ãŒãã¯ãGoogle Code-
wxKinectHelperã«ãããŸãã
ãããžã§ã¯ãã®éçºãšã°ã©ããŒã®æ°ããå®è£
ã®è¿œå ã楜ãã¿ã«ããŠããŸãã çŸåšãlibfreenectã飌ããªããããšããŠããŸãã ç®±ããåºããŠãäºåã®ã·ã£ãŒãããºã ãªãã§ãç»åãååŸããããšãé€ããŠãã¹ãŠãéå§ããããšãå¯èœã§ãã-LEDã€ã³ãžã±ãŒã¿ãç¹æ»
ãããšã³ãžã³ãå®å
šã«ãã¶ãŒããŸãã OpenNIã§ãåãããšãããããšããŠããŸãã
䟿å©ãªãªã³ã¯
Microsoft Research Kinect SDKKinect SDK
SDK
, Kinect SDK
C++ Kinect SDK ( ) , â .