Need help making a for loop on psytoolkit to display images

Trying to create a for loop with 70 iterations that will DrawTexture of 4 different images from different files in a randomized manner. All files have 70 images, except for file 2 it has 35 images and I want it to repeat presentation but in a randomised manner. I started the loop for the first group of files (could not randomise it tho) and every time I add the images from the following files it does not work
folder1 = 'Images_File1';
im1 = dir([folder1,'/*.jpg']);
images1 = {im1(:).name};
folder2 = 'Images_File2';
im2 = dir([folder2,'/*.jpg']);
images2 = {im2(:).name};
folder3 = 'Images_File3';
im3 = dir([folder3,'/*.jpg']);
images3 = {im3(:).name};
folder4 = 'Images_File4';
im4 = dir([folder4,'/*.jpg']);
images4 = {im4(:).name};
for i = 1:70
file_A{i} = double(imread([folder1,'/',images1{i}]));
file_B{i} = double(imread([folder2,'/',images2{i}]));
file_C{i} = double(imread([folder3,'/',images3{i}]));
file_D{i} = double(imread([folder4,'/',images4{i}]));
end
for i = 1:70
images_fileA = Screen('MakeTexture',w,file_A{i});
Screen('DrawTexture',w,images_fileA,[]);
Screen('Flip',w); WaitSecs(1)
end

Answers (1)

The below works with four folders in which the number of images are possibly different.
It presents exactly maximg (times 4) images. Each folder will be repeated as many times as needed. Within each repetition, the order will be scrambled, but the full folder will be presented before any image from the folder is repeated. If the number of images in a folder does not exactly divide into maximg then only some of the images from the folder will be presented in the final pass.
%for the below to work, something has to be assigned to the variable 'w'
maximg = 70;
folder1 = 'Images_File1';
im1 = dir( fullfile(folder1,'*.jpg'));
images1 = {im1(:).name};
folder2 = 'Images_File2';
im2 = dir( fullfile(folder2,'*.jpg'));
images2 = {im2(:).name};
folder3 = 'Images_File3';
im3 = dir( fullfile(folder3,'*.jpg'));
images3 = {im3(:).name};
folder4 = 'Images_File4';
im4 = dir( fullfile(folder4,'*.jpg'));
images4 = {im4(:).name};
nA = length(images1);
nB = length(images2);
nC = length(images3);
nD = length(images4);
textureA = cell(nA, 1);
textureB = cell(nB, 1);
textureC = cell(nC, 1);
textureD = cell(nD, 1);
for K = 1 : nA
files_A = imread(fullfile(folder1, images1{K}));
texture_A{K} = Screen('MakeTexture',w,file_A);
end
for K = 1 : nB
files_B = imread(fullfile(folder2, images2{K}));
texture_B{K} = Screen('MakeTexture',w,file_B);
end
for K = 1 : nC
files_C = imread(fullfile(folder3, images3{K}));
texture_C{K} = Screen('MakeTexture',w,file_C);
end
for K = 1 : nD
files_D = imread(fullfile(folder4, images4{K}));
texture_D{K} = Screen('MakeTexture',w,file_D);
end
fcA = floor(maximg/nA); pcA = mod(maximg, nA);
fcB = floor(maximg/nB); pcB = mod(maximg, nB);
fcC = floor(maximg/nC); pcC = mod(maximg, nC);
fcD = floor(maximg/nD); pcD = mod(maximg, nD);
idxA = []; idxB = []; idxC = []; idxD = [];
for K = 1 : fcA
idxA = [idxA, randperm(nA)];
end
if pcA ~= 0
idxA = [idxA, randperm(nA, pcA)];
end
for K = 1 : fcB
idxB = [idxB, randperm(nB)];
end
if pcB ~= 0
idxB = [idxB, randperm(nB, pcB)];
end
for K = 1 : fcC
idxC = [idxC, randperm(nC)];
end
if pcC ~= 0
idxC = [idxC, randperm(nC, pcC)];
end
for K = 1 : fcD
idxD = [idxD, randperm(nD)];
end
if pcD ~= 0
idxD = [idxD, randperm(nD, pcD)];
end
for K = 1 :maximg
Screen('DrawTexture', w, texture_A(idxA(K)), []);
Screen('Flip',w); WaitSecs(1)
Screen('DrawTexture', w, texture_B(idxB(K)), []);
Screen('Flip',w); WaitSecs(1)
Screen('DrawTexture', w, texture_C(idxC(K)), []);
Screen('Flip',w); WaitSecs(1)
Screen('DrawTexture', w, texture_D(idxD(K)), []);
Screen('Flip',w); WaitSecs(1)
end

