画像ファイルの呈示2

画像ファイルの呈示に変更点を加えて、実験らしくしたものです。

スペースキーを押すと凝視点が呈示され、指定した時間後に画像が呈示されます。

FまたはJのキーを押すと、どちらのキーを押したか、その反応時間が記録されます。

特定のフォルダ(以下のサンプルではimages)に保存しているすべてのJPEG画像を呈示すると実験が終わります。

(繰り返しも可能)

画像のファイル名をプログラム内で指定せずに、自動的に取得しています。あるディレクトリ(フォルダ)内のファイルのリストを取得する を参照してください。

function imageRT
% スペースキーを押すと凝視点が呈示され、指定した時間後に画像が呈示される。
% FまたはJのキーを押すと、どちらのキーを押したか、その反応時間が記録される。
%
% 画像(ファイル形式はJPEG)はプログラムと同じ場所に「images」という名前のフォルダを作り、その中に保存しておくこと。
% 1ブロックの試行数はフォルダ内の画像数で、repeatNumを使って繰り返し回数を指定可能。
%----------------------------------------
%  以下の変数を必要に応じて変更してください
%
% 背景色 
bgColor = [128 128 128]; %RGBの値
% 画像を拡大縮小して呈示するときの割合。1のときオリジナルのサイズ(小数点OK)
imgRatio = 1; 
% 繰り返し回数
repeatNum = 1;
% 何試行ごとに休憩メッセージを表示するか
restNum = 4;
%---------------------------------
% 凝視点
fixTime = 0.75; %凝視点の提示時間(単位は秒。小数点OK)
fixLength = 30; %凝視点線分の長さ(単位はピクセル。整数)
%凝視点の座標
fixApex = [
  fixLength/2, -fixLength/2, 0, 0;
  0, 0, fixLength/2, -fixLength/2];
fontSize = 30; % 文字サイズ(整数)
%---------------------------------
% 実験参加者名の入力
SubName = input('Name? ', 's'); % 名前をたずねる
if isempty(SubName) % 名前の入力がなかったらプログラムを終了
    return;
end;
% 出力ファイルの上書き確認を行う
SaveFileName=[SubName '.csv']; % 出力ファイル名
if exist(SaveFileName, 'file') % すでに同じ名前のファイルが存在していないかの確認
    resp=input([SaveFileName 'はすでに存在します。上書きをしてよい場合は y を入力してエンターキーを押してください。'], 's');
    if ~strcmp(resp,'y') 
        disp('プログラムを強制終了しました。')
        return
    end
end
% 呼び出しておいたほうがよい関数たち。
AssertOpenGL; 
KbName('UnifyKeyNames');
ListenChar(2); % Matlabに対するキー入力を無効
%myKeyCheck; % 外部ファイル
GetSecs;
WaitSecs(0.1);
rand('state', sum(100*clock)); % 古いMatlab
%rng('shuffle') % 新しいMatlab
    
