//好久没有跟新了,这次带来多线程的代码
// Win32TestPure.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <windows.h>
#include <opencv2\opencv.hpp>
#include <mmsystem.h>
#include <assert.h>
#include <strsafe.h>
#include "NuiApi.h"
using namespace cv;
using namespace std;
#define COLOR_WIDTH 640
#define COLOR_HIGHT 480
#define DEPTH_WIDTH 320
#define DEPTH_HIGHT 240
#define SKELETON_WIDTH 640
#define SKELETON_HIGHT 480
#define CHANNEL 3
BYTE buf[DEPTH_WIDTH*DEPTH_HIGHT*CHANNEL];
int drawColor(HANDLE h);
int drawDepth(HANDLE h);
int drawSkeleton();
//-----------------------------------------------------------------------------------
HANDLE h1;
HANDLE h3;
HANDLE h5;
HANDLE h2;
HANDLE h4;
DWORD WINAPI VideoFunc(LPVOID pParam)
{
cout<<"video start!"<<endl;
while(TRUE)
{
if(WaitForSingleObject(h1,INFINITE)==WAIT_OBJECT_0)
{
drawColor(h2);
}
// Sleep(10);
cout<<"video"<<endl;
}
}
DWORD WINAPI DepthFunc(LPVOID pParam)
{
cout<<"depth start!"<<endl;
while(TRUE)
{
if(WaitForSingleObject(h3,INFINITE)==WAIT_OBJECT_0)
{
drawDepth(h4);
}
// Sleep(10);
cout<<"depth"<<endl;
}
}
DWORD WINAPI SkeletonFunc(LPVOID pParam)
{
// HANDLE h = (HANDLE)pParam;
cout<<"skeleton start!"<<endl;
while(TRUE)
{
if(WaitForSingleObject(h3,INFINITE)==WAIT_OBJECT_0)
drawSkeleton();
// Sleep(10);
cout<<"skeleton"<<endl;
}
}
//-----------------------------------------------------------------------------------
int drawColor(HANDLE h)
{
const NUI_IMAGE_FRAME * pImageFrame = NULL;
HRESULT hr = NuiImageStreamGetNextFrame( h, 0, &pImageFrame );
if( FAILED( hr ) )
{
cout<<"Get Color Image Frame Failed"<<endl;
return -1;
}
INuiFrameTexture * pTexture = pImageFrame->pFrameTexture;
NUI_LOCKED_RECT LockedRect;
pTexture->LockRect( 0, &LockedRect, NULL, 0 );
if( LockedRect.Pitch != 0 )
{
BYTE * pBuffer = (BYTE*) LockedRect.pBits;
Mat temp(COLOR_HIGHT,COLOR_WIDTH,CV_8UC4,pBuffer);
imshow("b",temp);
waitKey(1);
}
NuiImageStreamReleaseFrame( h, pImageFrame );
return 0;
}
int drawDepth(HANDLE h)
{
const NUI_IMAGE_FRAME * pImageFrame = NULL;
HRESULT hr = NuiImageStreamGetNextFrame( h, 0, &pImageFrame );
if( FAILED( hr ) )
{
cout<<"Get Depth Image Frame Failed"<<endl;
return -1;
}
INuiFrameTexture * pTexture = pImageFrame->pFrameTexture;
NUI_LOCKED_RECT LockedRect;
pTexture->LockRect( 0, &LockedRect, NULL, 0 );
if( LockedRect.Pitch != 0 )
{
USHORT * pBuff = (USHORT*) LockedRect.pBits;
for(int i=0;i<DEPTH_WIDTH*DEPTH_HIGHT;i++)
{
BYTE index = pBuff[i]&0x07;
USHORT realDepth = (pBuff[i]&0xFFF8)>>3;
BYTE scale = 255 - (BYTE)(256*realDepth/0x0fff);
buf[CHANNEL*i] = buf[CHANNEL*i+1] = buf[CHANNEL*i+2] = 0;
switch( index )
{
case 0:
buf[CHANNEL*i]=scale/2;
buf[CHANNEL*i+1]=scale/2;
buf[CHANNEL*i+2]=scale/2;
break;
case 1:
buf[CHANNEL*i]=scale;
break;
case 2:
buf[CHANNEL*i+1]=scale;
break;
case 3:
buf[CHANNEL*i+2]=scale;
break;
case 4:
buf[CHANNEL*i]=scale;
buf[CHANNEL*i+1]=scale;
break;
case 5:
buf[CHANNEL*i]=scale;
buf[CHANNEL*i+2]=scale;
break;
case 6:
buf[CHANNEL*i+1]=scale;
buf[CHANNEL*i+2]=scale;
break;
case 7:
buf[CHANNEL*i]=255-scale/2;
buf[CHANNEL*i+1]=255-scale/2;
buf[CHANNEL*i+2]=255-scale/2;
break;
}
}
Mat b(DEPTH_HIGHT,DEPTH_WIDTH,CV_8UC3,buf);
imshow("depth",b);
waitKey(1);
}
NuiImageStreamReleaseFrame( h, pImageFrame );
return 0;
}
int drawSkeleton()
{
NUI_SKELETON_FRAME SkeletonFrame;
cv::Point pt[20];
Mat skeletonMat=Mat(SKELETON_HIGHT,SKELETON_WIDTH,CV_8UC3,Scalar(0,0,0));
HRESULT hr = NuiSkeletonGetNextFrame( 0, &SkeletonFrame );
if( FAILED( hr ) )
{
cout<<"Get Skeleton Image Frame Failed"<<endl;
return -1;
}
bool bFoundSkeleton = false;
for( int i = 0 ; i < NUI_SKELETON_COUNT ; i++ )
{
if( SkeletonFrame.SkeletonData[i].eTrackingState == NUI_SKELETON_TRACKED )
{
bFoundSkeleton = true;
}
}
// Has skeletons!
if( bFoundSkeleton )
{
NuiTransformSmooth(&SkeletonFrame,NULL);
for( int i = 0 ; i < NUI_SKELETON_COUNT ; i++ )
{
if( SkeletonFrame.SkeletonData[i].eTrackingState == NUI_SKELETON_TRACKED )
{
for (int j = 0; j < NUI_SKELETON_POSITION_COUNT; j++)
{
float fx,fy;
NuiTransformSkeletonToDepthImage( SkeletonFrame.SkeletonData[i].SkeletonPositions[j], &fx, &fy );
pt[j].x = (int) ( fx * SKELETON_WIDTH )/320;
pt[j].y = (int) ( fy * SKELETON_HIGHT )/240;
circle(skeletonMat,pt[j],5,CV_RGB(255,0,0));
}
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_HEAD],pt[NUI_SKELETON_POSITION_SHOULDER_CENTER],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_SHOULDER_CENTER],pt[NUI_SKELETON_POSITION_SPINE],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_SPINE],pt[NUI_SKELETON_POSITION_HIP_CENTER],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_HAND_RIGHT],pt[NUI_SKELETON_POSITION_WRIST_RIGHT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_WRIST_RIGHT],pt[NUI_SKELETON_POSITION_ELBOW_RIGHT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_ELBOW_RIGHT],pt[NUI_SKELETON_POSITION_SHOULDER_RIGHT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_SHOULDER_RIGHT],pt[NUI_SKELETON_POSITION_SHOULDER_CENTER],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_SHOULDER_CENTER],pt[NUI_SKELETON_POSITION_SHOULDER_LEFT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_SHOULDER_LEFT],pt[NUI_SKELETON_POSITION_ELBOW_LEFT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_ELBOW_LEFT],pt[NUI_SKELETON_POSITION_WRIST_LEFT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_WRIST_LEFT],pt[NUI_SKELETON_POSITION_HAND_LEFT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_HIP_CENTER],pt[NUI_SKELETON_POSITION_HIP_RIGHT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_HIP_RIGHT],pt[NUI_SKELETON_POSITION_KNEE_RIGHT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_KNEE_RIGHT],pt[NUI_SKELETON_POSITION_ANKLE_RIGHT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_ANKLE_RIGHT],pt[NUI_SKELETON_POSITION_FOOT_RIGHT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_HIP_CENTER],pt[NUI_SKELETON_POSITION_HIP_LEFT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_HIP_LEFT],pt[NUI_SKELETON_POSITION_KNEE_LEFT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_KNEE_LEFT],pt[NUI_SKELETON_POSITION_ANKLE_LEFT],CV_RGB(0,255,0));
cv::line(skeletonMat,pt[NUI_SKELETON_POSITION_ANKLE_LEFT],pt[NUI_SKELETON_POSITION_FOOT_LEFT],CV_RGB(0,255,0));
}
}
}
imshow("skeleton",skeletonMat);
waitKey(1);
return 0;
}
int main(int argc,char * argv[])
{
//初始化NUI
HRESULT hr = NuiInitialize(NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX|NUI_INITIALIZE_FLAG_USES_COLOR|NUI_INITIALIZE_FLAG_USES_SKELETON);
if( hr != S_OK )
{
cout<<"NuiInitialize failed"<<endl;
return hr;
}
//打开KINECT设备的彩色图信息通道
h1 = CreateEvent( NULL, TRUE, FALSE, NULL );
h2 = NULL;
hr = NuiImageStreamOpen(NUI_IMAGE_TYPE_COLOR,NUI_IMAGE_RESOLUTION_640x480, 0, 2, h1, &h2);
if( FAILED( hr ) )
{
cout<<"Could not open image stream video"<<endl;
return hr;
}
h3 = CreateEvent( NULL, TRUE, FALSE, NULL );
h4 = NULL;
hr = NuiImageStreamOpen( NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX, NUI_IMAGE_RESOLUTION_320x240, 0, 2, h3, &h4);
if( FAILED( hr ) )
{
cout<<"Could not open depth stream video"<<endl;
return hr;
}
h5 = CreateEvent( NULL, TRUE, FALSE, NULL );
hr = NuiSkeletonTrackingEnable( h5, 0 );
if( FAILED( hr ) )
{
cout<<"Could not open skeleton stream video"<<endl;
return hr;
}
HANDLE hThread1,hThread2,hThread3;
hThread1 = CreateThread(NULL,0,VideoFunc,h2,0,NULL);
hThread2 = CreateThread(NULL,0,DepthFunc,h4,0,NULL);
hThread3 = CreateThread(NULL,0,SkeletonFunc,NULL,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
CloseHandle(hThread3);
Sleep(10000);
NuiShutdown();
return 0;
}
欢迎指正和交流~