Pre-render frames before displaying moving grating - matlab

I am using DemoDrift2 from Psychtool box to create a moving grating. The grating moves perfectly and works great. However, i need to use it with some other devices connected and working with other softwares. In these situations the grating is displayed slower and jiggles. How can i pre-render the frames before the grating is displayed?
function DriftDemo2(angle, cyclespersecond, f, drawmask, gratingsize)
% function DriftDemo2([angle=30][, cyclespersecond=1][, f=0.05][, drawmask=1],[gratingsize=400])
if nargin < 5
gratingsize = [];
end
if isempty(gratingsize)
% By default the visible grating is 400 pixels by 400 pixels in size:
gratingsize = 400;
end
if nargin < 4
drawmask = [];
end
if isempty(drawmask)
% By default, we mask the grating by a gaussian transparency mask:
drawmask=1;
end;
if nargin < 3
f = [];
end
if isempty(f)
% Grating cycles/pixel: By default 0.05 cycles per pixel.
f=0.05;
end;
if nargin < 2
cyclespersecond = [];
end
if isempty(cyclespersecond)
% Speed of grating in cycles per second: 1 cycle per second by default.
cyclespersecond=1;
end;
if nargin < 1
angle = [];
end
if isempty(angle)
% Angle of the grating: We default to 30 degrees.
angle=30;
end;
movieDurationSecs=20; % Abort demo after 20 seconds.
% Define Half-Size of the grating image.
texsize=gratingsize / 2;
% Screen('Preference', 'SkipSyncTests', 1);
try
% This script calls Psychtoolbox commands available only in OpenGL-based
% versions of the Psychtoolbox.
AssertOpenGL;
% Get the list of screens and choose the one with the highest screen number.
screens=Screen('Screens');
screenNumber=max(screens);
% Find the color values which correspond to white and black:
% functions WhiteIndex and BlackIndex:
white=WhiteIndex(screenNumber);
black=BlackIndex(screenNumber);
% Round gray to integral number, to avoid roundoff artifacts with some
% graphics cards:
gray=round((white+black)/2);
% This makes sure that on floating point framebuffers we still get a
% well defined gray:
if gray == white
gray=white / 2;
end
% Contrast 'inc'rement range for given white and gray values:
inc=white-gray;
% Open a double buffered fullscreen window and set default background
% color to gray:
[w screenRect]=Screen('OpenWindow',screenNumber, gray);
if drawmask
% Enable alpha blending for proper combination of the gaussian aperture
% with the drifting sine grating:
Screen('BlendFunction', w, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
end
% Calculate parameters of the grating:
p=ceil(1/f);
% frequency in radians:
fr=f*2*pi;
% This is the visible size of the grating. It is twice the half-width
% of the texture plus one pixel to make sure it has an odd number of
% pixels and is therefore symmetric around the center of the texture:
visiblesize=2*texsize+1;
% Create one single static grating image:
%
% We only need a texture with a single row of pixels(i.e. 1 pixel in height) to
% define the whole grating! If the 'srcRect' in the 'Drawtexture' call
% below is "higher" than that (i.e. visibleSize >> 1), the GPU will
% automatically replicate pixel rows. This 1 pixel height saves memory
% and memory bandwith, ie. it is potentially faster on some GPUs.
%
% However it does need 2 * texsize + p columns, i.e. the visible size
% of the grating extended by the length of 1 period (repetition) of the
% sine-wave in pixels 'p':
x = meshgrid(-texsize:texsize + p, 1);
% Compute actual cosine grating:
grating=gray + inc*cos(fr*x);
% Store 1-D single row grating in texture:
gratingtex=Screen('MakeTexture', w, grating);
% Create a single gaussian transparency mask and store it to a texture:
% The mask must have the same size as the visible size of the grating
% to fully cover it. Here we must define it in 2 dimensions and can't
% get easily away with one single row of pixels.
%
% We create a two-layer texture: One unused luminance channel which we
% just fill with the same color as the background color of the screen
% 'gray'. The transparency (aka alpha) channel is filled with a
% gaussian (exp()) aperture mask:
mask=ones(2*texsize+1, 2*texsize+1, 2) * gray;
[x,y]=meshgrid(-1*texsize:1*texsize,-1*texsize:1*texsize);
mask(:, :, 2)=white * (1 - exp(-((x/90).^2)-((y/90).^2)));
masktex=Screen('MakeTexture', w, mask);
% Query maximum useable priorityLevel on this system:
priorityLevel=MaxPriority(w); %#ok<NASGU>
% We don't use Priority() in order to not accidentally overload older
% machines that can't handle a redraw every 40 ms. If your machine is
% fast enough, uncomment this to get more accurate timing.
%Priority(priorityLevel);
% Definition of the drawn rectangle on the screen:
% Compute it to be the visible size of the grating, centered on the
% screen:
dstRect=[0 0 visiblesize visiblesize];
dstRect=CenterRect(dstRect, screenRect);
% Query duration of one monitor refresh interval:
ifi=Screen('GetFlipInterval', w);
% Translate that into the amount of seconds to wait between screen
% redraws/updates:
% waitframes = 1 means: Redraw every monitor refresh. If your GPU is
% not fast enough to do this, you can increment this to only redraw
% every n'th refresh. All animation paramters will adapt to still
% provide the proper grating. However, if you have a fine grating
% drifting at a high speed, the refresh rate must exceed that
% "effective" grating speed to avoid aliasing artifacts in time, i.e.,
% to make sure to satisfy the constraints of the sampling theorem
% (See Wikipedia: "Nyquist?Shannon sampling theorem" for a starter, if
% you don't know what this means):
waitframes = 1;
% Translate frames into seconds for screen update interval:
waitduration = waitframes * ifi;
% Recompute p, this time without the ceil() operation from above.
% Otherwise we will get wrong drift speed due to rounding errors!
p=1/f; % pixels/cycle
% Translate requested speed of the grating (in cycles per second) into
% a shift value in "pixels per frame", for given waitduration: This is
% the amount of pixels to shift our srcRect "aperture" in horizontal
% directionat each redraw:
shiftperframe= cyclespersecond * p * waitduration;
% Perform initial Flip to sync us to the VBL and for getting an initial
% VBL-Timestamp as timing baseline for our redraw loop:
vbl=Screen('Flip', w);
% We run at most 'movieDurationSecs' seconds if user doesn't abort via keypress.
vblendtime = vbl + movieDurationSecs;
i=0;
% Animationloop:
while(vbl < vblendtime)
% Shift the grating by "shiftperframe" pixels per frame:
% the mod'ulo operation makes sure that our "aperture" will snap
% back to the beginning of the grating, once the border is reached.
% Fractional values of 'xoffset' are fine here. The GPU will
% perform proper interpolation of color values in the grating
% texture image to draw a grating that corresponds as closely as
% technical possible to that fractional 'xoffset'. GPU's use
% bilinear interpolation whose accuracy depends on the GPU at hand.
% Consumer ATI hardware usually resolves 1/64 of a pixel, whereas
% consumer NVidia hardware usually resolves 1/256 of a pixel. You
% can run the script "DriftTexturePrecisionTest" to test your
% hardware...
xoffset = mod(i*shiftperframe,p);
i=i+1;
% Define shifted srcRect that cuts out the properly shifted rectangular
% area from the texture: We cut out the range 0 to visiblesize in
% the vertical direction although the texture is only 1 pixel in
% height! This works because the hardware will automatically
% replicate pixels in one dimension if we exceed the real borders
% of the stored texture. This allows us to save storage space here,
% as our 2-D grating is essentially only defined in 1-D:
srcRect=[xoffset 0 xoffset + visiblesize visiblesize];
% Draw grating texture, rotated by "angle":
Screen('DrawTexture', w, gratingtex, srcRect, dstRect, angle);
if drawmask==1
% Draw gaussian mask over grating:
Screen('DrawTexture', w, masktex, [0 0 visiblesize visiblesize], dstRect, angle);
end;
% Flip 'waitframes' monitor refresh intervals after last redraw.
% Providing this 'when' timestamp allows for optimal timing
% precision in stimulus onset, a stable animation framerate and at
% the same time allows the built-in "skipped frames" detector to
% work optimally and report skipped frames due to hardware
% overload:
vbl = Screen('Flip', w, vbl + (waitframes - 0.5) * ifi);
% Abort demo if any key is pressed:
if KbCheck
break;
end;
end;
% Restore normal priority scheduling in case something else was set
% before:
Priority(0);
%The same commands wich close onscreen and offscreen windows also close
%textures.
Screen('CloseAll');
catch
%this "catch" section executes in case of an error in the "try" section
%above. Importantly, it closes the onscreen window if its open.
Screen('CloseAll');
Priority(0);
psychrethrow(psychlasterror);
end %try..catch..enter code here
Any help is appreciated!

Pre-rendering is done by calling owpnt = Screen('OpenOffscreenWindow',...) and then issuing your regular drawing commands, but passing owpnt as the destination. These are then written to a texture, which you can display with Screen('DrawTexture').
You'd need one offscreen window per frame. This will quickly exhaust your video card's memory. So:
Make sure to keep the dimensions of the offscreen window as small as possible: make it just fit your grating
Screen('Close') unneeded offscreen windows asap

Related

Keystoning in Matlab - projecting a square on the floor

So, as a part of an experiment I need a function that could use the projector to project something on the floor. The projector is angled so the Keystone effect comes in to play and I'd like to correct it.
I try to do that by calculating the homography matrix H. I project a square at the bottom of the projected area, measure its properties (it is shown as a trapezoid on the ground) and calculate the matrix. And then I reverse the process with the idea to use the homography matrix H (it's inverse) to calculate and project a shape on the ground that would look like the original square and not a trapezoid.
But I'm not successful. I calculate a shorter quadrangle and still get a trapeze on the ground. I'm pretty sure I'm doing something wrong with the calculations but I'm not sure. I am new to Matlab :) Thx for the help. The code, with a lot of comments, is bellow.
function keystoning()
projArea = 100; % 100%
testSquare = 20; % test square dimension
%% Drawing a "what's supposed to be a square" on the floor
% black background, red "sqare" dimensions 20x20, attached to the base
% of the projection area so the base dimension of the "sqare" don't change
% and minimal measuring is required
testX=[40 40+testSquare 40+testSquare 40];
testY=[0 0 testSquare testSquare];
scrsz = get(groot,'screensize');
f = figure('position',[0 0 scrsz(3) scrsz(4)],...
'OuterPosition',[0 0 scrsz(3) scrsz(4)],...
'toolbar','none','menubar','none','name','none',...
'units','normalized',...
'Color','black','Resize','Off'...
);
figure(f); % focus window
fill(testX, testY,'r');
axis ([0 projArea 0 projArea])
pbaspect([1 1 1])
drawnow
disp('*** PLACE THE NEAR PART OF THE ELEMENT AT THE END OF THE TREADMILL ***');
%% Measuring of the shape in order to calculate the homography matrix H
disp('*** Measure the width of the base of the projection area in centimeters. ***');
prompt = 'Enter the measured distance: ';
projAreaM = input(prompt);
projAreaCoef=projAreaM/projArea; % coefficient between the axes scale and the projection area
disp('*** Measure the distance between the paralel lines of the trapezoid in centimeters. ***');
prompt = 'Enter the measured distance: ';
trapYm = input(prompt)/projAreaCoef
disp('*** Measure the length of the longer paralel line of the trapezoid in centimeters. ***');
prompt = 'Enter the measured length: ';
trapXm = input(prompt)/projAreaCoef
%% Calculating the homography matrix H
% trapezoid definition
% coordinates of the first two points for the trapezoid and the square
% are the same since its at the start of the projection area
difX=(trapXm-testSquare)/2; % length of the "pertrusions"
trapX=[testX(1) testX(2) testX(3)+difX testX(4)-difX];
trapY=[testY(1) testY(2) trapYm trapYm];
% variable definition
P=[testX;testY;ones(size(testX))]; % test rectangle
Q=[trapX;trapY;ones(size(trapX))]; % shown trapezoid
% homography matrix H calculation
H=Q/P; % solution to the equation HP = Q
%% Testing the homography matrix H
% we want to show the rectangle on the ground
Pnew=inv(H)*P;
fill(Pnew(1,:),Pnew(2,:),'r');
axis ([0 projArea 0 projArea])
pbaspect([1 1 1])
drawnow

Count circle objects in an image using matlab

How to count circle objects in a bright image using MATLAB?
The input image is:
imfindcircles function can't find any circle in this image.
Based on well known image processing techniques, you can write your own processing tool:
img = imread('Mlj6r.jpg'); % read the image
imgGray = rgb2gray(img); % convert to grayscale
sigma = 1;
imgGray = imgaussfilt(imgGray, sigma); % filter the image (we will take derivatives, which are sensitive to noise)
imshow(imgGray) % show the image
[gx, gy] = gradient(double(imgGray)); % take the first derivative
[gxx, gxy] = gradient(gx); % take the second derivatives
[gxy, gyy] = gradient(gy); % take the second derivatives
k = 0.04; %0.04-0.15 (see wikipedia)
blob = (gxx.*gyy - gxy.*gxy - k*(gxx + gyy).^2); % Harris corner detector (high second derivatives in two perpendicular directions)
blob = blob .* (gxx < 0 & gyy < 0); % select the top of the corner (i.e. positive second derivative)
figure
imshow(blob) % show the blobs
blobThresshold = 1;
circles = imregionalmax(blob) & blob > blobThresshold; % find local maxima and apply a thresshold
figure
imshow(imgGray) % show the original image
hold on
[X, Y] = find(circles); % find the position of the circles
plot(Y, X, 'w.'); % plot the circle positions on top of the original figure
nCircles = length(X)
This code counts 2710 circles, which is probably a slight (but not so bad) overestimation.
The following figure shows the original image with the circle positions indicated as white dots. Some wrong detections are made at the border of the object. You can try to make some adjustments to the constants sigma, k and blobThresshold to obtain better results. In particular, higher k may be beneficial. See wikipedia, for more information about the Harris corner detector.

Creating a point moving along a circle in MATLAB with speed and radius defined by the user

I am looking to create a simple circle graph within MATLAB in which the model shows the point moving along the circle with radius and angular velocity defined by the user.
Angular velocity in RADIANS/SEC
I am relatively new at MATLAB coding so any help would be very useful!
I tried this code:
r=1;
t = 0:.01:2*pi;
x = r*cos(t);
y = r*sin(t);
comet(x,y);
But when I change the 0.01 value the point doesn't move faster, it just skips more of the curve, also i'm unsure if the increments are in radians.
Thanks for your time
Edited version: See edit history for previous version.
Radius = 10;
AngularVelocity = 5; % in deg / s
AngleStep = 0.1
Angles = AngleStep : AngleStep : 2*pi;
CircleX = [Radius]; % empty array
CircleY = [0]; % empty array
%Initial zero-angle plot whose data we'll keep updating in the for loop:
a = plot([CircleX,CircleX], [CircleY,CircleY], 'r:');
hold on;
b = plot(CircleX, CircleY, 'o', 'markeredgecolor', 'k', 'markerfacecolor','g');
axis([-Radius, +Radius, -Radius, +Radius]); % make sure the axis is fixed
axis equal; % make x and y pixels of equal size so it "looks" a circle!
hold off;
for t = Angles
CircleX(end+1) = Radius * cos (t); % append point at end of CircleX array
CircleY(end+1) = Radius * sin (t); % append point at end of Circley array
set(a,'xdata',CircleX,'ydata',CircleY); % update plot 'a' data
set(b,'xdata', CircleX(end), 'ydata', CircleY(end)); % update plot 'b' data
drawnow; % ensure intermediate frames are shown!
pause(AngleStep/AngularVelocity) % pause the right amount of time!
end
This edit has made two changes compared to the previous version:
Instead of redrawing, now we're updating the data of an existing plot. This is generally faster as matlab doesn't have to redraw axes objects (i.e. the containers that hold the plot)
I increased AngleStep from 0.01 to 0.1. This means there's 10 times less angles to draw, so you can afford to draw then 10 times slower, therefore it becomes less likely that matlab will be unable to draw because of overhead. Having said that, this is at the cost of a less perfect circle. Try with AngleStep=1 to see what I mean.

Matlab Region Growing Error Message

I am experiencing an error in Matlab.
Maximum recursion limit of 500 reached. Use set(0,'RecursionLimit',N) to change the limit.
Be aware that exceeding your available stack space can crash MATLAB and/or your computer.
The algorithm I am using is the one downloaded from:
http://www.mathworks.com/matlabcentral/fileexchange/19084-region-growing
Here is the code:
function J=regiongrowing(I,x,y,reg_maxdist)
% This function performs "region growing" in an image from a specified
% seedpoint (x,y)
%
% J = regiongrowing(I,x,y,t)
%
% I : input image
% J : logical output image of region
% x,y : the position of the seedpoint (if not given uses function getpts)
% t : maximum intensity distance (defaults to 0.2)
%
% The region is iteratively grown by comparing all unallocated neighbouring pixels to the region.
% The difference between a pixel's intensity value and the region's mean,
% is used as a measure of similarity. The pixel with the smallest difference
% measured this way is allocated to the respective region.
% This process stops when the intensity difference between region mean and
% new pixel become larger than a certain threshold (t)
%
%
% Author: D. Kroon, University of Twente
I = im2double(imread('ship.jpg'));
x=150; y=150;
J = regiongrowing(I,x,y,0.2);
figure, imshow(I+J);
if(exist('reg_maxdist','var')==0), reg_maxdist=0.2; end
if(exist('y','var')==0), figure, imshow(I,[]); [y,x]=getpts; y=round(y(1)); x=round(x(1)); end
J = zeros(size(I)); % Output
Isizes = size(I); % Dimensions of input image
reg_mean = I(x,y); % The mean of the segmented region
reg_size = 1; % Number of pixels in region
% Free memory to store neighbours of the (segmented) region
neg_free = 10000; neg_pos=0;
neg_list = zeros(neg_free,3);
pixdist=0; % Distance of the region newest pixel to the regio mean
% Neighbour locations (footprint)
neigb=[-1 0; 1 0; 0 -1;0 1];
% Start regiongrowing until distance between region and possible new pixels become
% higher than a certain threshold
while(pixdist<reg_maxdist&&reg_size<numel(I))
% Add new neighbours pixels
for j=1:4,
% Calculate the neighbour coordinate
xn = x +neigb(j,1); yn = y +neigb(j,2);
% Check if neighbour is inside or outside the image
ins=(xn>=1)&&(yn>=1)&&(xn<=Isizes(1))&&(yn<=Isizes(2));
% Add neighbour if inside and not already part of the segmented area
if(ins&&(J(xn,yn)==0))
neg_pos = neg_pos+1;
neg_list(neg_pos,:) = [xn yn I(xn,yn)]; J(xn,yn)=1;
end
end
% Add a new block of free memory
if(neg_pos+10>neg_free), neg_free=neg_free+10000; neg_list((neg_pos+1):neg_free,:)=0; end
% Add pixel with intensity nearest to the mean of the region, to the region
dist = abs(neg_list(1:neg_pos,3)-reg_mean);
[pixdist, index] = min(dist);
J(x,y)=2; reg_size=reg_size+1;
% Calculate the new mean of the region
reg_mean= (reg_mean*reg_size + neg_list(index,3))/(reg_size+1);
% Save the x and y coordinates of the pixel (for the neighbour add proccess)
x = neg_list(index,1); y = neg_list(index,2);
% Remove the pixel from the neighbour (check) list
neg_list(index,:)=neg_list(neg_pos,:); neg_pos=neg_pos-1;
end
% Return the segmented area as logical matrix
J=J>1;
I have attempted to change the value as suggested by set(0,'RecursionLimit',N) but this just crashes Matlab if it goes over 1000.
The error message makes sense since you've added the following lines to the function
I = im2double(imread('ship.jpg'));
x=150; y=150;
J = regiongrowing(I,x,y,0.2);
figure, imshow(I+J);
and so it will call itself (recurse) repeatedly. These four lines need to be removed from regiongrowing and should only be used from the Command Line (or another script/function).

How to order an array of randomly drawn ellipses by size before drawing them

matlab beginner here and a big thanks in advance.i'm having trouble with an existing program:
The purpose of this project is to build (6) layers of randomly sized and oriented ellipses on a background, then save each layer state as a separate image (i.e. image1 with just background, image2 with bg and 1 ellipse, image3 with bg and 2 ellipses, etc...). As of now, the program works but sometimes some of the ellipses become hidden in the final picture (with 6 ellipses) if one of the later objects is bigger than an earlier one. I was that one possible solution to this would be to save the ellipse values in an array but not export them yet as an image. Once they are all saved, calculate area of each then use a sort function to put them in descening order and then draw and export them.
Here is the code as it stands:
xdim=1280; ydim=1024; % screen dimensions - these should match the touch screen dimensions
scene=zeros(xdim,ydim,3);
for scene_counter=1:1 %amount of scenes generated
scene_counter
figure;
ell_size_min=100; ell_size_max=800; % range of axis lengths for ellipses/pacman
min_color_separation=0.15; % this could theoretically take values between 0 and sqrt(3)=1.73ish
% if you increase this, it will take the program longer to find an acceptable set of colors
% the probability that a set of colors fails the separation test & it has to get a new one is
% about 10% for 0.1; about 50% for 0.15 and about 70% for 0.2
%-------------------------------------------
scene=scene.*0;
p = randperm(4); % creates random permutation of (1-4)
bg_count=p(1)+2; % selects first integer in sequence, e.g. random 1-4
% number of bg elements, min 3, max 6.
%-------------------------------------------
% this bit spaces out the colors of background and foreground elements
% it checks that ALL combinations have a min separation in color space using Pythagoras' theorum
% here color space is defined as 0 < R,G,B < 1
% it picks 11 spaced colors for each scene -
% 7 possible ellipses/pacmen + 3 letters (s+,s-,big letter) + background 'field' ie the very background
color_check_flag=1;
while color_check_flag==1
colors=rand(11, 3);
color_check=...
[colors-repmat(colors(1,:),11,1);...
colors-repmat(colors(2,:),11,1);...
colors-repmat(colors(3,:),11,1);...
colors-repmat(colors(4,:),11,1);...
colors-repmat(colors(5,:),11,1);...
colors-repmat(colors(6,:),11,1);...
colors-repmat(colors(7,:),11,1);...
colors-repmat(colors(8,:),11,1);...
colors-repmat(colors(9,:),11,1);...
colors-repmat(colors(10,:),11,1);...
colors-repmat(colors(11,:),11,1) ];
color_check_flag=sum(sqrt(sum((color_check+(color_check==0)).^2,2))<min_color_separation)>0;
end;
%-------------------------------------------
% this bit makes the background of the scene
% first, it makes a matrix the size of the screen and lets the elements be 1 if they fall in the ellipse or zero otherwise
% then, it takes out a bite if the bg element should be a pacman (random, p=0.5)
% then, it converts the matrix defining the shape into a 3d matrix, the size of the screen x 3 for RGB intensities
% that matrix defines this bg element, or 'layer' fully
% it combines layers in another screen size x 3 matrix -
% to do this is blanks (makes then =0) any elements in the scene which should be overwriten by the new bg element
% and then adds the new bg element to the scene
im = zeros(xdim,ydim);
[x,y] = ind2sub(size(im),1:numel(im));
bg=reshape([ones(xdim,ydim).*rand,ones(xdim,ydim).*rand,ones(xdim,ydim).*rand,],xdim,ydim,3);
imwrite(permute(bg,[2 1 3]),['scene_' int2str(scene_counter) '_' int2str(1) '.jpg'], 'jpg');
for i=1:6
a=rand*(ell_size_max-ell_size_min)+ell_size_min; % a is one axis of ellipse
b=rand*(ell_size_max-ell_size_min)+ell_size_min; % b is the other axis
centre = [rand*xdim rand*ydim]; % background elements can be anywhere on screen
ellipse = (x-centre(1)).^2 / a^2 + (y-centre(2)).^2/b^2 < 1; % define which pixels fall in the ellipse
% this bit makes the ellipse into pacman
if rand<0.5
bite_start=(rand*2*pi)-pi;
bite_stop=(rand*2*pi)-pi;
[theta,rho] = cart2pol(y-centre(2),x-centre(1)); % generate polar coords for doing the pacman mouth
if bite_stop>bite_start
pacman=(bite_start<theta).*(theta<bite_stop);
else
pacman=(theta>bite_start)+(bite_stop>theta);
end
ellipse=(reshape(ellipse.*pacman,xdim,ydim));
end
layer=reshape([ellipse.*colors(i,1) ellipse.*colors(i,2) ellipse.*colors(i,3)],xdim, ydim,3); % make a colored image for this bg element
scene=(scene.*(layer==0))+layer; % add the bg element to the scene by blanking the scene where this ellipse/pacman should go, then adding the ellipse/pacman to the scene
scene_temp=scene+((scene==0).*bg); % color in the remaining bits of screen (background 'field')
% following bit creates jpegs for levels 1-5 of oneplace as the bg
% elements are added to the image. i = number of bg elements
% format 'scene_number_level'
if i == 1
imwrite(permute(scene_temp,[2 1 3]),['scene_' int2str(scene_counter) '_' int2str(3) '.jpg'], 'jpg');end;
if i == 2
imwrite(permute(scene_temp,[2 1 3]),['scene_' int2str(scene_counter) '_' int2str(4) '.jpg'], 'jpg');end;
if i == bg_count
imwrite(permute(scene_temp,[2 1 3]),['scene_' int2str(scene_counter) '_' int2str(5) '.jpg'], 'jpg');end
end
image(scene);
%-------------------------------------------
% this bit defines coordinates for the s+, s- and big background letter, which get drawn in Presentation
spacing_flag=1;
while spacing_flag>0
letter_centres = [ round(rand*(xdim-300))+150-(0.5*xdim) round(rand*(ydim-300))+150-(0.5*ydim); % big background letter can go anywhere more than 150 pixels from the edge
round(round((rand*15)+0.5).*(xdim./16)-0.5*xdim)
round(round((rand*11)+0.5).*(ydim./12)-0.5*ydim);
round(round((rand*15)+0.5).*(xdim./16)-0.5*xdim) round(round((rand*11)+0.5).*(ydim./12)-0.5*ydim)]; % using 11x15 grid of possible target & distractor positions to match old program
spacing_flag=sqrt(sum((letter_centres(2,:)-letter_centres(3,:)).^2))<(round(xdim*(427/800))); % min spacing is from old scenes, as determined by Phil
end
%-------------------------------------------
% define characters and fonts
letter_indices=[round((rand*62)+0.5) round((rand*62)+0.5) round((rand*62)+0.5)];
font_indices= [round((rand*10)+0.5) round((rand*10)+0.5) round((rand*10)+0.5)];
%-------------------------------------------
scene_info(scene_counter,:)=[scene_counter bg_count letter_indices font_indices...
letter_centres(1,:) letter_centres(2,:) letter_centres(3,:)...
round(colors(9,:).*255) round(colors(10,:).*255) round(colors(11,:).*255)];
end
dlmwrite('scene_info.txt',scene_info);
Please let me know if I can clarify any of the code and, again, I very much appreciate any help!
Rather than define the sizes of the ellipses in the loop, define a list of random parameters before, sort them, then reference the sorted list in the loop. I.e.:
a = rand(6,1)*(ell_size_max-ell_size_min)+ell_size_min; % random axis 1
b = rand(6,1)*(ell_size_max-ell_size_min)+ell_size_min; % random axis b
areas = % code for the area of an ellips
[~,order] = sort(areas);
a = a(order);
b = b(order);
for i = 1 : 6
% Stuff
ellipse = (x-centre(1)).^2 / a(i)^2 + (y-centre(2)).^2/b(i)^2 < 1;
% More stuff
end