1

ご挨拶、

Kinect 360 を使用して C++ でアプリを開発しています。実行時に期待どおりにカメラを初期化しない KinectGrabber で実行時に問題が発生しています。デバッグ中、「hr」の値をテストすると、「MSFTKinectGrabber::Init」でエラーが発生することがわかりました。このテストは忠実にプログラムを中断しますが、その理由はわかりません。

私のセットアップ:

  • Kinect v1.8 SDK、v1.8 Development Kit、最後に v1.8 Runtime をインストールしました。
  • コンパイラは VStudio 2010 です。
  • このアプリは私の同僚によって開発されたもので、以前は別のコンピューター (ラップトップ - Windows 8) で実行されていました。
  • 新しいデスクトップ (Windows 10) を使用しています。
  • 複数の USB エントリ (2.0 および 3.0) を試したところ、Kinect は "Developer Toolkit Browser v1.8.0 (kinect for Windows);
  • デバイス マネージャーで Kinect のドライバーを確認し、それらを更新しました (いずれにせよ、Kinect ランタイムは追加のドライバー機能を追加し、それらも更新します)。

これは、プログラムが IF ステートメント (@"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;
    }

以下に、以下に関するコード全体を示します。

  • 私が考える問題の核心ではなく、私の主なjsut は、プログラムを開始する方法を示しています。
  • 「MSFTKinectGrabber::Init」が true を返した場合、ステートメント if(!grabberMSFT.Init(&processor)) は false である必要がある私の関数「initializeKinect 」。これは問題がないことを意味します。
  • Kinect の初期化とテストが行​​われる " MSFTKinectGrabber::Init "関数。

機能:メイン

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;
}

関数:初期化キネクト

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;

}

関数: 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;
}

お時間をいただきありがとうございます!

4

1 に答える 1

0

素早い回答:

Kinect の前面に「XBOX360」と書かれている場合は、Near Mode を使用できず、nearModeActive を true から false に変更する必要があります。


詳細:

問題は、通常の Kinect で Near Mode を使用しようとしていることにあると思います。initializeKinect では、以下がハードコーディングされています。

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

その後

processor.SetDepthParameters(minDepth, maxDepth, nearModeActive);

次に、MSFTKinectGrabber::Init は、次の理由により、near モードで深度ストリームを開こうとします。

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

問題は、通常の XBOX Kinect がこの機能をサポートしていないことです。Kinect for Windows のみが対応しています。実際、それがそれらの間の唯一の本当の違いです。Kinect for Windows は、はるかに高価です。近距離モードの詳細については、こちらをご覧ください。

于 2016-10-12T18:08:05.730 に答える