1

Greetings,

I am developing an app in C++ using Kinect 360. I am having a problem in runtime with KinectGrabber which doesn't initialize the camera as I hoped for in runtime. When debugging it, I found that it gets an error in "MSFTKinectGrabber::Init" when testing the value of "hr". This test interrupts the program dutifully, but I don't know why.

My setup:

  • I have installed Kinect v1.8 SDK's, then v1.8 Development Kit and finally v1.8 Runtime.
  • The compiler is VStudio 2010;
  • This app was developed by a colleague of mine and was running before in another computer (Laptop - windows 8);
  • I am using a new desktop (Windows 10);
  • Tried multiple USB entries (2.0 and 3.0) and Kinect is working in the demos of the "Developer Toolkit Browser v1.8.0 (kinect for Windows);
  • Checked drivers of Kinect in Device Manager and updated them (either way, Kinect Runtime adds an extra driver feature and updates them too);

This is the place where all seems to go wrong, when the program enters the IF statement (@"MSFTKinectGrabber::Init"):

    hr = m_NuiSensor->NuiImageStreamOpen(NUI_IMAGE_TYPE_DEPTH, NUI_IMAGE_RESOLUTION_640x480,
                            depthFlags, 2, m_NextDepthFrameEvent, &m_pDepthStreamHandle);
    if( FAILED( hr ) )
    {
        std::cout << "Error: NuiImageStreamOpen " <<  hr << std::endl;
        return false;
    }

Below I have the whole codes regarding:

  • My main, not the core of the problem I think, jsut to show how I start the program;
  • My function "initializeKinect", where the statement if(!grabberMSFT.Init(&processor)) should be false if the "MSFTKinectGrabber::Init" returned true, which meant no problems;
  • The function "MSFTKinectGrabber::Init", where the initialization and the tests for the Kinect are made.

Function: Main

int main(int argc, char** argv){
    processor = new KinectDataProcessor();
    MSFTKinectGrabber grabberMSFT;

    int kinect_state = initializeKinect(*processor, grabberMSFT, argc, argv);

    if(kinect_state==0){
        cloudProcessor = new CloudProcessor();
        int v=0;
        while (run){
            v++;
            HandleKeyboardEvents();
            processor->Update(); 
            if (startClassify && !continueClassify){
                continueClassify = true;
                boost::thread classificationThread(&threadClassify);
            }
        }
        grabberMSFT.DeInit();   
        processor->DeInit();
    }else{
        system("PAUSE");
        return -1;
    }

    return 0;
}

Function: initializeKinect

int initializeKinect(KinectDataProcessor & processor, MSFTKinectGrabber & grabberMSFT, int argc,char** argv){
    int nRetCode = 0;

    if (hModule != NULL)
    {
        // initialize MFC and print and error on failure
        if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
        {
            // TODO: change error code to suit your needs
            _tprintf(_T("Fatal Error: MFC initialization failed\n"));
            nRetCode = 1;
        }
        else
        {

            std::cout << "Kinect Parameters: " << std::endl;
            std::cout << "1 - MinDepth (float)  - minimum allowed is '0.0f'" << std::endl;
            std::cout << "2 - MaxDepth (float)  - maximum allowed is '4.0f'" << std::endl;
            std::cout << "3 - NearMode (int)    - '0' for true, '1' for false" << std::endl;

            float minDepth = MIN_DEPTH;//float (atof(argv[1]));
            float maxDepth = MAX_DEPTH;//float (atof(argv[2]));

            std::cout << "[MinDepth, MaxDepth] = [" << minDepth << ", " << maxDepth << "]" << std::endl;

            bool nearModeActive = true;
            std::cout << "Near mode selected\n";

            //KinectDataProcessor processor;
            if(!processor.Init(KinectProcessor::GrabberType::MSFT))
            {
                processor.DeInit();
                run = false;
                return -1;
            }


            processor.SetDepthParameters(minDepth, maxDepth, nearModeActive);

            //MSFTKinectGrabber grabberMSFT;

            if (!grabberMSFT.Init(&processor)){
                    grabberMSFT.DeInit();
                    processor.DeInit();
                    run = false;

                    return -1;
            }

            cout<<"Ready to run"<<endl;
        }
    }
    else
    {
        // TODO: change error code to suit your needs
        _tprintf(_T("Fatal Error: GetModuleHandle failed\n"));
        nRetCode = 1;
    }

    return nRetCode;

}

Function: MSFTKinectGrabber::Init

bool MSFTKinectGrabber::Init(KinectProcessor * kinectProcessor)
{
    m_KinectProcessor = kinectProcessor;

    //get NuiSensor obj
    HRESULT hr = NuiCreateSensorByIndex(0, &m_NuiSensor);
    if ( FAILED(hr) )
    {
        std::cout << "Error: NuiCreateSensorByIndex " << hr << std::endl;
        return false;
    }

    m_DeviceID = m_NuiSensor->NuiDeviceConnectionId();

    hr = m_NuiSensor->NuiInitialize( NUI_INITIALIZE_FLAG_USES_COLOR | NUI_INITIALIZE_FLAG_USES_DEPTH );
    if( FAILED(hr) )
    {
        std::cout << "Error: NuiInitialize " << hr << std::endl;
        return false;
    }

    //Create color and depth events
    m_NextColorFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
    m_NextDepthFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

    //open video streams
    hr = m_NuiSensor->NuiImageStreamOpen(NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, 0, 2, m_NextColorFrameEvent, &m_pColorStreamHandle);
    if( FAILED( hr ) )
    {
        std::cout << "Error: NuiImageStreamOpen " <<  hr << std::endl;
        return false;
    }

    DWORD depthFlags = NULL;
    if(kinectProcessor->IsMSFTNearMode())
        depthFlags = NUI_IMAGE_STREAM_FLAG_ENABLE_NEAR_MODE;

    hr = m_NuiSensor->NuiImageStreamOpen(NUI_IMAGE_TYPE_DEPTH, NUI_IMAGE_RESOLUTION_640x480, depthFlags, 2, m_NextDepthFrameEvent, &m_pDepthStreamHandle);
    if( FAILED( hr ) )
    {
        std::cout << "Error: NuiImageStreamOpen " <<  hr << std::endl;
        return false;
    }

    // Start the NUI processing thread
    m_ProcessThreadStopEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
    m_ProcessThread = CreateThread( NULL, 0, ProcessThread, this, 0, NULL );

    return true;
}

Thank you for your time!

1 Answers1

0

Quick answer:

If your Kinect has "XBOX360" written on its front side than you cannot use the Near Mode and you need to change your nearModeActive from true to false.


More details:

I believe the issue is that you are trying to use the Near Mode with regular Kinect. In your initializeKinect the following is hardcoded:

bool nearModeActive = true;
std::cout << "Near mode selected\n";

and then

processor.SetDepthParameters(minDepth, maxDepth, nearModeActive);

The MSFTKinectGrabber::Init then tries to open the depth stream in near mode, because of the following:

if(kinectProcessor->IsMSFTNearMode())
    depthFlags = NUI_IMAGE_STREAM_FLAG_ENABLE_NEAR_MODE;

The problem is: regular XBOX Kinect does not support this feature. Only Kinect for Windows does. In fact, that is the only real difference between them. The Kinect for Windows is much more expensive. You can read more about the Near Mode here.