0

私は以下を含むかなり単純なアプリケーションを持っています:

context->mFaceTracker = FTCreateFaceTracker();
hr = context->mFaceTracker->Initialize( &mVideoCameraConfig, &mDepthCameraConfig, NULL, NULL );

これは正常に動作し、S_OKを返し、mFaceTrackerは(私が知る限り)適切に初期化されます。ただし、次の行は次のとおりです。

hr = context->mFaceTracker->CreateFTResult( &context->mFTResult );

これは常にFT_ERROR_UNINITIALIZEDを返し、ポインターを割り当てず、私を困惑させます。デバイスと検出器のスレッド化の動作方法の変更から、FTcontextオブジェクトのクラスからサンプルに一致する構造体への変更まで、これを機能させるためのさまざまな戦略を試しましたが、すべて成功しませんでした。Kinect SDKサンプルはすべて正常に機能しますが、デバイスとFace Trackerを初期化する方法を厳密に反映しているにもかかわらず、自分のアプリケーションでそれらを使用しようとしてもうまくいかないようです。IFTFaceTrackerまたはIFTResultの初期化に関して、他の誰かがこの問題または同様の問題に遭遇したかどうか知りたいです。また、Initialize()が返すHRESULTをテストする以外に、IFTFaceTrackerをテストして正しい初期化を行う方法が知りたいです。前もって感謝します、

===編集

より多くのコードを求めるリクエストがいくつかありました。これはCinder上に構築されており、Cinderにこのブロックを使用しています:https ://github.com/BanTheRewind/Cinder-KinectSdk

すべてのコードを投稿することはできませんが、少なくとも関連するKinect初期化コードのほとんどをここに投稿しました。

void Kinect::start( const DeviceOptions &deviceOptions ) 
    {
        if ( !mCapture ) {

            // Copy device options
            mDeviceOptions  = deviceOptions;
            string deviceId = mDeviceOptions.getDeviceId();
            int32_t index   = mDeviceOptions.getDeviceIndex();

            // Clamp device index
            if ( index >= 0 ) {
                index = math<int32_t>::clamp( index, 0, math<int32_t>::max( getDeviceCount() - 1, 0 ) );
            }

            // Initialize device instance
            long hr = S_OK;
            if ( index >= 0 ) {
                hr = NuiCreateSensorByIndex( index, &mSensor );
                if ( FAILED( hr ) ) {
                    trace( "Unable to create device instance " + toString( index ) + ": " );
                    error( hr );
                    return;
                }
            } else if ( deviceId.length() > 0 ) {
                _bstr_t id = deviceId.c_str();
                hr = NuiCreateSensorById( id, &mSensor );
                if ( FAILED( hr ) ) {
                    trace( "Unable to create device instance " + deviceId + ":" );
                    error( hr );
                    return;
                }
            } else {
                trace( "Invalid device name or index." );
                return;
            }

            // Check device
            hr = mSensor != 0 ? mSensor->NuiStatus() : E_NUI_NOTCONNECTED;
            if ( hr == E_NUI_NOTCONNECTED ) {
                error( hr );
                return;
            }

            // Get device name and index
            if ( mSensor != 0 ) {
                mDeviceOptions.setDeviceIndex( mSensor->NuiInstanceIndex() );
                BSTR id = ::SysAllocString( mSensor->NuiDeviceConnectionId() ); 
                _bstr_t idStr( id );
                if ( idStr.length() > 0 ) {
                    std::string str( idStr );
                    mDeviceOptions.setDeviceId( str );
                }
                ::SysFreeString( id );
            } else {
                index = -1;
                deviceId = "";
            }
            flags |= NUI_INITIALIZE_FLAG_USES_COLOR;
            }
            hr = mSensor->NuiInitialize( flags );
            if ( FAILED( hr ) ) {
                trace( "Unable to initialize device " + mDeviceOptions.getDeviceId() + ":" );
                error( hr );
                return;
            }
                hr = mSensor->NuiSkeletonTrackingEnable( 0, flags );
                if ( FAILED( hr ) ) {
                    trace( "Unable to initialize skeleton tracking for device " + mDeviceOptions.getDeviceId() + ": " );
                    error( hr );
                    return;
                }
            mIsSkeletonDevice = true;

            mThread = CreateThread(NULL, 0, &Kinect::StaticThread, (PVOID)this, 0, 0);
        }
    }

    DWORD WINAPI Kinect::StaticThread(PVOID lpParam)
    {
        Kinect* device = static_cast<Kinect*>(lpParam);
        if (device)
        {
            return device->run();
        }
        return 0;
    }

void run() {

if(mSensor) {

if(mEnabledFaceTracking)
                {

                    if(mNeedFaceTracker) {
                        mFaceTracker = new FaceTracker( 
                        mDeviceOptions.getVideoSize().x,
                        mDeviceOptions.getVideoSize().y,
                        mDeviceOptions.getDepthSize().x,
                        mDeviceOptions.getDepthSize().y,
                        1.0,
                        1 );

                        mNeedFaceTracker = false;
                    }


                    // make sure we have both color && depth buffers to work with
                    if(newDepth || newVideo)
                    {
                        FT_SENSOR_DATA sensorData(mFTColorImage, mFTDepthImage);
                        FT_VECTOR3D hint[2]; // this is initialized elsewhere

                        mFaceTracker->checkFaces( (NUI_SKELETON_FRAME*) &skeletonFrame, mFTColorImage, mFTDepthImage, 1.0, 0);

                        if(mFaceTracker->getNumFaces() > 0) {

                            cout << " we have a face " << mFaceTracker->getNumFaces() << endl;

                            mNewFaceTrackData = true;
                            mFaceData.clear();
                            for( int i = 0; i < mFaceTracker->getNumFaces(); i++) {

                                Face newFace;
                                mFaceTracker->getProjectedShape(0, newFace.scale, newFace.rotation, newFace.transform, newFace.screenPositions);
                                mFaceData.push_back(newFace);
                            }
                        }
                    }
                }
Sleep( 8 );
}

}
4

1 に答える 1

1

Init メソッドでの SingleFace サンプルの KinectSensor.cpp のコード スニペットのように、NuiImageStreamOpen() を呼び出していない (またはコード サンプルに含めることを省略している) ようです。

hr = NuiImageStreamOpen(
    colorType,
    colorRes,
    0,
    2,
    m_hNextVideoFrameEvent,
    &m_pVideoStreamHandle );
if (FAILED(hr))
{
    return hr;
}

hr = NuiImageStreamOpen(
    depthType,
    depthRes,
    (bNearMode)? NUI_IMAGE_STREAM_FLAG_ENABLE_NEAR_MODE : 0,
    2,
    m_hNextDepthFrameEvent,
    &m_pDepthStreamHandle );

CreateFTResult() を呼び出す前にそれらを呼び出すと、初期化されていないエラーが修正される場合があります。

さらに、CreateThread() を呼び出してから run() を呼び出しますが、while ループがないため、Kinect が FaceTracking にデータを提供し始めるのに十分な時間がなく、スレッドがすぐに終了します。

センサーの新しいデータをチェックし、mFTColorImage と mFTDepthImage を更新し、newDepth と newVideo フラグを設定するスレッドまたはイベント ループが含まれているようには見えません。これは、上記で作成した同じスレッド (while ループを作成し、Kinect データを必要とするパフォーマンスやその他のクラスを無視する場合) にすることも、SingleFace Kinect SDK サンプルのように別のスレッドにすることもできます。

于 2012-08-03T00:48:42.507 に答える