画像の印象評定2
画像の印象評定 の改良版です。
主な変更点は画像のファイル名を自由に設定できる点です。
imagesという名前のフォルダに存在する、すべてのjpg形式の画像を自動的に抽出して、印象評定を行います。
(日本語を表示するプログラムとしても参考になるかと思います)
function InsyoHyotei3
% 画像(JPEG形式)を呈示して印象評定を行うプログラムです。
% 質問項目は7件法で回答します。
%
% 1から7のテンキーを押すと、対応する場所に○がつきます。
% スペースキーで回答を決定し、次の質問に変わります。
% すべての質問に回答すると、次の画像に変わります。
%
% プログラムと同じフォルダに「images」という名前のフォルダを作り
% そこに呈示したいすべての画像を保存します。
%
% 出力ファイルは「プログラムと同じフォルダ 」にできます。
%
% プログラムを起動するとコマンドウィンドウ上に Name? と表示されるので実験参加者名を入力してください。
%----------------------------------------
% 以下の変数を必要に応じて変更してください
%
imgRatio = 0.5; % 画像の拡大縮小率。1のとき原画像のサイズ
fontSize = 30; % フォントサイズ
bgColor = [128 128 128]; % 背景色
%評定用(7件法)の線分
% 5件法のときなどは適宜変更をしてください。
LineKankaku = 50; %垂直線分の間隔
LineNagasa = 30; %垂直線分の長さ
LineHaba = 2; %線分の幅
LineVertPos = 600; %水平線分の垂直方向の位置
LineColor = [255 255 255];
%線分を描画するための座標。転置行列であることに注意
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 = {
'嫌いな' '好きな';
'暗い' '明るい'
'美しくない' '美しい'};
% 質問項目の微調整
blank1 = 10; % 線分の端と質問項目とのあいだ
blank2 = -10; % 質問項目の垂直位置
%評定の回答円の半径
Radius = 10;
%---- 以下プログラム ---
% 実験参加者名の入力
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
try
AssertOpenGL;
ListenChar(2);
%OSで共通のキー配置にする
KbName('UnifyKeyNames');
%myKeyCheck;
%あらかじめ読み込んでおく必要がある関数たち
GetSecs;
WaitSecs(0.1);
rand('state', sum(100*clock)); % 古いMatlab
%rng('shuffle') % 新しいMatlab
HideCursor;
screenNumber = max(Screen('Screens'));
%ウィンドウモード
%[windowPtr, windowRect] = Screen('OpenWindow', screenNumber, bgColor, [50 50 1000 700]);
%フルスクリーンモード
[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, 'fontSize,%d\n', fontSize);
fprintf(Fid, 'ifi (ms),%f\n', ifi * 1000);
fprintf(Fid, '%s\n', '');
% 出力ファイルの見出し
fprintf(Fid, '試行,ファイル,');
for i=1:size(Question, 1)
fprintf(Fid, '%s,', char(Question(i, 2)));
end;
fprintf(Fid, '\n'); % 改行
%order = [1:imgNum]; % 刺激をランダムに呈示しないとき
order = randperm(imgNum); % 刺激をランダムに呈示するとき
for i = 1:imgNum
imgFileName = char(imgFileList(order(i)).name); % 画像のファイル名(フォルダ情報なし)
imgFileName2 = [imgFolder imgFileName]; % 画像のファイル名(フォルダ情報あり)
fprintf(Fid, '%d,%s,', i, imgFileName);
%画像情報をテクスチャに
imdata = imread(imgFileName2, 'jpg');
[iy, ix, id] = size(imdata);
imagetex = Screen('MakeTexture', windowPtr, imdata);
Screen('FillRect', windowPtr, bgColor);
Screen('TextSize', windowPtr, fontSize);
DrawFormattedText(windowPtr, double('スペースキーを押してください'), 'center', 'center', LineColor);
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;
firstFlag = 1;
OvalCnt = 0; %回答円の場所を示す
QCnt = 1; %何番目の質問か
% 背景色を画像の背景と合わせたいときはコメントを解除してください。
% ここでは画像ファイルの(10, 10)の座標の色を背景色として設定しています。
% tmpR = imdata(10,10,1);
% tmpG = imdata(10,10,2);
% tmpB = imdata(10,10,3);
% Screen('FillRect', windowPtr, [tmpR tmpG tmpB]);
while 1
if firstFlag
firstFlag = 0;
else
%キー入力を待つ
[secs, keyCode]=KbWait([],3);
if keyCode(KbName('ESCAPE')) %プログラムの強制終了
error('ESCキーが押されました'); % 強制終了
end;
if keyCode(KbName('space'))
if OvalCnt ~= 0
fprintf(Fid, '%d,', OvalCnt);
QCnt = QCnt + 1; %次の質問へ
%ある画像について全部の質問に答えたら
if QCnt > size(Question, 1)
fprintf(Fid, '\n'); % 改行
break; % while文を抜ける
else
OvalCnt = 0; %回答円を消去(未回答の状態にする)
end;
end;
end;
if keyCode(KbName('1'))
OvalCnt = 1;
end;
if keyCode(KbName('2'))
OvalCnt = 2;
end;
if keyCode(KbName('3'))
OvalCnt = 3;
end;
if keyCode(KbName('4'))
OvalCnt = 4;
end;
if keyCode(KbName('5'))
OvalCnt = 5;
end;
if keyCode(KbName('6'))
OvalCnt = 6;
end;
if keyCode(KbName('7'))
OvalCnt = 7;
end;
end;
% 画像の呈示
tmp = [ix, iy]*imgRatio;
Screen('DrawTexture', windowPtr, imagetex, [], [centerPos - tmp/2, centerPos + tmp/2]);
%評定用の線分
Screen('DrawLines', windowPtr, LinesXY, LineHaba, LineColor, [centerPos(1) LineVertPos]);
%線分に添える数字
for k = 1:7
tmpX = LinesXY(1,1) + LineKankaku*(k-1) + centerPos(1) + NumPosX;
tmpY = LineVertPos + NumPosY;
DrawFormattedText(windowPtr, num2str(k), tmpX, tmpY, LineColor);
end;
%質問対の描画
QL = char(Question(QCnt,1)); %質問対の左側の文字
QR = char(Question(QCnt,2)); %質問対の右側の文字
[BoundsRect, offsetBoundsRect]= Screen('TextBounds', windowPtr, QL);
sx = centerPos(1) + LinesXY(1) - BoundsRect(RectRight) - blank1;
sy = LineVertPos + blank2;
DrawFormattedText(windowPtr, double(QL), sx, sy, LineColor); % 質問左
sx = centerPos(1) + LinesXY(end-1) + blank1;
DrawFormattedText(windowPtr, double(QR), sx, sy, LineColor); % 質問右
%回答円の描画
if OvalCnt > 0
tmp = [LinesXY((OvalCnt-1)*4 + 1) + centerPos(1), LineVertPos];
Screen('FrameOval', windowPtr, [255 0 0], [tmp - Radius, tmp + Radius]);
end;
Screen('Flip', windowPtr);
%次の行でキーボードから手を離したことを確認している
while KbCheck; end;
end
end;
fclose(Fid); % ファイルを閉じる。
DrawFormattedText(windowPtr, double('実験は終了です。お疲れさまでした。'), 'center', 'center', LineColor);
Screen('Flip', windowPtr);
KbWait([],3);
sca;
ShowCursor;
ListenChar(0);
%psychrethrow(psychlasterror);
catch
if exist('Fid', 'var') % ファイルを開いていたら閉じる。
fclose(Fid);
disp('fclose');
end;
sca;
ShowCursor;
ListenChar(0);
psychrethrow(psychlasterror);
end;