【问题标题】:Rendering videos and polling for Saccade Data in Real Time in PsychToolbox在 PsychToolbox 中实时渲染视频和轮询 Saccade 数据
【发布时间】:2016-03-15 21:01:38
【问题描述】:

我正在使用 MATLAB 的 PsychToolbox 运行一个实验,我必须实时收集扫视信息,同时还逐帧渲染视频。 我遇到的问题是,考虑到视频和显示器的帧速率(~24fps),这意味着我有大约 40 毫秒的时间窗口来渲染查询和渲染我之前存储在内存中的每一帧。这很好,但由于这个过程需要额外的时间,这通常意味着我有大约 20 毫秒的时间来从头到尾持续轮询眼跳。

这是一个问题,因为当我轮询眼跳时,我通常在做什么(比如静止图像,只需要显示一次),是等待注视的开始和结束,给定一致的轮询来自眼动追踪机器,它检测到观察者的视线突然从一个点转移到另一个点,并带有

速度超过:35 度/秒

还有一个

加速度超过:9500 deg/s^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

理想情况下,我想要一个 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) 命令所需的时间似乎也约为 16 毫秒。这意味着如果在此间隔内发生任何眼跳,我将无法检测或轮询它们。请注意,最后我有 42 毫秒(帧刷新率)减去 16 毫秒(查询和显示帧所需的时间),因此每帧总共有大约 26 毫秒的探测时间来获取眼球运动和计算任何真实的-时间处理。

一种可能的解决方案可能是不断轮询注视,而不是检查眼球运动是否是扫视。但我仍然会遇到无法捕捉每帧大约三分之一的内容的问题,只是因为加载它需要时间。

【问题讨论】:

    标签: multithreading matlab video psychtoolbox


    【解决方案1】:

    您需要重新组织代码。完成这项工作的唯一方法是知道翻转需要多长时间以及知道提交下一个视频帧需要多长时间。然后你循环轮询眼动仪,直到你有足够的时间在下一个屏幕垂直空白之前执行绘图命令。

    你不能在matlab中做任何形式的可靠多线程

    【讨论】:

      猜你喜欢
      • 2014-10-15
      • 1970-01-01
      • 1970-01-01
      • 2011-10-10
      • 1970-01-01
      • 2011-12-07
      • 1970-01-01
      • 1970-01-01
      • 2020-08-17
      相关资源
      最近更新 更多