6 Comments

Reaam Abdalla's incorrecly posted "Answer" moved here:
Hi @Walter Roberson, thank you for replying. I've tried the codes you put up but once the screen opens it gets stuck and doesn't execute any of the codes I've written (even ones I had before this loop that were working) ..
I tried another way that runs, but the for loop stops after 35 images are shown from all 4 files. I am not sure if I should use a while loop or counter for it What would you recommend?
folder1 = 'Images_File1';
im1 = dir([folder1,'/*.jpg']);
images1 = {im1(:).name};
folder2 = 'Images_File2';
im2 = dir([folder2,'/*.jpg']);
images2 = {im2(:).name};
folder3 = 'Images_File3';
im3 = dir([folder3,'/*.jpg']);
images3 = {im3(:).name};
folder4 = 'Images_File4';
im4 = dir([folder4,'/*.jpg']);
images4 = {im4(:).name};
for i = 1:70
file_A{i} = double(imread([folder1,'/',images1{i}]));
file_B{i} = double(imread([folder2,'/',images2{i}]));
file_C{i} = double(imread([folder3,'/',images3{i}]));
file_D{i} = double(imread([folder4,'/',images4{i}]));
end
for i = 1:70
images_fileA = Screen('MakeTexture',w,file_A{i});
Screen('DrawTexture',w,images_fileA,[]);
Screen('Flip',w); WaitSecs(1)
images_fileB = Screen('MakeTexture',w,file_B{i});
Screen('DrawTexture',w,images_fileB,[]);
Screen('Flip',w); WaitSecs(1)
images_fileC = Screen('MakeTexture',w,file_C{i});
Screen('DrawTexture',w,images_fileC,[]);
Screen('Flip',w); WaitSecs(1)
images_fileD = Screen('MakeTexture',w,file_D{i});
Screen('DrawTexture',w,images_fileD,[]);
Screen('Flip',w); WaitSecs(1)
end
FYI: it stops after 35 times as the second file only has 35 images whereas the other 3 files have 70 files
To get around the 35 problem:
But this does not randomize as required.
folder1 = 'Images_File1';
im1 = dir([folder1,'/*.jpg']);
images1 = {im1(:).name};
folder2 = 'Images_File2';
im2 = dir([folder2,'/*.jpg']);
images2 = {im2(:).name};
folder3 = 'Images_File3';
im3 = dir([folder3,'/*.jpg']);
images3 = {im3(:).name};
folder4 = 'Images_File4';
im4 = dir([folder4,'/*.jpg']);
images4 = {im4(:).name};
for i = 1:70
file_A{i} = double(imread([folder1,'/',images1{i}]));
file_B{i} = double(imread([folder2,'/',images2{i}]));
file_C{i} = double(imread([folder3,'/',images3{i}]));
file_D{i} = double(imread([folder4,'/',images4{i}]));
end
for i = 1:70
images_fileA = Screen('MakeTexture',w,file_A{i});
Screen('DrawTexture',w,images_fileA,[]);
Screen('Flip',w); WaitSecs(1)
images_fileB = Screen('MakeTexture',w,file_B{ mod(i-1,35)+1});
Screen('DrawTexture',w,images_fileB,[]);
Screen('Flip',w); WaitSecs(1)
images_fileC = Screen('MakeTexture',w,file_C{i});
Screen('DrawTexture',w,images_fileC,[]);
Screen('Flip',w); WaitSecs(1)
images_fileD = Screen('MakeTexture',w,file_D{i});
Screen('DrawTexture',w,images_fileD,[]);
Screen('Flip',w); WaitSecs(1)
end
I had a typing mistake in the code that used the textures after they were created; I have fixed it in the above.

Sign in to comment.

Products

Release

R2019a

Asked:

on 25 Dec 2021

Commented:

on 26 Dec 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!