For Loop Matrix Error - matlab

I am writing some Matlab code to analyze spikes and their stimuli. In the first part of the code I get the timing of a spike and then find the frame that was shown on the screen just prior. I then want to take the image data from that frame and add it to my own movie data. The x and y components of myMovie and moviedata are both 128x128, however when I try to add the image values from a certain frame from the stimuli moviedata(:,:,j) to a specific frame in my movie myMovie(:,:,k) I get "error: matrix dimensions must agree". Is there any way to fix this?
Code:
for n=1:1100
t = blocks(5).spikes{1}(:,n);
for k=1:25
ind = find(round(double(blocks(5).frameEpocs*1000)/1000) == (t-(1/(25*10))));
j = blocks(5).frameEpocs(1,ind);
myMovie(:,:,k) = myMovie(:,:,k) + double(moviedata(:,:,j));
end
end

find may return an empty matrix and hence j would be empty as well.
In that case, the command myMovie(:,:,k) + double(moviedata(:,:,j)); attempts to add a 128x128x1 matrix with a 128x128x0 matrix and thus the error you got.

Related

How to Fix Frame Size Error When Making Animation in MATLAB

I have this code to create an animation:
obj = VideoWriter(pvideo);
open(obj);
pic=dir(strcat(outputs,'/','*.tif'));
num=length(pic);
for i=1:num
im = imread(strcat(outputs,'/',pic(i).name));
writeVideo(obj,im);
end
close(obj)
It is giving me the following error:
Error using VideoWriter/writeVideo (line 368)
Frame must be 1768 by 1326
I understand that my video dimensions are off, but I'm not sure what part of my code needs to be changed to fix this.
Possible Size Mismatch
I believe a possible issue is that the images being combined into the video file may not match in resolution/dimensional size. Here is a sample script that creates a video file from built-in MATLAB images. Here all the images are written as size 500 by 500. If one of the images are not matching the error is thrown. They're are two ways to handle the issue resize the image using the imresize() function or crop the image using the imcrop() function or indexing (this can be done in the for-loop). Can one of the 500 dimensions in the script below throws the same error which might be an indicator of this problem.
%Creating test images to combine into video file%
Folder_Path = "";
Image = imresize(imread('moon.tif'),[500 500]);
imwrite(Image,fullfile(Folder_Path,"Image_1.tif"));
Image = imresize(imread('circuit.tif'),[500 500]);
imwrite(Image,fullfile(Folder_Path,"Image_2.tif"));
Image = imresize(imread('autumn.tif'),[500 500]);
imwrite(Image,fullfile(Folder_Path,"Image_3.tif"));
%Starting to create video%
Pictures = dir(fullfile(Folder_Path,'*.tif'));
%Creating a video object to save the video structure to%
Video_Object = VideoWriter('Saved_Video.mp4','MPEG-4');
Video_Object.FrameRate = 1;
Video_Object.Quality = 100;
Number_Of_Frames = length(Pictures);
open(Video_Object);
%Scanning the frames into the video structure%
for Frame_Index = 1: Number_Of_Frames
writeVideo(Video_Object,imread(fullfile(Folder_Path,Pictures(Frame_Index).name)));
end
close(Video_Object);
implay('Saved_Video.mp4');

Exceeding matrix dimensions when averaging elements

I am trying to create a vector with the average of every 48 elements in eddyCO2.
Tweedle = eddyCO2(1:47:end);
Tweedle(1) = mean(eddyCO2(1):eddyCO2(48));
for i = 2:length(Tweedle)
Tweedle(i) = mean(eddyCO2((i-1)*48):eddyCO2(i*48)); (ERROR: Index exceeds matrix dimensions)
end
I've tried reshaping and the only thing that seems to work is entering values manually but the size is too large to work without a loop. Why is this error appearing?
Does the following modified version of your script do what you intend? Hope it helps.
Tweedle = eddyCO2(1:48:end);
sz = length(eddyCO2);
for i = 1:length(Tweedle)-1
Tweedle(i) = mean(eddyCO2((i-1)*48+1):eddyCO2(i*48)); % averages elements 1-48, 49-96, etc.
end
Tweedle(i+1) = mean(eddyCO2(i*48+1):sz); % averages remaining items at end of vector

Repeating trials in MatLab

