从今天开始,我打算边解释 PTB 自带的 demo 程序,边讲解一些涉及到的知识点,这样进度会快一点。
PTB 的 demo 可以在 Psychtoolbox Demos 网站上获取。另外,在安装目录的 PsychDemos
文件夹下也有大量的 demo 程序。
这次介绍下 Screen 的窗口操作。
在屏幕上显示一些内容,是我们用得最多的功能。要在屏幕上显示内容,需要先打开一个窗口。
Psychtoolbox Demos 网站上的第一个 demo 就演示了如何打开窗口,并获得一些其他信息。
% 第一块 Clear the workspace and the screen
sca;
close all;
clearvars;
% 第二块 Here we call some default settings for setting up Psychtoolbox
PsychDefaultSetup(2);
% 第三块 Get the screen numbers. This gives us a number for each of the screens
% attached to our computer.
screens = Screen('Screens');
% 第四块 To draw we select the maximum of these numbers. So in a situation where we
% have two screens attached to our monitor we will draw to the external
% screen.
screenNumber = max(screens);
% 第五块 Define black and white (white will be 1 and black 0). This is because
% in general luminace values are defined between 0 and 1 with 255 steps in
% between. All values in Psychtoolbox are defined between 0 and 1
white = WhiteIndex(screenNumber);
black = BlackIndex(screenNumber);
% 第六块 Do a simply calculation to calculate the luminance value for grey. This
% will be half the luminace values for white
grey = white / 2;
% 第七块 Open an on screen window using PsychImaging and color it grey.
[window, windowRect] = PsychImaging('OpenWindow', screenNumber, grey);
% 第八块 Now we have drawn to the screen we wait for a keyboard button press (any
% key) to terminate the demo.
KbStrokeWait;
% 第九块 Clear the screen.
sca;
运行程序时,要记得把除了 matlab 以外的其他程序,能关闭退出的全都关闭退出,不然,有可能会出现 synchronization error.
最先要学习的是这个 demo 的注释风格,当然,我们自己熟练以后,可能不需要这么详细。但是为了交流方便,注释越详细越好。
为了指代方便,后面我会把 demo 程序里面每个用空白行分隔开的代码称为 “ 代码块 ”。比如,demo 中的前四行,就是第一个代码块(我在注释中也添加了这个描述),这当中,只有第一行是注释,后三行都是可执行的程序语句。
第一个代码块主要是做了一些准备工作,几乎每个程序都有,所以几乎都是约定俗成了,每个程序的头几行都是这个。
sca
是 Screen (' CloseAll' )
的简写。其功能就是关闭所有由 PTB 打开的窗口。
close all
是关闭所有 matlab 打开的图形窗口(如用 plot
命令画出来的函数图)。
clearvars
是清空所有的变量。
第二个代码块是载入默认的设置,这个不管了,一般我们都用这个 demo 里的设置。有兴趣的也可以自己 help PsychDefaultSetup
看看,内容也不难。
第三块和第四块的代码是为了获取当前要操纵的屏幕代号,这个代码是用数字标示的。
一般情况下,我们都只有一个屏幕,但有时候我们一台电脑上连接着多个显示器,那么这不同的显示器,我们怎么区分?
windows 操作系统用数字编号来区分,在我们看来就是 0 号显示器,1 号显示器这类的区别。
当只有一个显示器的时候,你使用的显示器叫 0 号显示器,每添加一块显示器,那个显示器的编号就增加1,如第二块显示器就是 1 号显示器,第三块就叫 2 号显示器,以此类推。
不同操作系统上,这种设置可能不同,但大体规则如此。
还有个方法就是在 windows 设置的显示属性中有一个按钮叫 “检测”(有些版本是 “识别” 按钮, 如在 win 7 系统中),你点一下它,windows 会在不同的显示器上显示一个大大的透明数字,告诉你这些显示器分别是几号显示器。
回到这个代码中来,它用了两行代码来获取当前显示器的数字编号。
先是使用 screens = Screen ('Screens')
获得当前系统连接了哪些显示器,返回值是一个单行矩阵,它存储了所有的显示器编号。
例如,有两块显示器,那 screens
的值就是 [0 1]
。
然后 screenNumber = max ( screens )
取变量 screens 中的最大值,按上例的话,那意味着后面的一系列操作都只是在 1 号显示器上进行。当然,如果只有一块显示器,后面的一系列操作都是在当前显示器上进行。
第五、六代码块涉及到颜色操作的问题,今天不讨论,大家知道,经过这两块代码后,我们获得了灰色值,并且把它存储在变量 gray
中。
第七块代码的功能是打开一个窗口,后面接着解释它。
第八块代码涉及到了键盘输入的问题,今天也不讨论,只需要知道,它会一直等着你按一个键,按任意键以后,执行其后的语句,也就是第九块代码 sca
, 程序就结束了。
总之,这个程序的功能很简单,打开一个灰色的全屏窗口,按任意键后程序结束。
第七块代码才是我们今天要说的重点。
[window, windowRect] = PsychImaging('OpenWindow', screenNumber, grey);
PsychImaging
这个函数的帮助文档,内容比较多,说的多是一些技术细节,干脆也不管了,只管这个具体用法。
实际上,这个函数接受了三个参数,第一个参数 OpenWindow
是一个指令,告诉它我要做的事情是打开一个窗口;第二个参数是告诉它我在哪个显示器上打开窗口;最后一个参数是指定了这个窗口的颜色。所以,你运行这个程序以后,它就打开了一个灰色的窗口,还是全屏的。
它的返回值,有两个。第一个返回值 window
可以理解为你打开的那个窗口的名字。以后呈现刺激、显示指导语等工作,就是对这个窗口来操作的。
请注意,窗口要在某个显示器中打开,具体的一些视觉刺激的呈现工作要在打开的那个窗口中操作,这个待操作的窗口用某个变量指代,如这里的 window
。请不要弄混了。
返回值 windowRect
,给出了打开的窗口大小,它是用一对坐标值描述,所以你运行完程序以后,在左边的变量列表中可以看到 windowRect
的值。比如,我这里的结果是 [ 0 0 2560 1440 ]
简单介绍一下显示器的坐标系。我们知道,显示器还有一个很重要的参数是分辨率,如我的显示器分辨率是 2560 X 1440
,这意味着,这块显示器横向上有 2560 个像素点,纵向上有 1440 个像素点,一共有 3686400 个像素点。
这每个像素点都有对应的一个坐标,这个坐标系可以用下面的图来表示:
![](https://img.haomeiwen.com/i8678012/96305981cc01ac45.png)
左上角的那个是起点,右下角的才是这个显示器最大分辨率的位置。显然,对于一个矩形来说,只需要给出两个坐标点就可以描述这个矩形。PTB 就是这样做的,对于任意一个矩形,只给出左上角和右下角的像素点坐标。
现在,我们能理解 PsychImaging
打开一个窗口以后,返回windowRect
值的意义了。[0 0 2560 1440]
这个矩阵的前两个值是矩形左上角那个点的坐标,后两个值是矩形右下角那个点的坐标。显然,这个矩阵的大小信息,我们也能知道。
据此,我们还可以获得其他信息,如屏幕的中心位置在哪里?还有,如果想把一个宽为 400 像素,高为 300 像素的矩形放到屏幕的中心,那么这个矩形的位置坐标应该是什么?这些问题,大家可以思考下。
网友评论