Creating Stimuli Digitally*

Creating Stimuli Digitally*

7 Creating Stimuli Digitally In order to create a set of stimuli of the same type (e.g. 10 horizontal lines of 5–10 centimeters), we are often tempte...

5MB Sizes 0 Downloads 61 Views

7 Creating Stimuli Digitally

In order to create a set of stimuli of the same type (e.g. 10 horizontal lines of 5–10 centimeters), we are often tempted to use some classical graphic design software such as Photoshop/Gimp/Inkscape to first create the stimuli, before saving them separately in 10 different files, all named manually. However, doing this for 100 stimuli is not only time-consuming and labor-intensive, but also likely to accrue a variety of handling errors. MATLAB® lets us easily create images, as they are considered to be matrices of numbers corresponding to colors for each of the pixels. Here we look at some simple examples that highlight the benefits of MATLAB® programming in the creation of digital images. We shall see that the programs used allow us to automatically create and save stimuli with a single click of the mouse. With just a few parameters, we can recreate the same stimuli as much as we want, for example, if we want to change the screen resolution, or the background color, etc. 7.1. Overlaying stimuli The first example shows that, armed with a few basic notions, MATLAB® can help free our creative spirit. The following program allows us to overlay several images. This process could be used in a visual search task, for example. First, the program reads the pixels of each image, then

For a color version of the code appearing in this chapter, see www.iste.co.uk/mathy/ experiments.zip.

132

Experiments and Modeling in Cognitive Science

divides the amount of light by three in order to balance the final result (without this program it is likely to return a majority of white pixels) and, finally, adds the pixels together to come up with a new stimulus that is made up of objects from the three original images. The code used is basic.

Figure 7.1. For a color version of this figure, see www.iste.co.uk/mathy/experiments.zip

Code: %Reads the pixels pic1=imread('pic1.jpg'); pic2=imread('pic2.jpg'); pic3=imread('pic3.jpg'); %Balances the colors, dividing the values by 3 pic1new=0.33*pic1; pic2new=0.33*pic2; pic3new=0.33*pic3;

Creating Stimuli Digitally

133

%Adds the pixels of the 3 images, pixel by pixel combined = pic1new + pic2new+pic3new; %Displays the result image(combined); axis image; axis off Output

Figure 7.2. For a color version of this figure, see www.iste.co.uk/mathy/experiments.zip

We can quickly add a target (here a blue square) using the following piece of code. The value 256 of the RGB (Red Green Blue) vector gives us a blue pixel to draw with. We then just need to choose the location of the pixels (we randomly choose from the 50th pixel to the 70th, both horizontally and vertically). Here we can see the advantage of using MATLAB®, which allows us to assign a value to 400 pixels in one go and without using a loop. Code: % Draws a red square combined(50:70,50:70,3)=255; combined(50:70,50:70,1:2)=0; Output

134

Experiments and Modeling in Cognitive Science

Figure 7.3. For a color version of this figure, see www.iste.co.uk/mathy/experiments.zip

7.2. Create and combine various stimuli 7.2.1. Ten large stimuli of increasing size using linspace In order to create 10 stimuli of increasing size (e.g. 10 horizontal lines of 5–10 centimeters), we can use the function linspace to automatically calculate the intervals. This is very handy for creating continuous color variations, while maintaining regularly changing discrete values. The first code indicates that we want three regularly spaced numbers between 5 and 10, and the following code indicates that we want 10 regularly spaced numbers between 5 and 10. >> linspace(5,10,3) ans = 5.0000

7.5000 10.0000

>> linspace(5,10,10) ans = Columns 1 through 9 5.0000

5.5556

Column 10 10.0000 >>

6.1111

6.6667

7.2222

7.7778

8.3333

8.8889

9.4444

Creating Stimuli Digitally

135

