MATLAB Answers

0

Wacomタブレット 文字表示 数値化

タブレットにペンで書いたものを、X軸、Y軸、Z軸のデータで読み込み表示することを行っています。
wacomタブレットを用いて下記のコードを元に数値を取り込んでいます。 数値としてデータを読み込むことまではできたのですが、読み込みの際にタブレットに書いているものを表示できていないので、読み込みの際に書いている文字などが表示されるようにし、読み込みが終わると数値が表示されるようにしたいです。
ここでウィンドウを開いているのですがデータを読み込む際に画面すべてを使うのではなく、小さいウィンドウのようなものに表示するようにしたいのですが、どのように定義したらよいかわかっていません。
try
[wPtr rect] = Screen('OpenWindow', 0);
WinTabMex(0, wPtr);
使用中のコード
function fastLoop
% function fastLoop
%
% PTB画面を開き、関連付けられた画面ポインタwPtrにタブレットを接続し、イベントキューの内容をダンプします。
%
%
% pkt = WinTabMex(5)タブレットのイベントキューから最新のデータポイントを読み込みます。このキューは約50のデータポイントを保持できるバッファです。
% このキューは、キューを空にするWinTabMex(2)への呼び出しの後に満ちあがり、
% 高速ループ'(fastLoop.m参照)での刺激提示中に運動データを記録するために使用できます。
%
% pktは8x1の列ベクトルです
%
% tabletTestData.mat:
% xPos = pkt(1), x軸の位置(タブレット座標)
% yPos = pkt(2), y軸の位置(タブレット座標)
% zPos = pkt(3), z軸の位置(タブレット座標)
% buttonState = pkt(4), エンコードされたボタンの状態(少し不規則に動作します)
% serialNumber = pkt(5)
% tabletTimeStamp = pkt(6), タブレットからの時間(ミリ秒)
% penStatus = pkt(7), さまざまなイベントを通知します(例:penOutOfRange)
% penChange = pkt(8), 最後のサンプルから何が変更されたかを示すフラグ
%
%pkt(1:6)は単純ですが、pkt(7:8)はそれが何を意味するか
%
%Andrew D. Wilson, 2009 (adwkiwi@gmail.com)
KbName('UnifyKeyNames');
spaceKeyID = KbName('space');
data = [];
try
[wPtr rect] = Screen('OpenWindow', 0);
WinTabMex(0, wPtr); %タブレットドライバを初期化し、 'wPtr'に接続します。
%PTB things
Priority(1);
ListenChar(2);
HideCursor;
black = BlackIndex(wPtr);
white = WhiteIndex(wPtr);
%*******************************************************************************************
%ウィンドウをロードし、入力を待って録音を開始します。
instructions = 'Place the stylus on the tablet and press the space bar to begin recording';
[instructionsX instructionsY] = centreText(wPtr, instructions, 15);
Screen('DrawText', wPtr, instructions, instructionsX, instructionsY, black); Screen(wPtr, 'Flip');
%スペースバーを待つ
[keyIsDown, secs, keyCode] = KbCheck;
while keyCode(spaceKeyID)~=1
[keyIsDown, secs, keyCode] = KbCheck;
end
%*******************************************************************************************
WinTabMex(2); %実際のデータを収集するためにパケットキューを空にします。
information = 'Event queue is filling up...you will be able to retrive up to 50 events (500ms @ 100Hz)';
[informationX informationY] = centreText(wPtr, information, 15);
Screen('DrawText', wPtr, information, informationX, informationY, black);
Screen(wPtr, 'Flip');
WaitSecs(3);
%キューからすべてのデータを変数にダンプする高速ループ。 WintabMex(5)を呼び出すたびに、データポイントがキューの先頭から取り出され、
%このループは、Matlabがキューが排水されるまで実行できるように速く実行されます
%
%注意:データが収集された後、キューを排水するこのループが実行されます
while 1
pkt = WinTabMex(5);
if isempty(pkt) %キューが空です
data = [data zeros(9,1)]; %breakが呼び出されたことを示す
break;
else
data = [data pkt];
end
status = uint32(pkt(7));
if bitget(status, 1)
disp('Pen is outside the tablet');
end
if bitget(status, 2)
disp('Queue overflow - packets getting lost');
end
end
data = data' %Matlabのメモリ環境設定が行や列などを扱う方法に合わせてこのようにします
samplingRate = 1000 / mean(diff(data(1:end-1,6)));
disp(['Your sampling rate appears to be ', int2str(samplingRate), 'Hz.']);
endInstructions = 'Queue drained...pull the stylus away from the tablet';
[endX endY] = centreText(wPtr, endInstructions, 15);
Screen('DrawText', wPtr, endInstructions, endX, endY, black); Screen(wPtr, 'Flip');
WaitSecs(3);
WinTabMex(3); %データ収集を停止/一時停止します。
WinTabMex(1); % シャットダウンドライバ.
ListenChar(1); ShowCursor;
Screen('CloseAll');
catch
disp('Quit with error (wintabfastLoop.m)');
WinTabMex(3); WinTabMex(1);
ListenChar(1); ShowCursor;
Screen('CloseAll');
tabletTestError = lasterror;
message = tabletTestError(1).message
identifier = tabletTestError(1).identifier
stack = tabletTestError(1).stack;
file = stack.file
line = stack.line
end
function [x y] = centreText(wPtr, text, preferredFontSize)
%function [x y] = centreText(wPtr, text, preferredFontSize)
%
%Psychtoolboxで使用する場合。
%ウィンドウのポインタと文字列を受け取り、Screen( 'DrawText')に入力された場合にテキストを中央に配置するx、y座標を返します
%
%議論:
%wPtr = Screen( 'OpenWindow')への呼び出しによって返されたウィンドウポインタ
%text =画面に送信する文字列
%preferredFontSize =あなたが望む最大サイズのフォント。テキストが大きすぎる場合、
% centreTextは動作するまでテキストサイズを循環させ、最大のサイズに設定します
%
%戻り値:
%[x y] =(x、y)座標を中心とするベクトルです。
%
%NB Screen( 'OpenWindow')を使用する必要があります
%
%Andrew D. Wilson (v1.0.3; 11 April 2008)
x=-1; y=-1; %ループを1回実行できるようにする
while x<0
Screen('TextSize', wPtr, preferredFontSize);
[normBoundsRect, offsetBoundsRect]= Screen('TextBounds', wPtr, text);
rect = Screen('Rect', wPtr);
windowCentre = [rect(3)/2 rect(4)/2];
textCentre = [normBoundsRect(3)/2 normBoundsRect(4)/2];
x = windowCentre(1) - textCentre(1);
y = windowCentre(2) - textCentre(2);
if x < 0 || y < 0 %つまり、テキストが画面外に描画された場合
preferredFontSize = preferredFontSize-1;
end
end
return;

  0 Comments