HideCursor;
%---------------------------------
try
  
    % 刺激を呈示するディスプレイ(ウィンドウ)の設定
    screenNumber = max(Screen('Screens'));
    
    % デバッグ用。ウィンドウでの呈示
    %[windowPtr, windowRect] = Screen('OpenWindow', screenNumber, bgColor, [10 50 750 550]);
    % 実験用。フルスクリーン
    [windowPtr, windowRect] = Screen('OpenWindow', screenNumber, bgColor);
  
    % 1フレームの時間 (inter flame interval)
    ifi = Screen('GetFlipInterval', windowPtr);
    
    %画面の中央の座標
    [centerPos(1), centerPos(2)] = RectCenter(windowRect);
   
    % 画像はimagesという名前のフォルダに保存しておくこと。
    imgFolder = ['images' filesep]; % 画像を保存しているフォルダ名
    imgFileList = dir([imgFolder '*.jpg']);   
    imgNum = size(imgFileList, 1); % フォルダ内の画像の枚数
           
    %------------------------------
    % フォント設定
    if IsWin
        %Screen('TextFont', windowPtr, 'メイリオ');
        Screen('TextFont', windowPtr, 'Courier New');
    end;
   
    if IsOSX
        % DrawHighQualityUnicodeTextDemoを参照。
        allFonts = FontInfo('Fonts');
        foundfont = 0;
        for idx = 1:length(allFonts)
            %if strcmpi(allFonts(idx).name, 'Hiragino Mincho Pro W3')
            if strcmpi(allFonts(idx).name, 'Hiragino Kaku Gothic Pro W3')
                foundfont = 1;
                break;
            end
        end
        if ~foundfont
            error('Could not find wanted japanese font on OS/X !');
        end
        Screen('TextFont', windowPtr, allFonts(idx).number);     
    end;
    %------------------------------
              
    % 出力ファイルを開く
    Fid = fopen(SaveFileName, 'wt');
    
    fprintf(Fid, '%s\n', SubName);
    fprintf(Fid, '%s\n', datestr(now, 'yy-mmdd-HH:MM'));
    fprintf(Fid, '%s\n', '');
    fprintf(Fid, 'imgRatio,%f\n', imgRatio);
    fprintf(Fid, 'fixTime,%f\n', fixTime);
    fprintf(Fid, 'fontSize,%d\n', fontSize);
    fprintf(Fid, 'ifi (ms),%f\n', ifi * 1000);
    fprintf(Fid, '%s\n', '');
    tmpStr = '繰り返し,試行,ファイル名,反応時間(ms),凝視点(ms)';
    fprintf(Fid, '%s\n', tmpStr);
    
    trialNum = 0; % 現在の試行数
    
    for k = 1: repeatNum % ブロックの繰り返し
        order = randperm(imgNum); % ランダムに呈示するため
        
        for i = 1 : imgNum % 1ブロックの試行数はフォルダ内の画像数
            
            % ファイル名の設定
            imgFileName = char(imgFileList(order(i)).name); % 画像のファイル名(フォルダ情報なし)
            imgFileName2 = [imgFolder imgFileName]; % 画像のファイル名(フォルダ情報あり)
                     
            %画像の読み込み
            imdata = imread(imgFileName2, 'jpg');
            %画像サイズの幅(ix)が列の数に相当し、画像サイズの高さ(iy)が行の数の相当。
            [iy, ix, id] = size(imdata);
            % 画像の情報をテクスチャに。
            imagetex = Screen('MakeTexture', windowPtr, imdata);
            
            Screen('TextSize', windowPtr, fontSize);
            if (trialNum ~= 0) && mod(trialNum, restNum) == 0 % 条件を満たしたら休憩。
                DrawFormattedText(windowPtr, double('休憩をして下さい。スペースキーで再開です。'), 'center', 'center', [255 255 255]);
            else
                DrawFormattedText(windowPtr, double('スペースキーを押して下さい。'), 'center', 'center', [255 255 255]);
            end;
                
            Screen('Flip', windowPtr); % 画面にメッセージを呈示
            
            while KbCheck; end; % いずれのキーも押していないことを確認
            while 1 % while 文の中をぐるぐる回ります。
                [ keyIsDown, keyTime, keyCode ] = KbCheck; % キーが押されたか、そのときの時間、どのキーか、の情報を取得する
                if keyIsDown
                    if keyCode(KbName('ESCAPE'))
                        error('ESCキーが押されました'); % 強制終了
                    end
                    if keyCode(KbName('SPACE')) % 
                        break; % while文を抜ける。
                    end;
                    while KbCheck; end;                    
                end;
            end;
                      
            % 凝視点の呈示
            Screen('DrawLines', windowPtr, fixApex, 4, [0 0 0], centerPos, 0);
            vbl1 = Screen('Flip', windowPtr); % vbl1は凝視点を呈示した時間
            % 画像の呈示
            tmp = [ix, iy]*imgRatio;
            Screen('DrawTexture', windowPtr, imagetex, [], [centerPos - tmp/2, centerPos + tmp/2]);
            vbl2 = Screen('Flip', windowPtr, vbl1 + fixTime - ifi / 2); % vbl1からfixTime秒後に刺激画像を画面に呈示
            
            % 回答を待つ
            while KbCheck; end; % いずれのキーも押していないことを確認
            while 1 % while 文の中をぐるぐる回ります。
                [ keyIsDown, keyTime, keyCode ] = KbCheck; % キーが押されたか、そのときの時間、どのキーか、の情報を取得する
                if keyIsDown
                    if keyCode(KbName('F'))
                        kaito = 1;
                        break;
                    end;
                    
                    if keyCode(KbName('J'))
                        kaito = 2;
                        break;
                    end;
                    
                    % キーを離したかどうかの確認
                    while KbCheck; end
                end;
            end;
                        
            % データの記録(1行にまとめて書いてもよい)
            fprintf(Fid, '%d,%d,%s,%d', k, i, imgFileName, kaito);
            fprintf(Fid, '%f,%f\n', (keyTime - vbl2) * 1000, (vbl2 - vbl1) * 1000);
            
            trialNum = trialNum + 1;
            Screen('Close'); % テクスチャ情報を破棄
        end;
    end;
    DrawFormattedText(windowPtr, double('実験は終わりです。'), 'center', 'center');
    Screen('Flip', windowPtr);
    KbWait([], 3);
 
    %終了処理
    fclose(Fid); % ファイルを閉じる。
    Screen('CloseAll');
    ShowCursor;
    ListenChar(0);
 
catch % 以下はプログラムを中断したときのみ実行される。
    if exist('Fid', 'var') % ファイルを開いていたら閉じる。
        fclose(Fid);
        disp('fclose');
    end;
    
    Screen('CloseAll');
    ShowCursor;
    ListenChar(0);
    psychrethrow(psychlasterror);
end