全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > 医疗电子 >

基于Dragonboard 410c的kinect应用系列之四——获取人

时间:2017-02-21 10:29

人气:

作者:admin

标签: Kinect 

导读:基于Dragonboard 410c的kinect应用系列之四——获取人体骨骼图-在继《基于Dragonboard 410c的kinect应用系列之三——获取深度图》之后,今天我们来获取下人体的骨骼图。...

在继《基于Dragonboard 410c的kinect应用系列之三——获取深度图》之后,今天我们来获取下人体的骨骼图。

一、核心代码:

//------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //------------------------------------------------------------------------------   #include "stdafx.h" #include #include "SkeletonBasics.h" #include "resource.h"   static const float g_JointThickness = 3.0f; static const float g_TrackedBoneThickness = 6.0f; static const float g_InferredBoneThickness = 1.0f;   /// /// Entry point for the application /// /// handle to the application instance /// always 0 /// command line arguments /// whether to display minimized, maximized, or normally /// status int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { CSkeletonBasics application; application.Run(hInstance, nCmdShow); }   /// /// Constructor /// CSkeletonBasics::CSkeletonBasics() : m_pD2DFactory(NULL), m_hNextSkeletonEvent(INVALID_HANDLE_VALUE), m_pSkeletonStreamHandle(INVALID_HANDLE_VALUE), m_bSeatedMode(false), m_pRenderTarget(NULL), m_pBrushJointTracked(NULL), m_pBrushJointInferred(NULL), m_pBrushBoneTracked(NULL), m_pBrushBoneInferred(NULL), m_pNuiSensor(NULL) { ZeroMemory(m_Points,sizeof(m_Points)); }   /// /// Destructor /// CSkeletonBasics::~CSkeletonBasics() { if (m_pNuiSensor) { m_pNuiSensor->NuiShutdown(); }   if (m_hNextSkeletonEvent && (m_hNextSkeletonEvent != INVALID_HANDLE_VALUE)) { CloseHandle(m_hNextSkeletonEvent); }   // clean up Direct2D objects DiscardDirect2DResources();   // clean up Direct2D SafeRelease(m_pD2DFactory);   SafeRelease(m_pNuiSensor); }   /// /// Creates the main window and begins processing /// /// handle to the application instance /// whether to display minimized, maximized, or normally int CSkeletonBasics::Run(HINSTANCE hInstance, int nCmdShow) { MSG msg = {0}; WNDCLASS wc = {0};   // Dialog custom window class wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbWndExtra = DLGWINDOWEXTRA; wc.hInstance = hInstance; wc.hCursor = LoadCursorW(NULL, IDC_ARROW); wc.hIcon = LoadIconW(hInstance, MAKEINTRESOURCE(IDI_APP)); wc.lpfnWndProc = DefDlgProcW; wc.lpszClassName = L"SkeletonBasicsAppDlgWndClass";   if (!RegisterClassW(&wc)) { return 0; }   // Create main application window HWND hWndApp = CreateDialogParamW( hInstance, MAKEINTRESOURCE(IDD_APP), NULL, (DLGPROC)CSkeletonBasics::MessageRouter, reinterpret_cast<LPARAM>(this));   // Show window ShowWindow(hWndApp, nCmdShow);   const int eventCount = 1; HANDLE hEvents[eventCount]; // Main message loop while (WM_QUIT != msg.message) { hEvents[0] = m_hNextSkeletonEvent;   // Check to see if we have either a message (by passing in QS_ALLEVENTS) // Or a Kinect event (hEvents) // Update() will check for Kinect events individually, in case more than one are signalled MsgWaitForMultipleObjects(eventCount, hEvents, FALSE, INFINITE, QS_ALLINPUT);   // Explicitly check the Kinect frame event since MsgWaitForMultipleObjects // can return for other reasons even though it is signaled. Update();   while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { // If a dialog message will be taken care of by the dialog proc if ((hWndApp != NULL) && IsDialogMessageW(hWndApp, &msg)) { continue; }   TranslateMessage(&msg); DispatchMessageW(&msg); } }   return static_cast<int>(msg.wParam); }   /// /// Main processing function /// void CSkeletonBasics::Update() { if (NULL == m_pNuiSensor) { return; }   // Wait for 0ms, just quickly test if it is time to process a skeleton if ( WAIT_OBJECT_0 == WaitForSingleObject(m_hNextSkeletonEvent, 0) ) { ProcessSkeleton(); } }   /// /// Handles window messages, passes most to the class instance to handle /// /// window message is for /// message /// message data /// additional message data /// result of message processing LRESULT CALLBACK CSkeletonBasics::MessageRouter(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CSkeletonBasics* pThis = NULL;   if (WM_INITDIALOG == uMsg) { pThis = reinterpret_cast<CSkeletonBasics*>(lParam); SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pThis)); } else { pThis = reinterpret_cast<CSkeletonBasics*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA)); }   if (pThis) { return pThis->DlgProc(hWnd, uMsg, wParam, lParam); }   return 0; } /// /// Handle windows messages for the class instance /// /// window message is for /// message /// message data /// additional message data /// result of message processing LRESULT CALLBACK CSkeletonBasics::DlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: { // Bind application window handle m_hWnd = hWnd;   // Init Direct2D D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory);   // Look for a connected Kinect, and create it if found CreateFirstConnected(); } break;   // If the titlebar X is clicked, destroy app case WM_CLOSE: DestroyWindow(hWnd); break;   case WM_DESTROY: // Quit the main message pump PostQuitMessage(0); break;   // Handle button press case WM_COMMAND: // If it was for the near mode control and a clicked event, change near mode if (IDC_CHECK_SEATED == LOWORD(wParam) && BN_CLICKED == HIWORD(wParam)) { // Toggle out internal state for near mode m_bSeatedMode = !m_bSeatedMode;   if (NULL != m_pNuiSensor) { // Set near mode for sensor based on our internal state m_pNuiSensor->NuiSkeletonTrackingEnable(m_hNextSkeletonEvent, m_bSeatedMode ? NUI_SKELETON_TRACKING_FLAG_ENABLE_SEATED_SUPPORT : 0); } } break; }   return FALSE; }   /// /// Create the first connected Kinect found /// /// indicates success or failure HRESULT CSkeletonBasics::CreateFirstConnected() { INuiSensor * pNuiSensor;   int iSensorCount = 0; HRESULT hr = NuiGetSensorCount(&iSensorCount); if (FAILED(hr)) { return hr; }   // Look at each Kinect sensor for (int i = 0; i < iSensorCount; ++i) { // Create the sensor so we can check status, if we can't create it, move on to the next hr = NuiCreateSensorByIndex(i, &pNuiSensor); if (FAILED(hr)) { continue; }   // Get the status of the sensor, and if connected, then we can initialize it hr = pNuiSensor->NuiStatus(); if (S_OK == hr) { m_pNuiSensor = pNuiSensor; break; }   // This sensor wasn't OK, so release it since we're not using it pNuiSensor->Release(); }   if (NULL != m_pNuiSensor) { // Initialize the Kinect and specify that we'll be using skeleton hr = m_pNuiSensor->NuiInitialize(NUI_INITIALIZE_FLAG_USES_SKELETON); if (SUCCEEDED(hr)) { // Create an event that will be signaled when skeleton data is available m_hNextSkeletonEvent = CreateEventW(NULL, TRUE, FALSE, NULL);   // Open a skeleton stream to receive skeleton data hr = m_pNuiSensor->NuiSkeletonTrackingEnable(m_hNextSkeletonEvent, 0); } }   if (NULL == m_pNuiSensor || FAILED(hr)) { SetStatusMessage(L"No ready Kinect found!"); return E_FAIL; }   return hr; }   /// /// Handle new skeleton data /// void CSkeletonBasics::ProcessSkeleton() { NUI_SKELETON_FRAME skeletonFrame = {0};   HRESULT hr = m_pNuiSensor->NuiSkeletonGetNextFrame(0, &skeletonFrame); if ( FAILED(hr) ) { return; }   // smooth out the skeleton data m_pNuiSensor->NuiTransformSmooth(&skeletonFrame, NULL);   // Endure Direct2D is ready to draw hr = EnsureDirect2DResources( ); if ( FAILED(hr) ) { return; }   m_pRenderTarget->BeginDraw(); m_pRenderTarget->Clear( );   RECT rct; GetClientRect( GetDlgItem( m_hWnd, IDC_VIDEOVIEW ), &rct); int width = rct.right; int height = rct.bottom;   for (int i = 0 ; i < NUI_SKELETON_COUNT; ++i) { NUI_SKELETON_TRACKING_STATE trackingState = skeletonFrame.SkeletonData[i].eTrackingState;   if (NUI_SKELETON_TRACKED == trackingState) { // We're tracking the skeleton, draw it DrawSkeleton(skeletonFrame.SkeletonData[i], width, height); } else if (NUI_SKELETON_POSITION_ONLY == trackingState) { // we've only received the center point of the skeleton, draw that D2D1_ELLIPSE ellipse = D2D1::Ellipse( SkeletonToScreen(skeletonFrame.SkeletonData[i].Position, width, height), g_JointThickness, g_JointThickness );   m_pRenderTarget->DrawEllipse(ellipse, m_pBrushJointTracked); } }   hr = m_pRenderTarget->EndDraw();   // Device lost, need to recreate the render target // We'll dispose it now and retry drawing if (D2DERR_RECREATE_TARGET == hr) { hr = S_OK; DiscardDirect2DResources(); } }   /// /// Draws a skeleton /// /// skeleton to draw /// width (in pixels) of output buffer /// height (in pixels) of output buffer void CSkeletonBasics::DrawSkeleton(const NUI_SKELETON_DATA & skel, int windowWidth, int windowHeight) { int i;   for (i = 0; i < NUI_SKELETON_POSITION_COUNT; ++i) { m_Points[i] = SkeletonToScreen(skel.SkeletonPositions[i], windowWidth, windowHeight); }   // Render Torso DrawBone(skel, NUI_SKELETON_POSITION_HEAD, NUI_SKELETON_POSITION_SHOULDER_CENTER); DrawBone(skel, NUI_SKELETON_POSITION_SHOULDER_CENTER, NUI_SKELETON_POSITION_SHOULDER_LEFT); DrawBone(skel, NUI_SKELETON_POSITION_SHOULDER_CENTER, NUI_SKELETON_POSITION_SHOULDER_RIGHT); DrawBone(skel, NUI_SKELETON_POSITION_SHOULDER_CENTER, NUI_SKELETON_POSITION_SPINE); DrawBone(skel, NUI_SKELETON_POSITION_SPINE, NUI_SKELETON_POSITION_HIP_CENTER); DrawBone(skel, NUI_SKELETON_POSITION_HIP_CENTER, NUI_SKELETON_POSITION_HIP_LEFT); DrawBone(skel, NUI_SKELETON_POSITION_HIP_CENTER, NUI_SKELETON_POSITION_HIP_RIGHT);   // Left Arm DrawBone(skel, NUI_SKELETON_POSITION_SHOULDER_LEFT, NUI_SKELETON_POSITION_ELBOW_LEFT); DrawBone(skel, NUI_SKELETON_POSITION_ELBOW_LEFT, NUI_SKELETON_POSITION_WRIST_LEFT); DrawBone(skel, NUI_SKELETON_POSITION_WRIST_LEFT, NUI_SKELETON_POSITION_HAND_LEFT);   // Right Arm DrawBone(skel, NUI_SKELETON_POSITION_SHOULDER_RIGHT, NUI_SKELETON_POSITION_ELBOW_RIGHT); DrawBone(skel, NUI_SKELETON_POSITION_ELBOW_RIGHT, NUI_SKELETON_POSITION_WRIST_RIGHT); DrawBone(skel, NUI_SKELETON_POSITION_WRIST_RIGHT, NUI_SKELETON_POSITION_HAND_RIGHT);   // Left Leg DrawBone(skel, NUI_SKELETON_POSITION_HIP_LEFT, NUI_SKELETON_POSITION_KNEE_LEFT); DrawBone(skel, NUI_SKELETON_POSITION_KNEE_LEFT, NUI_SKELETON_POSITION_ANKLE_LEFT); DrawBone(skel, NUI_SKELETON_POSITION_ANKLE_LEFT, NUI_SKELETON_POSITION_FOOT_LEFT);   // Right Leg DrawBone(skel, NUI_SKELETON_POSITION_HIP_RIGHT, NUI_SKELETON_POSITION_KNEE_RIGHT); DrawBone(skel, NUI_SKELETON_POSITION_KNEE_RIGHT, NUI_SKELETON_POSITION_ANKLE_RIGHT); DrawBone(skel, NUI_SKELETON_POSITION_ANKLE_RIGHT, NUI_SKELETON_POSITION_FOOT_RIGHT);   // Draw the joints in a different color for (i = 0; i < NUI_SKELETON_POSITION_COUNT; ++i) { D2D1_ELLIPSE ellipse = D2D1::Ellipse( m_Points[i], g_JointThickness, g_JointThickness );   if ( skel.eSkeletonPositionTrackingState[i] == NUI_SKELETON_POSITION_INFERRED ) { m_pRenderTarget->DrawEllipse(ellipse, m_pBrushJointInferred); } else if ( skel.eSkeletonPositionTrackingState[i] == NUI_SKELETON_POSITION_TRACKED ) { m_pRenderTarget->DrawEllipse(ellipse, m_pBrushJointTracked); } } }   /// /// Draws a bone line between two joints /// /// skeleton to draw bones from /// joint to start drawing from /// joint to end drawing at void CSkeletonBasics::DrawBone(const NUI_SKELETON_DATA & skel, NUI_SKELETON_POSITION_INDEX joint0, NUI_SKELETON_POSITION_INDEX joint1) { NUI_SKELETON_POSITION_TRACKING_STATE joint0State = skel.eSkeletonPositionTrackingState[joint0]; NUI_SKELETON_POSITION_TRACKING_STATE joint1State = skel.eSkeletonPositionTrackingState[joint1];   // If we can't find either of these joints, exit if (joint0State == NUI_SKELETON_POSITION_NOT_TRACKED || joint1State == NUI_SKELETON_POSITION_NOT_TRACKED) { return; }   // Don't draw if both points are inferred if (joint0State == NUI_SKELETON_POSITION_INFERRED && joint1State == NUI_SKELETON_POSITION_INFERRED) { return; }   // We assume all drawn bones are inferred unless BOTH joints are tracked if (joint0State == NUI_SKELETON_POSITION_TRACKED && joint1State == NUI_SKELETON_POSITION_TRACKED) { m_pRenderTarget->DrawLine(m_Points[joint0], m_Points[joint1], m_pBrushBoneTracked, g_TrackedBoneThickness); } else { m_pRenderTarget->DrawLine(m_Points[joint0], m_Points[joint1], m_pBrushBoneInferred, g_InferredBoneThickness); } }   /// /// Converts a skeleton point to screen space /// /// skeleton point to tranform /// width (in pixels) of output buffer /// height (in pixels) of output buffer /// point in screen-space D2D1_POINT_2F CSkeletonBasics::SkeletonToScreen(Vector4 skeletonPoint, int width, int height) { LONG x, y; USHORT depth;   // Calculate the skeleton's position on the screen // NuiTransformSkeletonToDepthImage returns coordinates in NUI_IMAGE_RESOLUTION_320x240 space NuiTransformSkeletonToDepthImage(skeletonPoint, &x, &y, &depth);   float screenPointX = static_cast<float>(x * width) / cScreenWidth; float screenPointY = static_cast<float>(y * height) / cScreenHeight;   return D2D1::Point2F(screenPointX, screenPointY); }   /// /// Ensure necessary Direct2d resources are created /// /// S_OK if successful, otherwise an error code HRESULT CSkeletonBasics::EnsureDirect2DResources() { HRESULT hr = S_OK;   // If there isn't currently a render target, we need to create one if (NULL == m_pRenderTarget) { RECT rc; GetWindowRect( GetDlgItem( m_hWnd, IDC_VIDEOVIEW ), &rc );   int width = rc.right - rc.left; int height = rc.bottom - rc.top; D2D1_SIZE_U size = D2D1::SizeU( width, height ); D2D1_RENDER_TARGET_PROPERTIES rtProps = D2D1::RenderTargetProperties(); rtProps.pixelFormat = D2D1::PixelFormat( DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE); rtProps.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE; // Create a Hwnd render target, in order to render to the window set in initialize hr = m_pD2DFactory->CreateHwndRenderTarget( rtProps, D2D1::HwndRenderTargetProperties(GetDlgItem( m_hWnd, IDC_VIDEOVIEW), size), &m_pRenderTarget ); if ( FAILED(hr) ) { SetStatusMessage(L"Couldn't create Direct2D render target!"); return hr; }   //light green m_pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(0.27f, 0.75f, 0.27f), &m_pBrushJointTracked);   m_pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Yellow, 1.0f), &m_pBrushJointInferred); m_pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Green, 1.0f), &m_pBrushBoneTracked); m_pRenderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Gray, 1.0f), &m_pBrushBoneInferred); }   return hr; }   /// /// Dispose Direct2d resources /// void CSkeletonBasics::DiscardDirect2DResources( ) { SafeRelease(m_pRenderTarget);   SafeRelease(m_pBrushJointTracked); SafeRelease(m_pBrushJointInferred); SafeRelease(m_pBrushBoneTracked); SafeRelease(m_pBrushBoneInferred); }   /// /// Set the status bar message /// /// message to display void CSkeletonBasics::SetStatusMessage(WCHAR * szMessage) { SendDlgItemMessageW(m_hWnd, IDC_STATUS, WM_SETTEXT, 0, (LPARAM)szMessage); }

二、实测效果图:(这是有名的投降姿势矫正,哈哈~!)

三、例程工程分享:

http://pan.baidu.com/s/1c1S4Pkk

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信