Hello,
I am using a loop to calculate Area, Perimeter, etc. of some particles from a set of pictures and I would like to save the results from all the iterations in one table. I only manage to get the results from the last one. When i tried indexing I get an error:
Subscripting into a table using one subscript (as in t(i)) is not supported. Specify a row subscript and a variable subscript, as in
t(rows,vars). To select variables, use t(:,i) or for one variable t.(i). To select rows, use t(i,:).
for i=1:5
% rest of code
results = regionprops('table',lm2, 'Area','Perimeter','MinFeretProperties','MaxFeretProperties');
results_total = table;
results_total = [results_total;results];
end

댓글 수: 1

Paul Costache
Paul Costache 2021년 8월 14일
results_total = table; I think I found the problem as this row of the code had to be outside of the loop.

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

 채택된 답변

Adam Danz
Adam Danz 2021년 8월 14일
편집: Adam Danz 2021년 8월 16일

0 개 추천

As you noted, the second line of code in your for-loop should be moved outside and prior to the for-loop. However, there are two details that could make this solution inefficient.
First, the number of rows in each table is equal to the number of detected objects in the image so if you vertically concatenate all tables you will no longer be able to associate the rows of the table to the images you're looping through. If the images are very clean and you are certain of the number of expected objects in each image, you could compute the image index value for each row of the final table but I wouldn't trust that code.
Second, pre-allocation is almost always more efficient and eliminates indexing problems that occur when overwriting a variable.
This modification of your solution addresses those issues. It adds a column, imageIdx, that specifies the index value of the image. It's also a bit faster than without pre-allocation.
n = 5;
stats = cell(n,1);
for i = 1:n
stats{i} = regionprops('table',bw,'Centroid',...
'MajorAxisLength','MinorAxisLength');
end
imageIdx = repelem(1:n,cellfun(@(c)size(c,1),stats))';
statsTbl = [table(imageIdx), vertcat(stats{:})];
Example of output
>> head(statsTbl)
ans =
8×4 table
imageIdx Centroid MajorAxisLength MinorAxisLength
________ ________________ _______________ _______________
1 256.5 256.5 834.46 834.46
1 300 120 81.759 81.759
1 330.47 369.83 111.78 110.36
1 450 240 101.72 101.72
2 256.5 256.5 834.46 834.46
2 300 120 81.759 81.759
2 330.47 369.83 111.78 110.36
2 450 240 101.72 101.72
>>

댓글 수: 3

Hello and thank you for your answer.
As you said it would be helpful to save the index of each object for each foto. For example foto 1 has 10 objects and foto 2 has 5 objects. Something like this.
ImageIdx ObjectIdx
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
2 1
2 2
2 3
2 4
2 5
In your code then n would be the number of fotos used in the loop. And the ObjectIdx would come from the labelmatrix (lm2 in my code, bw in yours). I don't know how to implement also the ObjectIdx and also what 'c' should be in your code. Thanks for your help.
I would create the object index outside of the loop after creating ImageIdx by using the lines below.
nObjectsPerImg = groupcounts(ImageIdx); % number of objs per image
ObjIdx = cell2mat(arrayfun(@(n){(1:n)'},nObjectsPerImg)); % obj index
% Create final table
statsTbl = [table(ImageIdx, ObjIdx), vertcat(stats{:})];
Paul Costache
Paul Costache 2021년 8월 15일
Worked perfectly. Thank you!

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

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Matrix Indexing에 대해 자세히 알아보기

태그

질문:

2021년 8월 14일

편집:

2021년 8월 16일

Community Treasure Hunt

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

Start Hunting!

Translated by