none
C++ Kinect Program without GDI+ Drawing RRS feed

  • Question

  • Hi forum,

    I am trying to use the Kinect SDK v1.0 in a C++ program. Not too many tutorials could be found except the sample code from the Kinect Explore.

    I think the sample code used GDI to render images and it looks pretty complex, compared to the C# sample. My question is how I could just run the camera and get the frames (color, depth and skeleton) without drawing them, since what I need is the data.

    Here's the code that I've got. The code is basically from the sampel code without the drawing part. But it doesn't work. I guess I'm missing some key functions. Help please.

    First of all, I get the Nui_Init()

    HRESULT MyKinectNui::Nui_Init()
    {
    	HRESULT  hr;
        RECT     rc;
        bool     result;
    
        if ( !m_pNuiSensor )
        {
            int hr = NuiCreateSensorByIndex(0, &m_pNuiSensor);
    
            if ( FAILED(hr) )
            {
                return hr;
            }
    
            //SysFreeString(m_instanceId);
    
            m_instanceId = m_pNuiSensor->NuiDeviceConnectionId();
        }
    
        m_hNextDepthFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
        m_hNextColorFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
        m_hNextSkeletonEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
        
        DWORD nuiFlags = NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX | NUI_INITIALIZE_FLAG_USES_SKELETON |  NUI_INITIALIZE_FLAG_USES_COLOR;
        hr = m_pNuiSensor->NuiInitialize( nuiFlags );
        if ( E_NUI_SKELETAL_ENGINE_BUSY == hr )
        {
            nuiFlags = NUI_INITIALIZE_FLAG_USES_DEPTH |  NUI_INITIALIZE_FLAG_USES_COLOR;
            hr = m_pNuiSensor->NuiInitialize( nuiFlags) ;
        }
      
        if ( FAILED( hr ) )
        {
            if ( E_NUI_DEVICE_IN_USE == hr )
            {
                 printf(" IDS_ERROR_IN_USE, MB_OK | MB_ICONHAND \n");
            }
            else
            {
                printf(" IDS_ERROR_NUIINIT, MB_OK | MB_ICONHAND \n");
            }
            return hr;
        }
    
        if ( HasSkeletalEngine( m_pNuiSensor ) )
        {
            hr = m_pNuiSensor->NuiSkeletonTrackingEnable( m_hNextSkeletonEvent, 0 );
            if( FAILED( hr ) )
            {
                printf(" IDS_ERROR_SKELETONTRACKING, MB_OK | MB_ICONHAND ");
                return hr;
            }
        }
    
        hr = m_pNuiSensor->NuiImageStreamOpen(
            NUI_IMAGE_TYPE_COLOR,
            NUI_IMAGE_RESOLUTION_640x480,
            0,
            2,
            m_hNextColorFrameEvent,
            &m_pColorStreamHandle );
    
        if ( FAILED( hr ) )
        {
            printf(" IDS_ERROR_VIDEOSTREAM, MB_OK | MB_ICONHAND ");
            return hr;
        }
    
        hr = m_pNuiSensor->NuiImageStreamOpen(
            HasSkeletalEngine(m_pNuiSensor) ? NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX : NUI_IMAGE_TYPE_DEPTH,
            NUI_IMAGE_RESOLUTION_320x240,
            0,
            2,
            m_hNextDepthFrameEvent,
            &m_pDepthStreamHandle );
    
        if ( FAILED( hr ) )
        {
            printf(" IDS_ERROR_DEPTHSTREAM, MB_OK | MB_ICONHAND ");
            return hr;
        }
    
        // Start the Nui processing thread
        m_hEvNuiProcessStop = CreateEvent( NULL, FALSE, FALSE, NULL );
        m_hThNuiProcess = CreateThread( NULL, 0, Nui_ProcessThread, this, 0, NULL );
    
    	return hr;
    }

    and the Nui_ProcessThread() to run the loop in the new created thread (am i right?)

    DWORD WINAPI MyKinectNui::Nui_ProcessThread(LPVOID pParam)
    {
    	MyKinectNui *pthis = (MyKinectNui *) pParam;
        return pthis->Nui_ProcessThread();
    }
    
    //-------------------------------------------------------------------
    // Nui_ProcessThread
    //
    // Thread to handle Kinect processing
    //-------------------------------------------------------------------
    DWORD WINAPI MyKinectNui::Nui_ProcessThread()
    {
        const int numEvents = 4;
        HANDLE hEvents[numEvents] = { m_hEvNuiProcessStop, m_hNextDepthFrameEvent, m_hNextColorFrameEvent, m_hNextSkeletonEvent };
        int    nEventIdx;
        DWORD  t;
    
        m_LastDepthFPStime = timeGetTime( );
    
        //blank the skeleton display on startup
        m_LastSkeletonFoundTime = 0;
    
        // Main thread loop
        bool continueProcessing = true;
        while ( continueProcessing )
        {
            // Wait for any of the events to be signalled
            nEventIdx = WaitForMultipleObjects( numEvents, hEvents, FALSE, 100 );
    
            // Process signal events
            switch ( nEventIdx )
            {
                case WAIT_TIMEOUT:
                    continue;
    
                // If the stop event, stop looping and exit
                case WAIT_OBJECT_0:
                    continueProcessing = false;
                    continue;
    
                case WAIT_OBJECT_0 + 1:
                    Nui_GotDepthAlert();
                     ++m_DepthFramesTotal;
                    break;
    
                case WAIT_OBJECT_0 + 2:
                    Nui_GotColorAlert();
                    break;
    
                case WAIT_OBJECT_0 + 3:
                    Nui_GotSkeletonAlert( );
                    break;
            }
    
            //// Once per second, display the depth FPS
            //t = timeGetTime( );
            //if ( (t - m_LastDepthFPStime) > 1000 )
            //{
            //    int fps = ((m_DepthFramesTotal - m_LastDepthFramesTotal) * 1000 + 500) / (t - m_LastDepthFPStime);
            //    PostMessageW( m_hWnd, WM_USER_UPDATE_FPS, IDC_FPS, fps );
            //    m_LastDepthFramesTotal = m_DepthFramesTotal;
            //    m_LastDepthFPStime = t;
            //}
    
            //// Blank the skeleton panel if we haven't found a skeleton recently
            //if ( (t - m_LastSkeletonFoundTime) > 250 )
            //{
            //    if ( !m_bScreenBlanked )
            //    {
            //        Nui_BlankSkeletonScreen( GetDlgItem( m_hWnd, IDC_SKELETALVIEW ), true );
            //        m_bScreenBlanked = true;
            //    }
            //}
        }
    
        return 0;
    }
    

    Then it's the image functions to get the frames. like this:

    void MyKinectNui::Nui_GotColorAlert()
    {
    	NUI_IMAGE_FRAME imageFrame;
    
    	HRESULT hr = m_pNuiSensor->NuiImageStreamGetNextFrame(m_pColorStreamHandle, 0, &imageFrame);
    
    	
    }
    
    //-------------------------------------------------------------------
    //get depth image
    //-------------------------------------------------------------------
    void MyKinectNui::Nui_GotDepthAlert()
    {
    	NUI_IMAGE_FRAME imageFrame;
    
    	HRESULT hr = m_pNuiSensor ->NuiImageStreamGetNextFrame(m_pDepthStreamHandle, 0, &imageFrame);
    }
    
    //-------------------------------------------------------------------
    //get skeleton
    //-------------------------------------------------------------------
    void MyKinectNui::Nui_GotSkeletonAlert()
    {
    	NUI_SKELETON_FRAME SkeletonFrame = {0};
    
    	bool bFoundSkeleton = false;
    
    	if(SUCCEEDED(m_pNuiSensor->NuiSkeletonGetNextFrame(0, &SkeletonFrame)))
    	{
    		for(int i=0; i< NUI_SKELETON_COUNT; i++)
    		{
    			if(SkeletonFrame.SkeletonData[i].eTrackingState == NUI_SKELETON_TRACKED ||
    				(SkeletonFrame.SkeletonData[i].eTrackingState == NUI_SKELETON_POSITION_ONLY && m_bAppTracking))
    			{
    				bFoundSkeleton = true;
    			}
    		}
    	}
    
    	HRESULT hr = m_pNuiSensor->NuiTransformSmooth(&SkeletonFrame,NULL);
        if(FAILED(hr))
        {
            return;
        }
    }

    and I will implement my algorithm in these functions.

    Here's the constructor of the MyKinectNui class

    MyKinectNui::MyKinectNui():m_hInstance(NULL)
    {
    	Nui_Zero();
    	Nui_Init();
    }

    and I simply created a new variable in the main() function

    MyKinectNui *g_kinectNui = new MyKinectNui();

    I think by this method, the camera should work. Am I missing something for the initialization or the momery allocation? Thank you.
    Monday, February 27, 2012 9:18 AM

All replies

  • I'd start by just stripping a little out at a time, making sure it works, and then progressing further.

    It looks like at the very least you're not releasing the frames.

    Monday, February 27, 2012 7:37 PM