下記プログラムの改良版 画像の印象評定2 があります。特に理由がなければ改良版をお勧めします。
パソコン上に画像を提示し、その印象評定を7件法で行うサンプルプログラムです。
実際に実験を行う際は、プログラムが正しく動いているか十分に動作確認をしてください。
以下のサンプルプログラムを動かすには、プログラムと同じフォルダに
Images
というフォルダを作り、その中にjpeg形式の画像を3枚保存してください。
画像ファイル名は
1.jpg
2.jpg
3.jpg
としてください。
function InsyoHyotei% 画像(JPEG形式)を呈示して印象評定を行うプログラムです。% 質問項目は7件法です。% 1から7のテンキーを押すと、対応する場所に○がつきます。% 0(ゼロ)で回答を決定し、次の質問に変わります。% すべての質問に回答すると、次の画像に変わります。%% 画像ファイルは、プログラムと同じフォルダに「Imagesという名前のフォルダ 」を作り% そこに 1.jpg などを置いておくこと。%% 実験データは「プログラムと同じフォルダ 」にできます。%% SubNameは結果を出力するファイル名に使われる% 実験参加者名の入力SubName = input(['Name? '], 's'); % 名前をたずねるif isempty(SubName) % 名前の入力がなかったらプログラムを終了 return;end;try AssertOpenGL; ListenChar(2); %OSで共通のキー配置にする KbName('UnifyKeyNames'); %myKeyCheck; %あらかじめ読み込んでおく必要がある関数たち GetSecs; WaitSecs(1); rand('state', sum(100*clock)); HideCursor; screenNumber = max(Screen('Screens')); %ウィンドウモード %[windowPtr, windowRect] = Screen('OpenWindow', screenNumber, BlackIndex(screenNumber), [50 50 1000 700]); %フルスクリーンモード [windowPtr, windowRect] = Screen('OpenWindow', screenNumber, BlackIndex(screenNumber)); %画面の中央の座標 [centerX centerY] = RectCenter(windowRect); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 以下の変数を必要に応じて変更してください % imgNum = 3; %呈示する画像の枚数 imgRatio = 0.5; %画像を拡大縮小して呈示するときの割合。1のとき原画像のサイズ %評定用(7件法)の線分 % 5件法のときなどは適宜変更をしてください。 LineKankaku = 50; %垂直線分の間隔 LineNagasa = 30; %垂直線分の長さ LineHaba = 2; %線分の幅 LineVertPos = 600; %水平線分の垂直方向の位置 %線分を描画するための座標。転置行列であることに注意 LinesXY = [ LineKankaku*(-3) -LineNagasa/2 LineKankaku*(-3) LineNagasa/2 LineKankaku*(-2) -LineNagasa/2 LineKankaku*(-2) LineNagasa/2 LineKankaku*(-1) -LineNagasa/2 LineKankaku*(-1) LineNagasa/2 0 -LineNagasa/2 0 LineNagasa/2 LineKankaku*(1) -LineNagasa/2 LineKankaku*(1) LineNagasa/2 LineKankaku*(2) -LineNagasa/2 LineKankaku*(2) LineNagasa/2 LineKankaku*(3) -LineNagasa/2 LineKankaku*(3) LineNagasa/2 LineKankaku*(-3) 0 LineKankaku*(3) 0 ]'; %線分の番号の微調整 NumPosX = -7; NumPosY = -50; %質問項目 Question = { '嫌いな' '好きな'; '暗い' '明るい' '美しくない' '美しい'}; QLPos = 220; %質問項目(左)の水平位置 QRPos = 650; %質問項目(右)の水平位置 QYPos = LineVertPos - 20; %質問項目の垂直位置(微調整が必要) %評定の回答円の半径 Radius = 10; % 被験者の回答を記録する行列 % 1列目は画像ファイルの番号 % 2列目は1つ目の質問 % 3列目は2つ目の質問 Answer = zeros(imgNum, size(Question, 1)+1); CancelFlag = 0; %1になるとプログラムの強制終了 %order = [1:imgNum]; % 刺激を番号順で呈示するとき order = randperm(imgNum); % 刺激をランダムに呈示するとき for i = 1:imgNum %呈示する画像ファイル名(win) myimgfile = ['Images\' int2str(order(i)) '.jpg']; %呈示する画像ファイル名(mac) myimgfile = ['Images/' int2str(order(i)) '.jpg']; %画像情報をテクスチャに imdata = imread(myimgfile, 'jpg'); [iy, ix, id] = size(imdata); imagetex = Screen('MakeTexture', windowPtr, imdata); DrawFormattedText(windowPtr, 'スペースキーを押してください', 'center', 'center', WhiteIndex(windowPtr)); %メッセージを呈示 Screen('Flip', windowPtr); DrawFlag = 0; %刺激を提示してよいかどうか OvalCnt = 0; %回答円の場所を示す QCnt = 1; %何番目の質問か NumKeyFlag = 0; %数字キーを押すと1になる tmpAns = 0; %現在の質問に対する回答(0キーで決定する前) SpaceFlag = 0; %スペースキーを押した後かどうか while 1 %キー入力を待つ [secs, keyCode]=KbWait([],3); if keyCode(KbName('ESCAPE')) %プログラムの強制終了 CancelFlag = 1; break; end; if keyCode(KbName('space')) DrawFlag = 1; SpaceFlag = 1; end; %0キーを押すと回答が決定 if keyCode(KbName('0')) %回答を決定してよい状態だったら if NumKeyFlag == 1 Answer(i, QCnt+1) = tmpAns; %1列目には画像ファイルの番号が入る QCnt = QCnt+1; %次の質問へ NumKeyFlag = 0; %ある画像について全部の質問に答えたら if QCnt > size(Question, 1) Answer(i, 1) = order(i); %呈示した画像ファイルの番号 QCnt = 1; break; else OvalCnt = 0; %回答円を消去 DrawFlag = 1; end; end; end; if keyCode(KbName('1')) && SpaceFlag [DrawFlag, NumKeyFlag, OvalCnt, tmpAns] = SetAns(1); end; if keyCode(KbName('2')) && SpaceFlag [DrawFlag, NumKeyFlag, OvalCnt, tmpAns] = SetAns(2); end; if keyCode(KbName('3')) && SpaceFlag [DrawFlag, NumKeyFlag, OvalCnt, tmpAns] = SetAns(3); end; if keyCode(KbName('4')) && SpaceFlag [DrawFlag, NumKeyFlag, OvalCnt, tmpAns] = SetAns(4); end; if keyCode(KbName('5')) && SpaceFlag [DrawFlag, NumKeyFlag, OvalCnt, tmpAns] = SetAns(5); end; if keyCode(KbName('6')) && SpaceFlag [DrawFlag, NumKeyFlag, OvalCnt, tmpAns] = SetAns(6); end; if keyCode(KbName('7')) && SpaceFlag [DrawFlag, NumKeyFlag, OvalCnt, tmpAns] = SetAns(7); end; if DrawFlag %画像を描画(拡大縮小にも対応) x1 = centerX-(ix/2)*imgRatio; y1 = centerY-(iy/2)*imgRatio; x2 = centerX+(ix/2)*imgRatio; y2 = centerY+(iy/2)*imgRatio; Screen('DrawTexture', windowPtr, imagetex, [], [x1 y1 x2 y2]); %評定用の線分 Screen('DrawLines', windowPtr, LinesXY, LineHaba, WhiteIndex(windowPtr), [centerX LineVertPos]); %線分に添える数字 for k = 1:7 tmpX = LinesXY(1,1) + LineKankaku*(k-1) + centerX + NumPosX; tmpY = LineVertPos + NumPosY; DrawFormattedText(windowPtr, int2str(k), tmpX, tmpY, WhiteIndex(windowPtr)); end; QL = char(Question(QCnt,1)); %質問対の左側の文字 QR = char(Question(QCnt,2)); %質問対の右側の文字 %質問対の描画 DrawFormattedText(windowPtr, QL, QLPos, QYPos, WhiteIndex(windowPtr)); DrawFormattedText(windowPtr, QR, QRPos, QYPos, WhiteIndex(windowPtr)); %回答円の描画 if OvalCnt > 0 x1 = LinesXY((OvalCnt-1)*4+1)+centerX-Radius; y1 = LineVertPos-Radius; x2 = LinesXY((OvalCnt-1)*4+1)+centerX+Radius; y2 = LineVertPos+Radius; OvalRect = [x1 y1 x2 y2]'; Screen('FrameOval', windowPtr, [255 0 0], OvalRect); end; Screen('Flip', windowPtr); DrawFlag = 0; end; %次の行でキーボードから手を離したことを確認している while KbCheck; end; end %次の行でキーボードから手を離したことを確認している while KbCheck; end; if CancelFlag DrawFormattedText(windowPtr, 'プログラムを強制終了しました。何かキーを押してください。', 'center', 'center', WhiteIndex(windowPtr)); Screen('Flip', windowPtr); KbWait([],3); break; end; end; %データの保存 tmpStr = ['ファイル,']; for i=1:size(Question, 1) tmpStr = [tmpStr char(Question(i, 2)) ',']; end; SaveFileName = [SubName '.csv']; Fid = fopen(SaveFileName, 'wt'); fprintf(Fid, '%s\n', SubName); fprintf(Fid, '%s\n', datestr(now, 'yy-mmdd-HH:MM')); fprintf(Fid, '%s\n', tmpStr); fprintf(Fid, '%d,%d,%d,%d\n', Answer'); %転置行列になっていることに注意 fclose(Fid); DrawFormattedText(windowPtr, '実験は終了です。お疲れさまでした。', 'center', 'center', WhiteIndex(windowPtr)); Screen('Flip', windowPtr); KbWait([],3); sca; ListenChar(0); %psychrethrow(psychlasterror);catch sca; ListenChar(0); psychrethrow(psychlasterror);end;function [DrawFlag, NumKeyFlag, OvalCnt, tmpAns] = SetAns(NumKey) OvalCnt = NumKey; DrawFlag = 1; NumKeyFlag = 1; tmpAns = NumKey;