필터 지우기
필터 지우기

Error message: Index exceeds matrix dimension

조회 수: 1 (최근 30일)
Yvonne
Yvonne 2023년 9월 15일
댓글: Walter Roberson 2023년 9월 20일
I have a code that analyzes a short (75 second video) of the behavior of animals frame by frame and is designed to return an excel spreadsheet with the data. The code works for some video files, but abruptly stops at a certain frame (i.e. 1450 for one video file or 1900 for another video file) for some videos and returns the error message "index exceeds matrix dimension". The error is associated with (line 69) which is bolded below. How would I be able to fix this error?
directory = uigetdir;
cd(directory);
mov_list = dir('*mp4');
def = {'60','4.5','0.88','6','3','3','9','70','110','2'};
prompt = {'Gaussian hsize','Gaussian standard deviation (sigma)',...
'Detection thresholding value', 'Tadpole speed variability',...
'Tadpole X direction noise', 'Tadpole Y direction noise',...
'Tadpole distance between eyes and gut', 'Lower avoidance angle tolerance',...
'Higher avoidance angle tolerance','Dot radius (cm)'};
defAns = {char(def(1)), char(def(2)), char(def(3)), char(def(4)),...
char(def(5)), char(def(6)), char(def(7)), char(def(8)), char(def(9)),char(def(10))};
answer = inputdlg(prompt,'Initial Values', [1 1 1 1 1 1 1 1 1 1], defAns);
answer = str2double(answer);
v_name={};
encAvg={};
numEncount={};
numAvoid={};
for i = 1:length(mov_list)
[~,mov_name,~] = fileparts(mov_list(i).name);
mov = VideoReader(mov_list(i).name);
mkdir(mov_name)
cd(mov_name)
answer(10) = str2double(char(extractBetween(mov_name, "Dot", "R_")))*10;
diary on;
disp(answer(10));
try
[encAvg{i},numEncount{i},numAvoid{i}] = TadFunctionTestAT(mov,answer);
f_name = string(zeros(1,length(encAvg{i})));
for j = 1:length(encAvg{i})
f_name(1,j) = string(mov_name);
end
v_name{i} = f_name;
diary off;
clc;
cd(mov.path)
catch e
fprintf(2,'An error occurred in processing %s.\n',mov_name)
fprintf(2,'The error message was:\n%s\n',e.message)
cd(mov.path)
continue
end
delete(mov)
end
name = cat(2,v_name{1:end});
avg = cat(2,encAvg{1:end});
enc = cat(2,numEncount{1:end});
avo = cat(2,numAvoid{1:end});
alldata = [name',avg',avo',enc'];
tab = table(alldata(:,1),alldata(:,2),alldata(:,3),alldata(:,4),'VariableNames',...
{'MovieName','AvoidanceIndex','NumberAvoidances', 'NumberEncounters'});
writetable(tab,'Batch_Avoidance_Data.csv','FileType','text')

답변 (1개)

Walter Roberson
Walter Roberson 2023년 9월 15일
directory = uigetdir;
if isnumeric(directory);
fprintf('User cancel\n');
return;
end
mov_list = dir(fullfile(directory, '*.mp4'));
if isempty(mov_list)
fprintf('No mp4 files in directory "%s"\n', directory);
return;
end
def = {'60','4.5','0.88','6','3','3','9','70','110','2'};
prompt = {'Gaussian hsize','Gaussian standard deviation (sigma)',...
'Detection thresholding value', 'Tadpole speed variability',...
'Tadpole X direction noise', 'Tadpole Y direction noise',...
'Tadpole distance between eyes and gut', 'Lower avoidance angle tolerance',...
'Higher avoidance angle tolerance','Dot radius (cm)'};
defAns = {char(def(1)), char(def(2)), char(def(3)), char(def(4)),...
char(def(5)), char(def(6)), char(def(7)), char(def(8)), char(def(9)),char(def(10))};
answer = inputdlg(prompt,'Initial Values', [1 1 1 1 1 1 1 1 1 1], defAns);
answer = str2double(answer);
numfile = length(mov_list);
filenames = fullfile({mov_list.folder}, {mov_list.name});
v_name = cell(numfile, 1);
encAvg = cell(numfile, 1);
numEncount = cell(numfile, 1);
numAvoid = cell(numfile, 1);
for i = 1:numfile
thisfile = filenames{i};
[~,mov_name,~] = fileparts(thisfile);
mov = VideoReader(thisfile);
outdir = fullfile(directory, mov_name);
mkdir(outdir);
answer(10) = str2double(char(extractBetween(mov_name, "Dot", "R_")))*10;
diary on;
disp(answer(10));
try
[encAvg{i},numEncount{i},numAvoid{i}] = TadFunctionTestAT(mov,answer);
f_name = string(zeros(1,length(encAvg{i})));
for j = 1:length(encAvg{i})
f_name(1,j) = string(mov_name);
end
v_name{i} = f_name;
diary off;
clc;
catch e
fprintf(2,'An error occurred in processing %s.\n',mov_name)
fprintf(2,'The error message was:\n%s\n',e.message)
cd(mov.path)
continue
end
delete(mov)
end
name = cat(2,v_name{1:end});
avg = cat(2,encAvg{1:end});
enc = cat(2,numEncount{1:end});
avo = cat(2,numAvoid{1:end});
alldata = [name',avg',avo',enc'];
tab = table(alldata(:,1),alldata(:,2),alldata(:,3),alldata(:,4),'VariableNames',...
{'MovieName','AvoidanceIndex','NumberAvoidances', 'NumberEncounters'});
writetable(tab,'Batch_Avoidance_Data.csv','FileType','text')
If the function TadFunctionTestAT writes to files (such as extracting each frame into its own file) then you need to change the interface to pass in outdir to it, which it will need to use with fullfile() to construct the path to the file name to write.
That is, you should always avoid cd()'d around, and instead use qualified paths.
The two return that I added assume that you write this into a function; if not then you will need slightly more complex code to avoid executing when there is nothing to do.
  댓글 수: 7