The next step involves creating shapes and filling them in with a given color. The function fill accomplishes this perfectly. Since here we want a single line of visible thickness, we need to create rectangles. The function fill lets us draw a polygon as if we were using a felt pen without lifting it. We start with the south-west corner (x = 0 and y = 0), and move toward the south-east corner (x = 5 and y = 0), then to the north-east (x = 5 and y = .1), and finally move back to the north-west (x = 0 and y = .1). By default, fill completes the loop by returning to the south-west. The values that we have just described are present in the following program as the variables x = [0 5 5 0] and y = [0 0 .1 .1]. The final option 'g', gives us a green fill. The axis function lets us see the coordinates of the rectangle in a larger environment. Code: %% Draws a rectangle x=[0 5 5 0 ] y=[0 0 .1 .1] fill(x,y,'g') axis([0 10 -1 1]) Output

Figure 7.4.

In the following script, we generate 10 rectangles of increasing size, separated by a value of –.2 along the y axis. By default, the 10 rectangles are generated in different figures, but by using the function hold on, all of the rectangles appear in the same figure.

136

Experiments and Modeling in Cognitive Science

Code: %% Draws N rectangles of increasing size and places them in a single figure. %Parameters Nrectangles = 10 startLength =1 endLength =10 %Size lengthLine=linspace(startLength,endLength,Nrectangles) %Linespace creates a vector of N values in the interval [start, end] %Create the rectangles y=[0 0 .1 .1] shift =-.2 hold on %to keep drawing on the same page for lengthNum=1:Nrectangles x=[0 lengthLine(lengthNum) lengthLine(lengthNum) 0] y=y+ shift fill(x,y,'g') end axis off %hides the axes Output

Figure 7.5.

If we want to create 10 different figures, one for each of the rectangles, we need to comment (i.e. disable) the hold on command from the previous code and attribute a figure number to each iteration of the loop (figure(lengthNum)).

Creating Stimuli Digitally

137

Code: % hold on for lengthNum=1:Nrectangles figure(lengthNum) x=[0 lengthLine(lengthNum) lengthLine(lengthNum) 0] y=y+ shift fill(x,y,'g') axis([0 10 -2 2]) axis on end

7.2.2. A single cube The idea is then to generate all of the possible options for coloring the faces of the cube. %Build a cube vertex_matrix =[ 0 1 0 1 0 1 0 1

0 0 1 1 0 0

0 0 0 0 1 1 1 1

1 1]

faces_matrix=[ 1 2 6 5 %1st visible face 5 7 8 6 %2nd visible face 6 8 4 2 2 1 3 4 4 8 7 3 rd 3 7 5 1] %3 visible face gray= [

0 0.5 0 0 0 0 0 0 1 1

0 %1st color, black 0.5 0.5 %2 color, gray 0 %do not touch 0 %do not touch 0 %dondnot touch 1] %2 color, white 0

nd

patch('Vertices',vertex_matrix,'Faces',faces_matrix) patch('Vertices',vertex_matrix,'Faces',faces_matrix, 'FaceVertexCData',gray,'FaceColor','flat') view(3); axis square axis off % next, save as png for the background to be transparent

138

Experiments and Modeling in Cognitive Science

Figure 7.6. Output

7.2.3. Creating simple image stimuli, then varying colors of these stimuli Assume that, for a test, we need to create a set of stimuli whose shape and color characteristics must be varied. In this example, we want to present figures (triangles, squares, circles, etc.) and, for each of these figures, we want to have all the different possible color variations (blue triangle, green triangle, etc.). First of all, we need to create solid graphic shapes, convert them into images and then reproduce each of the shapes while changing their colors. Creating a square: % Drawing a square rectangle (’Position’, [0 0 3 3], ’FaceColor’, ’k’) % Draws a 3 by 3 rectangle axis off square ; box off % Removes the axes and frame of the graph saveas(gcf, ’stimulusSquare.png’) % Saves as image format png

Figure 7.7. Output

