0

刺激を提示するために、psychtoolbox から shady に移行することに興味があります。私はオンラインドキュメントに目を通しましたが、現在matlabで行っていることを怪しげに再現する方法がよくわかりません。

私がやっていることは、実はとてもシンプルです。試行ごとに、

  1. ディスクから 1 つの画像をロードします (オフラインで輝度の線形化を行います)。これには、その試行で表示する予定のすべてのフレームが含まれています (刺激は 1000x1000 px で、25 フレームを提示するため、画像は 5000x5000px になります。 BW 画像を使用するため、ピクセルごとに 1 つの int8 値があります)。

  2. 画像全体を CPU から GPU に転送します

  3. ある時点で (外部制御)、最初のフレームをビデオ バッファーにコピーして表示します。

  4. 別のポイント (外部制御) で、残りの 24 フレームの表示をトリガーします (各ビデオ フレームの画像の関連部分をビデオ バッファーにコピーしてから、flip() を呼び出します)。

  5. 外部制御は、別のマシンが TCP/IP を介して刺激提示コードと通信することによって行われます。コントロール PC がプレゼンテーション PC にコマンドを送信し、これが実行された後、プレゼンテーション PC は確認メッセージをコントロール PC に返信する必要があります。最初のフレームが画面に表示されたとき、2 番目のフレームが画面に表示されたとき、25 番目のフレームが画面に表示されたときに 1 つずつ、3 つの ACK メッセージを送信する必要があります (このようにして、コントロール PC はフレームがドロップされたかどうかを簡単に確認できます)。 )。matlab では、ブロッキング メソッドの Flip() を呼び出してフレームを表示し、戻ってきたら制御 PC に ACK を送信します。

それでおしまい。どうすれば日陰でそれを行うことができますか? 私が見るべき例はありますか?

4

1 に答える 1

0

この情報を探す場所は、 および の docstringShady.StimulusShady.Stimulus.LoadTexture、含まれているサンプル スクリプトanimated-textures.pyです。

ほとんどの Python と同様に、やりたいことを実行する方法は複数あります。これが私がそれを行う方法です:

w = Shady.World()
s = w.Stimulus( [frame00, frame01, frame02, ...], multipage=True )

ここで、それぞれframeNNは 1000x1000 ピクセルのnumpy配列 (浮動小数点またはuint8) です。

または、Shady にディスクから直接ロードするように依頼することもできます。

s = w.Stimulus('trial01/*.png', multipage=True)

ここで、ディレクトリtrial01には 25 個の 1000x1000 ピクセルの画像ファイルが含まれており、正しく並べ替えられるように (たとえば) 名前が付けられ00.png24.pngいます。または、ファイル名の明示的なリストを提供することもできます。

どちらの場合でも、メモリからロードした場合でもディスクからロードした場合でも、フレームはすべてその呼び出しでグラフィックス カードに転送されます。その後、(タイムクリティカルに)次の方法で切り替えることができます。

s.page = 0  # or any number up to 24 in your case

このmultipageオプションの使用により、デフォルトの「フレーム」メカニズム (1000x25000 OpenGL テクスチャを 1 つ作成) の代わりに「ページ」アニメーション メカニズム (フレームごとに 1 つの OpenGL テクスチャを作成) を使用していることに注意してください。多くのグラフィックス カードでの単一のテクスチャの最大許容寸法。これらのメカニズムの違いは、Shady.Stimulusクラスの docstring と前述のインタラクティブなデモで説明されています。

python -m Shady demo animated-textures

次のトライアルを準備するには、.LoadPages()(Shady バージョン 1.8.7 の新機能) を使用できます。これは、既存の「ページ」をループして新しいテクスチャを以前に使用されたグラフィックス カード テクスチャ バッファにロードし、必要に応じてさらにページを追加します。

s.LoadPages('trial02/*.png')

ここで、確立されたワークフローは、フレームを単一の 5000x5000 ピクセルの画像として連結することであると述べています。上記の私の解決策は、おそらく numpy 呼び出しを使用して、1000x1000 ピクセルのフレームに再度切り分ける作業を行ったことを前提としています (現在、Matlab で同等のことを行っているように聞こえます)。5000x5000 として保存し続ける場合、物事を制御し続けるための最良の方法は、それを切り分けるための独自のコードを維持することです。ただし、すべてを一度に転送するというまったく異なる戦略を取ることができることに言及する価値があります。

s = w.Stimulus('trial01_5000x5000.png', size=1000)

これにより、事前に準備された 5000x5000 の画像全体がディスクから (または、ファイル名の代わりに 5000x5000 numpy 配列を渡したい場合はメモリから) グラフィックス カードのメモリ内の単一のテクスチャにロードされます。ただし、size仕様により、Stimulusは配列の左下の 1000x1000 ピクセル部分のみを表示します。次に、エンベロープに対してキャリアをシフトすることで、「フレーム」を切り替えることができます。たとえば、次のように言うとします。

s.carrierTranslation = [-1000, -2000]

次に、5x5 配列の 1 つの「列」と 2 つの「行」にあるフレームを見ていることになります。

最後に、Shady のオンザフライ ガンマ補正とディザリングを利用できることを覚えておいてください。これらは、明示的に無効にしない限りいずれにせよ発生しますが、刺激.gammaを 1.0のままにしておくと、もちろん物理的な効果はありません。整数ピクセル値を使用します。そのため、刺激を個別の1000x1000配列として生成し、それぞれに 範囲内の線形化されていない浮動小数点値を含め、[0.0,1.0]Shady にそれ以上のすべてのことを心配させることができます。

于 2019-05-16T17:16:22.423 に答える