0

私は MATLAB の PsychToolbox を使用して、フレームごとにビデオをレンダリングしながらサッカード情報をリアルタイムで収集する必要がある実験を実行しています。私が抱えている問題は、ビデオとディスプレイのフレーム レート (〜 24 fps) を考えると、クエリをレンダリングし、以前にメモリに保存したすべてのフレームをレンダリングするのに約 40 ミリ秒の時間枠があることを意味します。これは問題ありませんが、このプロセスにはさらに時間がかかるため、通常、サッケードを最初から最後まで一貫してポーリングするには約 20 ミリ秒かかることを意味します。

これは問題です。サッケードをポーリングするとき、私が通常行っていること (静止画像では、一度だけ表示する必要がある) は、目からの一貫したポーリングが与えられた場合、固視の開始と終了を待つことです。観察者の視線がある点から別の点に急激に移動したことを検出する追跡マシン。

速度超過: 35 度/秒

加速度超過: 9500 deg/s^2

しかし、フレームがレンダリングされているときにサッケードの開始または終了が発生した場合 (ほとんどの場合)、レンダリングとポーリングのプロセスを 2 つに分割せずにリアルタイムでデータを取得することは不可能になります。 MATLAB スレッド。

私のコード(関連部分)は次のようになります:

    while GetSecs-t.stimstart(sess,tc)<fixation_time(stimshownorder(tc))
        x =evt.gx(1);
        y =evt.gy(1);
        pa = evt.pa(1);

        x_vec = [x_vec; x];
        y_vec = [y_vec; y];
        pa_vec = [pa_vec; pa];

        evta=Eyelink('NewestFloatSample');
        evtype=Eyelink('GetNextDataType');

        #%% Ideally this block should detect saccades
        #%% It works perfect in still images but it can't do anything here 
        #%% since it conflicts the main for loop ahead.

        if evtype==el.ENDSACC
            sacdata=Eyelink('GetFloatData',evtype);
            sac.startx(sess,tc,sacc)=sacdata.gstx;
            sac.starty(sess,tc,sacc)=sacdata.gsty;
            sac.endx(sess,tc,sacc)=sacdata.genx;
            sac.endy(sess,tc,sacc)=sacdata.geny;
            sac.start(sess,tc,sacc)=sacdata.sttime;
            sac.end(sess,tc,sacc)=sacdata.entime;
            sacc=sacc+1;
        end

         #%Main loop where we render each frame:
         if (GetSecs-t.space(sess,tc)>lag(tc)) 
            z = floor((GetSecs-t.space(sess,tc)-lag(tc))/(1/24))+1;
            if z > frame_number
                z = frame_number;
            end
            Screen('DrawTexture',win,stimTex{z});    
            Screen('Flip',win);
            #DEBUG:
            #disp(z);
            #%disp(frame_number);
        end

    end

理想的には、メイン スレッドでサッケードをポーリングしながら、バックエンドの 1 つの別のスレッドでビデオを個別にレンダリングできる MATLAB 関数が必要です。理想的には次のようになります。

    #% Define New thread to render video
    #% Some new function that renders video in parallel in another thread
    StartParallelThread(1);
    #%Play video:
    Playmovie(stimTex);

    #%Now start this main loop to poll for eye movements.
    while GetSecs-t.stimstart(sess,tc)<fixation_time(stimshownorder(tc))
        x =evt.gx(1);
        y =evt.gy(1);
        pa = evt.pa(1);

        x_vec = [x_vec; x];
        y_vec = [y_vec; y];
        pa_vec = [pa_vec; pa];

        evta=Eyelink('NewestFloatSample');
        evtype=Eyelink('GetNextDataType');
        if evtype==el.ENDSACC
            sacdata=Eyelink('GetFloatData',evtype);
            sac.startx(sess,tc,sacc)=sacdata.gstx;
            sac.starty(sess,tc,sacc)=sacdata.gsty;
            sac.endx(sess,tc,sacc)=sacdata.genx;
            sac.endy(sess,tc,sacc)=sacdata.geny;
            sac.start(sess,tc,sacc)=sacdata.sttime;
            sac.end(sess,tc,sacc)=sacdata.entime;
            sacc=sacc+1;
        end
    end

また、Screen('Flip',win) コマンドを実行するのにかかる時間は約 16ms のようです。これは、この間隔でサッカードが発生した場合、それらを検出またはポーリングできないことを意味します。最終的に、42 ミリ秒 (フレームのリフレッシュ レート) から 16 ミリ秒 (フレームのクエリと表示にかかる時間) を差し引いた時間になることに注意してください。時間処理。

考えられる解決策は、目の動きがサッカードかどうかをチェックする代わりに、視線を継続的にポーリングすることです。しかし、ロードに時間がかかるという理由だけで、各フレームの約 3 分の 1 で何が起こっているのかをキャプチャできないという問題がまだあります。

4

1 に答える 1

1

コードを再編成する必要があります。これを機能させる唯一の方法は、フリップにかかる時間を把握し、次のビデオ フレームの送信にかかる時間を把握することです。次に、次の画面の垂直ブランクの前に描画コマンドを実行するのに十分な時間が残るまで、ループでアイ トラッカーをポーリングします。

matlab で信頼性の高いマルチスレッドを実行することはできません

于 2016-04-14T10:12:32.783 に答える