i'm am very new to Matlab but really want improve. For my experiment i want to show a picture which the participant response yes/no to, using two different keys (f&g) and then the next picture is presented and it repeats so onward.
Presenting the picture, using the keys works for far, but i can't get it to repeat the trial. Thus my question is how can i get the program to repeat/loop my trial?
Is there something wrong in my code so far or is there additional coding i should use?
this is my code so far
function try1_6()
cleanupObj= onCleanup(#() myCleanupFxn);
% PRETEST
% Initialize screen with black background
winID = Screen('openWindow',0, [0 0 0]);
%Parameter
backcol=255;
textcol=0;
% Load image file(s)
structimages= [];
TheImagesdir = dir('theImagesdir/*.jpg');
for i=1: length(TheImagesdir);
TheImages = imread(['theImagesdir/' TheImagesdir(i).name], 'JPEG');
% Get width and height
imageX = size(TheImages,2);
imageY = size(TheImages,1);
% Convert to texture
myTexture = Screen('MakeTexture', winID, TheImages);
% Set destination rectangle
destRect = [50 100 50+imageX 100+imageY];
%save to structure
structimages(end+1).filename=TheImagesdir(i).name;
structimages(end).destRect= destRect;
structimages(end).texture= myTexture;
end
%Make triallist
numberOfItems= [5]; %list of all possible items
Nrepeats=4;
Response=0;
TrialList=HH_mkTrialList({numberOfItems Response},Nrepeats);
%PRESENTATION
for trialnum=1:size(TrialList,1)
nitems = TrialList(trialnum,1);
Screen('FillRect', winID,backcol); % makes the screen blank
%displays text
DrawFormattedText(winID,'dkjfghaslkdfglksdjgfh','center','center',textcol);
Screen('Flip', winID)
HH_waitForKeyPress({'space'}); % waits for spacebar to be pressed
Screen('FillRect',winID,backcol);
Screen('Flip',winID);
WaitSecs(1);
%display picture
whichTheImages= randi(length(TheImagesdir)); % randomly selects image for directory
Screen('FillRect',winID,backcol);
Screen('DrawTexture', winID, myTexture, [], destRect);
Screen('Flip', winID);
HH_waitForKeyPress({'f','j'},5)
if resp==-1
break
end
TrialList(trialnum,4)= response; %records response
end
end
function myCleanupFxn()
Screen('CloseAll')
end
There are a number of problems with you code that you need to address. First of all, TrialList is used before it is declared/initialized. The Make triallist block of code seems out of place in the body of the for loop, and should probably be placed before you loop TrialList.
Your second problem is the inner for loop that loads images. Right now, it loads every image found in the directory, on every trial! There is no reason for you to be doing this, and you should be placing this for loop outside the trial loop as well. Furthermore, your original code never worked as intended, because you never save the loaded texture anywhere; myTexture is overwritten by the last image in your folder and that's the only texture you're ever gonna get. So in addition to pre-loading the images before the loop, you need to save them in a data structure so that you can use them later in your trial loop. A simple struct will work nicely here:
structImages = [];
TheImagesdir = dir('theImagesdir/*.jpg');
for i = 1:length(TheImagesdir);
TheImages = imread(['theImagesdir/' TheImagesdir(i).name], 'JPEG');
% Get width and height
imageX = size(TheImages,2);
imageY = size(TheImages,1);
% Convert to texture
myTexture = Screen('MakeTexture', winID, TheImages);
% Set destination rectangle
destRect = [50 100 50+imageX 100+imageY];
%save to structure
structImages(end+1).filename = TheImagesdir(i).name;
structImages(end).destRect = destRect;
structImages(end).texture = myTexture;
end
There are other inconsistencies in your code:
whichTheIamges is defined but not used
resp is used in the comparison if resp==-1 but is not defined
response is saved into TrialList before it is defined
Finally, the biggest problem is Screen('CloseAll', winID); is inside the trial loop, so you tear down your whole presentation platform after the first trial.
FYI, as noted in my comment wrapping your entire script in a try block is really poor practice. I suspect you do this because you want to be able to Ctrl+C mid-task, but there's a better way to do this. If you make your entire script a function then you can use the onCleanup method to execute code whenever your function exits (whether normally, by error, or by interruption). The method goes like this:
function myScript()
%//make your script a function. There is an additional advantages to doing this:
%//function performance is better than script performance.
%//blah-blah-blah
%//setup the cleanup object before opening screen
cleanupObj = onCleanup(#() myCleanupFxn);
%//open the screen
winID = Screen('openWindow',0, [0 0 0]);
%//blah-blah-blah
end
function myCleanupFxn()
%//local function, not visible outside of this file
Screen('CloseAll');
end

beginner:referencing a cell containing a zero matlab

So far I have got this code:
clear all; % clears all variables from your workspace
close all; % closes all figure windows
clc; % clears command window
%%=============================================
%%define number of trials and subjects
%%=============================================
njump=81;
nsbj=6;
%%
%%==============================================
%%defining size of cell that will be created
%%==============================================
data=cell(njump,1);
%%
%%==============================================
%%defining gravity and frame rate per second (fps)
%%==============================================
fps=0.001; %frames per second
g=-9.81; %acceleration
%%
%%==============================================
%%read in excel data in CSV format
%%===============================================
for i=1:njump;
x=sprintf('Trial%02d.csv',i),sprintf('Trial%02d',i),'A1:E7000';;% jump data
data{i}=xlsread(x,'A1:E7000');
%%===============================================
%%defining total no. of frames and time of flight
%tnf=total number of frames equal to zero
%n = nnz(X) returns the number of nonzero elements in matrix X.
%%===============================================
% myMax(i) = nanmax(data{i}(:,5));
% vals = find(data{i}(:,5) > (myMax(i) - 10));
% pointsInAir = numel(vals,i);
tnf(i,1) = size(data{i,1},1) - nnz(data{i,1}(:,5)); %number of zeros
tof(i)=tnf(i)*fps; %Time of flight is equal to this
jh(i,1)=(-g*(tof(i).^2)/8); %defining jump height
%%=================================================
%%to find average power first use "find" function to find the first zero in
%%Fz, have the cell referenced
%%then use nanmean for average power(av_pwr)
%%use nanmin for peak power (peak_pwr)
%%=================================================
n = 1; % the following call to find retrieves only the n first element(s) found.
ref= find(data{i,1}(:,5)==0, n, 'first');
% ref=find(data(:,5)==0);
peak_pwr(i,1) = nanmin (data {i,1}(1:ref,5)); %preak power in coloumn E1 in all data with reference to cell found
av_pwr(i,1)=nanmean(data {i,1}(1:ref,5));%average power in coloumn E1 in all data with reference to cell found
%%==================================================
%%Plot the results onto a time vs jump height, time vs average power and
%%time vs peak power
However the part that is hard is trying to find the first zero in column E which is the 5th column to use as a reference cell. I want to use this reference cell so that I can do my average and peak power calcs. that use the numbers before this zero.
In this case ref is empty so you cannot access the first element.
If you think that ref should not be empty you need to go back further to see where things go wrong. Otherwise, you can use something like:
if any(ref)
%Do something
else
%Return the default value/do alternative action
end
It could help to have an example of what's in data. I have created one which might be similar to yours :
data{1,1}=magic(6)-10
Now in this matrix, column 5 actually does have a zero element so ref= find(data{1,1}(:,5)==0); ref(1) actually works and retrieves the first index of a zero element. However, if it didn't, you would be trying to access the first element of an empty matrix.
Try instead using the second (and perhaps third) arguments of find to achieve this :
n = 1;
% the following call to find retrieves only the n first element(s) found.
ref= find(data{1,1}(:,5)==0, n, 'first');
The rest of your code seems like it should work, although from the looks of it i have a feeling your loop (i take it you are using a loop for i) could maybe be vectorized.
Hope this helps :)
Tepp

Output loop result in Matlab

Hi have this code and I don't know how to put the output result with every pixel.I think the output code are not well defined.
EDIT:
I'm going to try to explain the code:
% I have an image
imagen1=imread('recor.tif');
imagen2= double(imagen1);
band1= imagen2(:,:,1);
% I preallocate the result (the image size is 64*89*6)
yvan2= zeros(61,89,1);
% For every pixel of the image, I want to get one result (each one is different).
for i = 1 : nfiles
for j = 1 : nrows
for i = 1:numel(band1)
% I'm doing this because I've to multiply the results of this interpolation with that result a2ldb1y= ldcm_1(:,1). This vector has a length of 2151x1 and I need to muliply the result of the interpolation for (101:267) position on the vector, this is the reason because I'm doing the interpolation since 101 to 267 (also because I don't have that values).
interplan= interp1(van1,man2,t2,'spline');
ma(96) = banda1a(i); % I said 96, because I want to do an interpollation
end
van1= [101 96 266]';
mos1= ma(134);
van2= [0 pos1 0];
t= 101:267;
t2= t';
xi= 101:1:267;
xi2=xi';
interplan= interp1(van1,van2,t2,'spline');
% After this, I 'prepare' the vector.
out=zeros(2151,1)
out(101:267) = interplan;
% And then, I do all this operation (are important for the result)
a2ldb1y= ldcm_1(:,1);
a2ldsum_pesos1= sum(a2ldb1y);
a2l7dout1_a= a2ldb1y.*out;
a2l7dout1_b= a2l7dout1_a./a2ldsum_pesos1;
a2l7dout1_c= sum(a2l7dout1_b);
% And the result a2l7dout1_c I want it for every pixel (the results are different because every pixel has a different value...)
**yvan2(:,:,1)= [a2l7dout1_c];**
end
end
Thanks in advance,
I'm shooting in the dark here, but I think you're looking for:
yvan2(i, j, 1)= a2l7dout1_c;
instead of:
yvan2(:,:,1)= [a2l7dout1_c];
and thus your output should be stored in the variable yvan2 after the loops are done.
P.S
Some issues in your code:
Why do you have two loops using the same iteration variable i? Your calculations are probably incorrect since i is being modified by two for loops.
Why do you even need the second loop? Each iteration overruns the value of ma(134) set by the previous iteration. You can just replace the entire loop with:
ma(134) = banda1a(numel(band1))
You shouldn't be using the names i and j for loop variables. They are already reserved for the imaginary unit (that is, sqrt(-1)), so MATLAB needs extra processing time for name resolution. You'd rather use other loop variable names instead, even ii and jj.