The following program (open drawfilledPolygons.m) allows for different shapes to be created automatically, with the color variations automatically applied afterward. We can also choose to automatically give the figure a name that specifies its shape and color. This method saves a considerable amount of time, and the possible changes that can be made are infinite. As a result, in order to modify one or several colors or shapes, we do not need to

Creating Stimuli Digitally

139

recreate each of the figures, and we just need to run the program again with different color (or shape) codes. A color image is usually made up of three levels of matrices, each coding for the three color levels: red, green and blue (RGB). Each color is therefore precisely defined by a vector of three values following an established standard, for example, in the decimal system, red is coded by [255 0 0], black by [0 0 0] and blue by [0 0 255]. The original figures in our example are all black with a see-through background. These image files must first be created; a vectorization technique (avoiding loops; this is the advantage of MATLAB®) then allows us to replace the black color with the desired colors. Next, the program saves and names each of the images created (imwrite function), so that the name provides the shape and color of the image, for example, 34.jpg corresponds to shape 3 and color 4. Finally, in order to include an elegant presentation of our stimuli in the experiment description, we can gather all of the figures created in order to visualize them in a single image. Code: %% This program allows us to create 8 simple stimuli (geometric shapes) with a black fill, and then to automatically change their color. In total the program generates 64 image stimuli as .jpg files, 8 shapes in 8 different colors each. cd('/Users/mchekaf/Desktop/manuelMatlab®/drawPolygons') % specifies the directory mkdir output % Creates and output folder and makes it the current directory cd('/Users/mchekaf/Desktop/manuelMatlab®/drawPolygons/output') clear;clc; % clears the command window and workspace ___________________________________________________________________ %% Creates a black triangle figure fig = gcf; fig.InvertHardcopy = 'off'; % Retain Current Background Color for output x = [0, 0.5, 1.0]; y = [0, 0.86, 0 ]; fill(x, y, 'k'); axis off; saveas(gcf,'stimulusTrianglepng’) ) % Saves in png image format

140

Experiments and Modeling in Cognitive Science

___________________________________________________________________ %% Creates a black square figure fig = gcf; fig.InvertHardcopy = 'off'; % Retain Current Background Color for output rectangle('Position',[0 0 3 3],'FaceColor','k') axis off square; box off saveas(gcf,'stimulusSquare.png') ) % Saves in png image format ___________________________________________________________________ %% Creates a black circle figure fig = gcf; fig.InvertHardcopy = 'off'; % Retain Current Background Color for output plot(.5, .5, '.k', 'MarkerSize',1150) axis off square; box off saveas(gcf,'stimulusCirclepng’) ) % Saves in png image format ___________________________________________________________________ %% Creates a black star figure; fig = gcf; fig.InvertHardcopy = 'off'; % Retain Current Background Color for output xc = 1.0; yc = 3.0; t = (-1/4:1/10:3/4)*2*pi; r1 = 0.5; r2 = 0.2; r = (r1+r2)/2 + (r1-r2)/2*(-1).^[0:10]; x = r.*cos(t) + xc; y = r2 - r.*sin(t) + yc; fill(x, y, 'k') axis off square; box off saveas(gcf,'stimulusStarpng’) ) % Saves in png image format ___________________________________________________________________ %% Creates a black cross figure ; fig = gcf; fig.InvertHardcopy = 'off'; % Retain Current Background Color for output rectangle('Position',[1 3 5 1],'FaceColor','k') rectangle('Position',[3 1 1 5],'FaceColor','k') axis off square; box off saveas(gcf,'stimulusCrosspng’) ) % Saves in png image format ___________________________________________________________________ %% creates a black pentagon figure; fig = gcf; fig.InvertHardcopy = 'off'; % Retain Current Background Color for output theta = [0:pi/2.5:2*pi];

Creating Stimuli Digitally

141

x = sin(theta); y = cos(theta); B(:,1) = x; B(:,2) = y; fill(x,y,'k'); axis off square; box off; saveas(gcf,'stimulusPentagonpng’) ) % Saves in png image format ___________________________________________________________________ %% creates a black spiral figure; fig = gcf; fig.InvertHardcopy = 'off'; % Retain Current Background Color for output turns=5; %Number of turns of the spiral x=-1*pi*turns : 0.02 : pi*turns; r=0:1/(length(x)-1):1; X=sin(x).*r; Y=cos(x).*r; plot(X,Y,'-k','LineWidth',15); axis off square box off saveas(gcf,'stimulusSpiralpng’) ) % Saves in png image format ___________________________________________________________________ %% creates a black flower figure; fig = gcf; fig.InvertHardcopy = 'off'; % Retain Current Background Color for output theta=linspace(0,2*pi,300); radius=cos(5*theta); radius(radius <= 0) = 0; x=radius.*(cos(2*theta)); y=radius.*(sin(2*theta)); fill(x,y, 'k'); axis('square') axis off saveas(gcf,'stimulusFlowerpng’) ) % Saves in png image format ______________________________________________________________ %% This part of the program lets us automatically change the color of the 8 stimuli created previously. In total the program generates 64 image stimuli as .jpg files, 8 shapes in 8 different colors each. % Creates the ‘colors’ table (RGB): black; blue; green; red; cyan; purple; yellow; gray colors=[0 0 0; 0 0 255; 0 255 0; 255 0 0; 0 255 255; 255 0 255; 255 255 0; 175 175 175]; filenames = dir('*.png' ); % lists the *.png files present in the folder filenames = {filenames.name}'; Nshapes=size(filenames,1);

142

Experiments and Modeling in Cognitive Science

imageCell={0}; %pre-allocation of variable(s) % integrates all of the images into a cell type group for pic=1: Nshapes imageCell{pic}= imread(char(filenames(pic))); end %Finds the black elements and applies the colors saved in the ‘colors’ table incr=0; figNum=0; for shapeNum=1:Nshapes for colorNum=1:size(colors,1) incr=incr+1; newPic{incr}=ones(size(imageCell{shapeNum}))*255 ; %sets the background color for colorDim=1:3 %changes the RGB colors positionBlackPixels=find(imageCell{shapeNum} (:,:,colorDim)==0); tmp=newPic{incr}(:,:,colorDim); tmp(positionBlackPixels)=colors(colorNum,colorDim); newPic{incr}(:,:,colorDim)=tmp; end newStimulus=uint8(newPic{incr}); %The new stimulus is ready to be saved figNum=shapeNum*10+colorNum; %We give the stimulus a new name imwrite(newStimulus, sprintf('%d.jpg',figNum)); %The stimulus is saved in the jpg format end end

The screenshot below shows the folder where the images are saved. The first digit codes the shape (1 = circle, 2 = cross, …), and the second codes the color (1= black, 2 = blue, …)

Figure 7.8. For a color version of this figure, see www.iste.co.uk/mathy/experiments.zip

Creating Stimuli Digitally

143

We can create a super-figure of the figures using the subplot function, which can generate a graphical representation of graphical representations. subplot(8,8,..) creates an 8-by-8 grid. The image obtained can help clarify the method used (e.g. an article, a poster) or the stimuli used during experimentation. Below is a possible continuation to the previous code: %% We want to create a summary figure with all 64 figures side by side. incr=0; figure('Color',[1 1 1]); % creates a white background for the images fig = gcf; for shapeNum=1:Nshapes for colorNum=1:size(colors,1) incr=incr+1; figName= [num2str(shapeNum*10+colorNum),'.jpg']; x=imread(figName); subplot(Nshapes,size(colors,1),incr); %subplot lets us put several figures in the same window %this function is hierarchical, 10 sub-functions can be placed in one box, etc. image(x) axis off end end saveas(gcf,'allStimuli.pdf') %exports the result as a PDF

Figure 7.9. Output: summary figure obtained with the last part of the program using the subplot function. For a color version of this figure, see www.iste.co.uk/mathy/experiments.zip

144

Experiments and Modeling in Cognitive Science

A function lets us overlay images, which can be useful for some experimental protocols that require the mixing of images with other images, numbers, letters, colored backgrounds, etc. Each overlaid figure can be saved as an image and be later used as a stimulus. Below is a possible continuation to the previous code: %% We want to overlay the images in twos, incr=0; figure('Color',[1 1 1]); for shapeNum= 1:Nshapes for colorNum = 1:size(colors,1) incr=incr+1; figNameA = [num2str(shapeNum*10 + colorNum),'.jpg']; figNameB = [num2str(randi(Nshapes)*10 + colorNum),'.jpg']; A = imread(figNameA); B = imread(figNameB); C = imfuse(A, B, 'blend', 'scaling', 'joint'); %Creates a blended overlay (imfuse), %reducing the intensities of A and B (scaling) subplot(Nshapes, size(colors,1), incr); %we use subplot again to display several figures in one window; image(C) axis off end end

Figure 7.10. Output 2: summary figure obtained after overlaying the figures. For a color version of this figure, see www.iste.co.uk/mathy/experiments.zip

Creating Stimuli Digitally

145

7.2.4. Generate color variations from existing images In the context of a similar protocol (several figures varying in color), if you have already created the different figures that you need (using a classical graphic design program), you can import all of your images from one file, and then search for a color and replace it with as many colors as you want for your protocol. Once again, the figures from our example are black with a transparent background. However, this time the image files (png format in our example) already exist and must be imported in order to be transformed. Going further, and in order to get closer to certain experimental standards, we suggest adding a gray background to the images (BackgroundColor function), and then changing the black color to desired colors using the same vectorization technique. Code: %% This program automatically changes the color of 8 stimuli previously created black in the png format. The program generates 64 images (jpg) with 8 different colors per shape. cd('/Users/mchekaf/Desktop/manuelMatlab®/drawPolygons') % specifies the directory mkdir output % Creates an output folder and makes it the current folder cd('/Users/mchekaf/Desktop/manuelMatlab®/drawPolygons/output') clear;clc; % clears the command window and the workspace ___________________________________________________________________ % Creates the table ‘colors’ (RGB): black; blue; green; red; cyan; purple; yellow; white colors=[0 0 0; 0 0 255; 0 255 0; 255 0 0; 0 255 255; 255 0 255; 255 255 0; 255 255 255]; %Loads the png images filenames = dir('*.png' ); % lists the *.png files present in the folder filenames = {filenames.name}'; BACKGROUNDCOLOR=[.5 .5 .5] ; %Vector for the color gray Nshapes=size(filenames,1); for pic=1: Nshapes picCell{pic}= imread(char(filenames(pic)),'BackgroundColor',BACKGROUNDCOLOR); end %Finds whatever is not gray and applies the colors saved in ‘colors’ incr=0; figNum=0;

146

Experiments and Modeling in Cognitive Science

for shapeNum=1:Nshapes for colorNum=1:size(colors,1) incr=incr+1 newPic{incr}=ones(size(picCell{shapeNum}))*128 %sets the background color for colorDim=1:3 %changes the RGB colors positionNONGREYpixels=find(picCell{shapeNum}(:,:,colorDim)~=12 8); tmp=newPic{incr}(:,:,colorDim); tmp(positionNONGREYpixels)=colors(colorNum,colorDim); newPic{incr}(:,:,colorDim)=tmp; end newStimulus=uint8(newPic{incr});%The new stimulus is ready to be saved figNum=shapeNum*10+colorNum;%The stimulus is given a new name imwrite(newStimulus, sprintf('%d.jpg',figNum));%The stimulus is saved in the jpg format end end

Figure 7.11. For a color version of this figure, see www.iste.co.uk/mathy/experiments.zip

Creating Stimuli Digitally

147

7.2.5. Creating windows of stimuli to be loaded in other experimentation software Assume that you are very attached to your experimentation software and, as a result, you do not want to use psychtoolbox. MATLAB® still lets you design your own stimuli that you can load into your experimentation software to display in full screen. The following example creates stimuli in 800 × 600 (to be displayed in full screen on a screen with a resolution of 800 × 600). The stimuli in question are typical of experiments in which a target has to be found among distractors. Here we use matrices of 12 cells with a distractor that shifts between one of the eight cells that are not in the corners. The goal is to create hundreds of stimuli that are similar to the two stimuli below: Stimulus 1:

Stimulus 2:

Our first program uses a loop that can generate eight possible positions of the targets, with 2 different targets and 10 random cases per condition. This represents 160 stimuli, recorded in 160 separate .bmp files. %Creates stimuli using a matrix of 3 rows by 4 columns %The 12 cells are set up like this: % P B E K % R D F M % Z A H V %In each matrix, a target (R or N) must be found by the participant

148

Experiments and Modeling in Cognitive Science

%parameters targetAllPos=[{[1 2]},{[2 1]},{[2 2]},{[2 3]},{[3 1]},{[3 2]},{[3 3]},{[4 2]}]; % the 8 possible positions of the targets; c-a-d, all the positions of the matrix except the corners target=['R', 'N']; % the two letters that have to be searched for nTrialsPerCondition=10; % number of random stimuli per condition %loop that calls the function CreateStimArrays for numTargetPos=1:length(targetAllPos) %loops positions for TargetChosen=1:length(target) %loops the two targets for numTrial=1:nTrialsPerCondition %loops the random draws name=['pos',num2str(numTargetPos),'target',num2str(TargetChose n),'stim',num2str(numTrial),'.bmp']; CreateStimArrays(name, targetAllPos{numTargetPos}, target(TargetChosen)); end end end

The following program is the function CreateStimArrays called by the previous program. function CreateStimArrays(filename, targetPos, targetId) if nargin == 0 %if the function is copy-pasted without being called by the previous program, it generates a stimulus; allows debugging filename='test.bmp'; targetPos=[1 2]; targetId='R'; end %screen size parameter X_WINDOW=800; Y_WINDOW=600; BACKGROUND_Col=[1 1 1];%color white in RGB set(gca, 'outerposition', [0 0 X_WINDOW Y_WINDOW]) %gca is the axis of the figure set(gcf,'outerposition',[200 200 X_WINDOW Y_WINDOW],'color',BACKGROUND_Col) %gcf is figure being created set(0,'DefaultAxesVisible','off')%makes the axes invisible %parameters for writing the letters in the matrix stimFont='Arial'; fontCol=[0 0 0];%black fontSize=36; xTarget=((X_WINDOW/6)*targetPos(1))/X_WINDOW ; % 6, because we have placed a free space on the left, a free space on the right, and there are 4 horizontal spaces made for the matrix yTarget=((Y_WINDOW/5)*targetPos(2))/Y_WINDOW; % 5, because we have put a free space at the top, one at the bottom, and there are 3 vertical spaces made for the matrix

Creating Stimuli Digitally

149

clf %clears the current figure hold on %puts the figure on hold text(xTarget,yTarget,targetId,'FontName',stimFont,'Color',font Col,'FontSize',fontSize,'HorizontalAlignment'... ,'center','VerticalAlignment','middle','FontWeight','normal'); %writes the target %removes the position of the target and places the 11 distractors allPositions=[{[1 1]},{[1 2]},{[1 3]},{[2 1]},{[2 2]},{[2 3]},{[3 1]},{[3 2]},{[3 3]},{[4 1]},{[4 2]},{[4 3]}]; ok=0; posNum=1; while ~ok %loops until the position of the target is found if allPositions{posNum}==targetPos allPositions(posNum)=[];%clears position of the target ok=1; end posNum=posNum+1; end %randomly places the distractors distr=['P', 'B', 'E', 'K', 'D', 'F', 'M', 'Z', 'A', 'H', 'V']; orderDistr=randperm(numel(distr)); %permutes the list for posNum=1:11 distrPos=allPositions{posNum}; distrId=distr(orderDistr(posNum)); xDistr=((X_WINDOW/6)*distrPos(1))/X_WINDOW ; yDistr=((Y_WINDOW/5)*distrPos(2))/Y_WINDOW; hold on text(xDistr,yDistr,distrId,'FontName',stimFont,'Color',fontCol ,'FontSize',fontSize,'HorizontalAlignment','center','VerticalA lignment','middle','FontWeight','normal'); %writes the distractor end %saves the stimulus outfilename=sprintf(filename); ScreenShot = getframe(gcf);%screenshot actual_pixels=(ScreenShot.cdata);%saves the pixels imwrite(actual_pixels,outfilename);%writes pixels in the file end %end of function

It is also relatively easy to adapt the previous program, so that it displays the stimuli L and T with various rotations and three different colors, with a greater number of possible positions on the screen. Here we choose 30 rows and 40 columns of possible positions.

150

Experiments and Modeling in Cognitive Science

Here is the desired result, with a single target T that is shown here in green in the top right:

Figure 7.12. For a color version of this figure, see www.iste.co.uk/mathy/experiments.zip

Chance does not always do a good job – here all the red Ls have appeared with the same rotation, by chance; a more perfected program would be able to balance out the rotations and the colors. The goal here was mainly to simplify the hand-typed part in the previous program, which was not desirable. It was the line: allPositions=[{[1 1]},{[1 2]},{[1 3]},{[2 1]},{[2 2]},{[2 3]},{[3 1]},{[3 2]},{[3 3]},{[4 1]},{[4 2]},{[4 3]}];

This line was typed out, which constitutes an error risk, and would not be possible for the 1200 possible positions. To make this task automatic, we can number the positions in a matrix, by writing:

Creating Stimuli Digitally

151

>> allPositions=reshape([1:12],[3,4]) allPositions = 1 2 3

4 5 6

7 8 9

10 11 12

To find the row and column of element 6, for example, we would have to write: >> [x,y]=find(allPositions==6) x= 2 y= 2

To choose the positions, it is better to switch from the 2D matrix to a simple vector: >> allPositions(:)' ans = 1

2

3

4

5

6

7

8

9

10

11

12

The first program uses a loop that lets us generate two possible targets in a T shape, with four different orientations. Here that represents eight stimuli in total; the program uses the function CreateStimArrays eight times to create eight .bmp files. %Make stimuli for an experiment using a stimulus array %In each matrix, there is a target (here: T) to be searched for %parameters nRowsArray=30; nColumnsArray=40; NTargetPos=2 target=['T']; % the letter to be searched for in the matrix allOrientation=[0, 90, 180, 270]; %loop stimuli for numTargetPos=1:NTargetPos %loop all target positions for TargetChosen=1:length(target)%loop all target types for numRotation=1:length(allOrientation)%make several trials depending on orientation

152

Experiments and Modeling in Cognitive Science

name=['pos',num2str(numTargetPos),'target',num2str(TargetChose n),'rotation',num2str(allOrientation(numRotation)),'.bmp']; CreateStimArrays(name, numTargetPos, target(TargetChosen),nRowsArray,nColumnsArray,allOrientation(n umRotation)); end end end

The second program uses L-shaped distractors. The parameters show that we choose 11 distractors. Seeing as the matrix allows for 1200 possible positions, the program chooses 12 positions out of 1200. We can modify the size of the font if the stimuli overlap. function CreateStimArrays(filename, targetPosTMP, targetId,nRows,nColumns,rotationType); if nargin == 0 %if the function has been copy-pasted without being called by the previous program, it generates a stimulus; allows debugging filename='test.bmp'; NTargetPos=1; nRows=30; nColumns=40; rotationType=90; positions=reshape([1:nColumns*nRows],[nRows,nColumns]) else positions=reshape([1:nColumns*nRows],[nRows,nColumns]) end positionsVector=positions(:) %parameters targetId='T'; distr=['L']; fontSize=28; numDistr=11; %screen size X_WINDOW=800; Y_WINDOW=600; BACKGROUND_Col=[0.5 0.5 0.5];%gray, in RGB set(gca, 'outerposition', [0 0 X_WINDOW Y_WINDOW]) %see comments for previous program set(gcf,'outerposition',[200 200 X_WINDOW Y_WINDOW],'color',BACKGROUND_Col) set(0,'DefaultAxesVisible','off') %target stimFont='Arial'; fontCol=[0 0 0]; fontCol(randi(3))=1 %randomly choose red, green or blue targetPosTMP=randi(length(positionsVector)) [x y]=find(positions==targetPosTMP)

Creating Stimuli Digitally

153

targetPos=[x y] xTarget=((X_WINDOW/nRows+1)*targetPos(1))/X_WINDOW ; yTarget=((Y_WINDOW/nColumns+1)*targetPos(2))/Y_WINDOW; clf hold on text(xTarget,yTarget,targetId,'FontName',stimFont,'Color',font Col,'FontSize',fontSize,'HorizontalAlignment'... ,'center','VerticalAlignment','middle','FontWeight','normal',' Rotation', rotationType); %removes the target position and randomly draws the positions of the distractors positionsVector(targetPosTMP)=[]; positionsChosenTMP=[ones(numDistr,1)',zeros(length(positionsVe ctor)-1,1)'] positionsChosen=positionsChosenTMP(randperm(length(positionsCh osenTMP))) positionsRemainingForDistractors=find(positionsChosen) %loops the positions of the distractors for posNum=1:length(positionsRemainingForDistractors) [x y]=find(positions==positionsRemainingForDistractors(posNum)) distrPos=[x y] distrId=distr(1); xDistr=((X_WINDOW/nRows+1)*distrPos(1))/X_WINDOW ; yDistr=((Y_WINDOW/nColumns+1)*distrPos(2))/Y_WINDOW; hold on fontCol=[0 0 0]; fontCol(randi(3))=1; allOrientation=[0, 90, 180, 270]; rotationType=allOrientation(randi(4)); text(xDistr,yDistr,distrId,'FontName',stimFont,'Color',fontCol ,'FontSize',fontSize,'HorizontalAlignment'... ,'center','VerticalAlignment','middle','FontWeight','normal',' Rotation',rotationType); end %saves outfilename=sprintf(filename); ScreenShot = getframe(gcf); actual_pixels=(ScreenShot.cdata); imwrite(actual_pixels,outfilename); end %end of function

7.2.6. Moving stimuli Refer to Chapter 8, which focuses on mobile stimuli on the screen. This touches on psychtoolbox-based experimentation.

154

Experiments and Modeling in Cognitive Science

7.3. Resources TARRLAB (http://tarrlabwiki.cnbc.cmu.edu/index.php/Main_Page) provides free access not only to a large number of original stimuli, such as fribbles, geons or gribbles, but also to an impressive library of more classical stimuli that can be used when programming experiments. Some of the stimuli have been generated using MATLAB®.

Figure 7.13.

The library Image Processing Toolbox, available in MATLAB®, provides an advanced set of algorithms for the processing of images, as well as mathematical transformations that can help to build complex stimuli such as gratings/Gabor patches:

Figure 7.14.

Creating Stimuli Digitally

155

The code used to create this stimulus is very mathematical. It is commonly used in psychophysics (does not require the Image Processing Toolbox): http://www.icn.ucl.ac.uk/courses/MATLAB®-Tutorials/Elliot_Freeman/ html/gabor_tutorial.html