Search code examples
imageoctavepsychtoolbox

Troubles presenting new and random images using Psychtoolbox


I'm fairly new at programming and am attempting to program my first experiment using Psychtoolbox. In this experiment a random number of faces will be shown (1-6 faces), and each face will be different from each other. The faces will disappear after 2 seconds and then a probe face will appear for 2 seconds. The participant must decide if the probe face had been in the previous set of faces. With my current code the number of faces presented is being randomized. But my problem is that the faces shown in the learning phase are always the same (e.g., if 5 faces are shown it's the same face in all 5 locations). This same face will appear for 6 trials (finishing the p=1:6 for loop) until and then a new face is shown but the problem is the same with this same face appearing all the time. Is there a way to make it so that a new face is shown each time?

f = 1
ntrials = 20;
for i = 1:ntrials

  positions = Shuffle(1:6); %positions = the number of faces that will be shown (randomized)


           folder = '/Users/ricelab06/cropped_faces';
           fileFull = fullfile(folder, {'*.jpg'});
           files = dir(fileFull{1});
           images = cell(1, 1);  
           currentfilename = files(imgs(f)).name;
           fullFileName = fullfile(folder, currentfilename);
           currentimage = imread(fullFileName);
           images{imgs(f)} = currentimage;
           randFaceTexture = Screen('MakeTexture', window, currentimage);
           [imageHeight, imageWidth, colorChannels] = size(currentimage);

           f = f + 1;


for k = 1:6
     if positions(k) == 1  %1 face is shown 
         for p = 1:positions(k)             
                %Draw the images to the back buffer
                Screen('DrawTexture', window, randFaceTexture, [], []);

         end

     elseif positions(k) == 2 %2 faces are shown 
         for p = 1:positions(k)
                posLine = {line1, line2}; 
                %Draw the images to the back buffer 
                Screen('DrawTexture', window, randFaceTexture, [], [posLine{p}]);

         end

     elseif positions(k) == 3 %3 faces are shown 
         for p = 1:positions(k)
                posTriangle = {triangle1, triangle2, triangle3};                 
                %Draw the images to the back buffer
                Screen('DrawTexture', window, randFaceTexture, [], [posTriangle{p}]);

         end  

     elseif positions(k) == 4  %4 faces are shown 
         for p = 1:positions(k)
                posSquare = {square1, square2, square3, square4};                 
                %Draw the images to the back buffer
                Screen('DrawTexture', window, randFaceTexture, [], [posSquare{p}]);

         end

     elseif positions(k) == 5  %5 faces are shown 
         for p = 1:positions(k)
                posPentagon = {pentagon1, pentagon2, pentagon3, pentagon4, pentagon5};                      
                %Draw the images to the back buffer
                Screen('DrawTexture', window, randFaceTexture, [], [posPentagon{p}]);

         end      

     elseif positions(k) == 6  %6 faces are shown
         for p = 1:positions(k)
                posHexagon = {hexagon1, hexagon2, hexagon3, hexagon4, hexagon5, hexagon6};                       
                %Draw the images to the back buffer
                Screen('DrawTexture', window, randFaceTexture, [], [posHexagon{p}]);

         end 
     end     
end

Screen('Flip', window);
WaitSecs(2);

Solution

  • The same face is displaying because choice of face index (defined as the variable 'f') is defined outside of the k = 1:6 loop. So the same single value of 'f' will be used to load an image texture for all values of k.

    It's not clear if you have 6 total face images or a larger set. But on each run within your k = 1:6 loop, you can select k unique face indices via:

    n = 10; % unclear your actual value of total face images
    % choose 'k' values out of 'n' (without replacement)
    faces_to_display = ChooseKFromN(n, k);
    

    You would then display the indices of the faces in 'faces_to_display' by loading those face images as textures (or selecting the textures from an array if pre-loaded).

    In practice when selecting data randomly you would also want to add:

    % reseed random number generatetor
    ClockRandSeed()
    

    To the top of your script to be sure the random number generator selects different values between runs.