Sign in to comment.

1 Answer

Answer by Hirokazu Tanaka on 20 Oct 2018
 Accepted Answer

 [wPtr rect] = Screen('OpenWindow', 0);

の部分の変更方法が分かれば・・と TabletDemo_README.pdf を見てみると、下記の呼び出しをしてました。

 wPtr = Screen('OpenWindow', 0, 0, [0 0 30 30]);

[0 0 30 30] の部分でWindowサイズを指定できるみたいですね。左から

  • スクリーン左上から、立ち上げる画面の左上までのピクセル数(横)
  • スクリーン左上から、立ち上げる画面の左上までのピクセル数(縦)
  • 立ち上げる画面の幅(ピクセル数)
  • 立ち上げる画面の高さ(ピクセル数)

を表すようです。ただ全画面起動以外では Psychotoolbox 側での何らかのチェックに引っかかるようですが、詳細は私も分かりません。

http://psychtoolbox.org/docs/Screen も参考にしました。こちらは Screen関数の使い方が羅列されていますが、いまいちよくわかりません・・。

  15 Comments

参考にしてみます。 ありがとうございます。
よろしければ、また何かあったときは質問させてください。
Kazuya
on 24 Oct 2018
Good luck :)
タブレットからの記録が始まってからfigureが表示され、線が表示されているのですが、現状では最初の方のデータがうまくデータをとれず、直線になってしまいます。そこで、実行したときに、先にfigureを表示しておき、そこに読み込んだデータをもとに線を表示したいのですが、どのようようにしたらfigurを先に表示し、そこに線を表示できるかわかりますでしょうか。
また、記録時間が短く、その時間を長くしたいと思っていて、WinTabMex(4)というものが、デフォルトではWinTabMex(4)=50;になっているみたいで、50を変更したら長くできるのではないかと思っているのですが、変更の仕方がわかりません。コードにも定義されていないので、どこに定義したらいいかわかっていません。
上記二つもし少しでも教えていただけるとありがたいです。 私がやりたいことに似たようなものでもいいので何か参考にさせてもらいたいです。お願いします。

Sign in to comment.