Yvonne
Yvonne 2023년 9월 20일
편집: Yvonne 2023년 9월 20일
The TadFunctionTestAt is meant to extract the number of times the tadpole encounters a dot and the number of times it avoids the dots they encounter on a video file. What I get after running the code is an excel spread sheet with 3 data columns...
  1. avoidance index (# of avoidances/# of encounters)
  2. # of avoidances
  3. # of encounters
I don't know where the values are defined for mov, initvals unless they refer to the code below.
(In the workspace, the value for mov is "1x1 VideoReader" and the value for outdir is a file path to the folder where the excel sheet is stored after running the code)
%Video dimensions
numFrames = 2250; %numFrames = mov.NumOfFrames;
vidH = mov.Height;
vidW = mov.Width;
%Initializations
noDot_img = zeros(vidH,vidW,numFrames);
numBgFrames = numFrames; %Number of frames from 0 to use to form average background image; in this case, use all frames
noDotFrames = 450; %Number of frames in video prior to the start of dot displaying
imopenThreshold = initvals(10) + 1; %Disk radius to use for imopen function (threshold for removing dot detections under a certain size); was 3
imfindcirclesMin = initvals(10)*5; %Minimum post-imopen disk radius to be detected as a circle; was 10
imfindcirclesMax = initvals(10)*10; %Maximum post-imopen disk radius to be detected as a circle; was 20
imfindcirclesSensitivity = 0.93; %Sensitivity of imfindcircles; was originally 0.91
tadFrameWindow = 1; %Window over which to check for grossly inaccurate tadpole angles and velocities
tadFrameEvaluationWindow = 8; %Window over which to assess tadpole angle
I am also wondering if the issue might be in the "Removing Bad Detections" section of code as some video files run perfectly and return data on an excel spreadsheet whereas a handful of video files do not.
%% Removing Bad Detections
%detections out of video boundary are given nan values
for i = 1:length(Q_loc_estimateX(1,:)) % i = 1:length(Q_loc_estimateX(1,:))
%removeX = find(Q_loc_estimateX(:,i)<Q_loc_estimateX(1,i) - 50 | Q_loc_estimateX(:,i)>Q_loc_estimateX(1,i) + 50);%find(Q_loc_estimateX(:,i)<0 | Q_loc_estimateX(:,i)>vidH);
removeX = find(Q_loc_estimateX(:,i)<50 | Q_loc_estimateX(:,i)>550);
removeY = find(Q_loc_estimateY(:,i)<50 | Q_loc_estimateY(:,i)>770);%find(Q_loc_estimateY(:,i)<0 | Q_loc_estimateY(:,i)>vidW);
Q_loc_estimateX(removeX,i) = nan;
Q_loc_estimateY(removeY,i) = nan;
end
Walter Roberson
Walter Roberson 2023년 9월 20일
When you invoke a function in MATLAB, and the function has named parameters, then MATLAB never searches the environment hoping to find a definition for the parameter. In every case, when there are named parameters for a function, the value associated with the variable name inside the function is based upon what was passed positionally by whatever invoked the function. It is not directly an error to invoke a function and pass in fewer positional values than there are named variables in the function, since the function can use nargin to find out how many parameters were passed and can implement suitable defaults.
For example,
function plotme(f, lb, ub)
if nargin == 0
f = @(x)x.^2 - sin(2*pi*x); lb = 0; ub = 10;
elseif nargin == 1
lb = 0; ub = 10;
elseif nargin == 2
ub = 10;
end
end
This example code can be invoked with 0, 1, 2, or 3 positional parameters, and supplies its own default values for the parameters that the user did not supply.
So it is not inherently work to invoke TadFunctionTestAt by itself with no parameters even though the function definition is
function [encAvg,numEncount,numAvoid] = TadFunctionTestAT(mov,initvals,outdir);
because the code inside TadFunctionTestAT might choose to test nargin and do something reasonable if passed less than 3 parameters. Or it might just choose to give an error message that is more meaningful to the situation than the generalized MATLAB error message might be.
If you were to invoke TadFunctionTestAT passing in (say) one parameter, then under no circumstances would MATLAB go hunting in the calling function or the "base" workspace or the "global" workspace hoping to somewhere find a defined variable named initvals to use the value of that variable in the function. There are some limited circumstances under which MATLAB will go hunting for variables that have not been defined inside the local function, but those circumstances never apply to a named parameter of a function.
You are invoking TadFunctionTestAT from the command line, either by typing in its name or by pressing the green Run button in the TadFunctionTestAT.m file. You are not passing any parameters to it. MATLAB is never going to go searching outside the function to find values for mov, initvals, outdir . If the code for TadFunctionTestAT is not checking nargin and providing usable default values for the parameters, then you are invoking TadFunctionTestAT incorrectly
This discussion would have been totally unnecessary if you had not tried to run TadFunctionTestAT by itself and instead had just run the code from https://www.mathworks.com/matlabcentral/answers/2021761-error-message-index-exceeds-matrix-dimension#comment_2890677 -- which calls TadFunctionTestAT appropriately

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Performance and Memory에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by