Help with syntax for a self-made function
이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
이전 댓글 표시
Hi folks,
I have the following function defined in Matlab but am getting an error when running. The error and the code are below. May I please ask for help with debugging this?
Thanks in advance
function fields = populateFields(index, structure)
Area(index) = getfield(structure, 'Area');
MajorAxisLength(index) = getfield(structure, 'MajorAxisLength');
MinoeAxisLength(index) = getfield(structure, 'MinorAxisLength');
Eccentricity(index) = getfield(structure, 'Eccentricity');
Orientation(index) = getfield(structure, 'Orientation');
ConvexArea(index) = getfield(structure, 'ConvexArea');
Circularity(index) = getfield(structure, 'Circularity');
EquivDiameter(index) = getfield(structure, 'EquivDiameter');
Solidity(index) = getfield(structure, 'Solidity');
Extent(index) = getfield(structure, 'Extent');
Perimeter(index) = getfield(structure, 'Perimeter');
MaxFeretDiameter(index) = getfield(structure, 'MaxFeretDiameter');
MaxFeretAngle(index) = getfield(structure, 'MaxFeretAngle');
MinFeretDiameter(index) = getfield(structure, 'MinFeretDiameter');
MinFeretAngle(index) = getfield(structure, 'MinFeretAngle');
end
function call:
[matrix, numObjects] = bwlabel(mask1);
rg = regionprops(matrix, 'all');
fields = populateFields(1, rg);
The error:
Output argument "fields" (and maybe others) not assigned during call to "Threshold>populateFields".
채택된 답변
Simon Chan
2021년 8월 12일
편집: Simon Chan
2021년 8월 12일
You have not define your output variable 'fields' in your function, so nothing returns from the function
댓글 수: 11
@Simon Chan thanks, may I please ask how to define the output such that all the data is returned?
It depends on how you would like to be the format and type of the output. Below is just an example which only returns the variable 'Area' and 'Perimeter' as a 1x2 matrix. I also change the variable name to 'output'.
function output = populateFields(index, structure)
Area(index) = getfield(structure, 'Area');
MajorAxisLength(index) = getfield(structure, 'MajorAxisLength');
MinoeAxisLength(index) = getfield(structure, 'MinorAxisLength');
Eccentricity(index) = getfield(structure, 'Eccentricity');
Orientation(index) = getfield(structure, 'Orientation');
ConvexArea(index) = getfield(structure, 'ConvexArea');
Circularity(index) = getfield(structure, 'Circularity');
EquivDiameter(index) = getfield(structure, 'EquivDiameter');
Solidity(index) = getfield(structure, 'Solidity');
Extent(index) = getfield(structure, 'Extent');
Perimeter(index) = getfield(structure, 'Perimeter');
MaxFeretDiameter(index) = getfield(structure, 'MaxFeretDiameter');
MaxFeretAngle(index) = getfield(structure, 'MaxFeretAngle');
MinFeretDiameter(index) = getfield(structure, 'MinFeretDiameter');
MinFeretAngle(index) = getfield(structure, 'MinFeretAngle');
%
output = [Area, Perimeter];
end
"... how to define the output such that all the data is returned?"
You could define all fifteen or so variables that you want as output arguments:
But fifteen positional arguments... ugh. That is just designing bugs into your code. Best avoided.
Ditto putting all of the data into one indexed (i.e. positional) array/matrix: you lose the fieldname meta-information.
What is the very good reason why you can't just access the data directly from the structure?
What are you actually trying to achieve?
There are images of objects (~1500 images) which I am thresholding the background out of to get information on the shape of the object. The object colour and shape changes over the images, but also the background colour changes too. Therefore, I need to use different thresholds and techniques to get a mask for the object for different image. The idea, however, is that I have ~200 folders to threshold, each with ~1500 images, so doing this by hand isn't ideal. Hence, there are several conditions within the for loop where I switch from one threshold technique or level to another, depending on the value of the area of the thresholded object (a high difference bewteen the area of the i'th mask and the (i-1)th mask means I need to switch to the next thresholding technique). Therefore, at each image, I threshold the object/background, then measure the region properties to determine if the correct threshold has been used as well as to determine the properties of the region. I then want to store these properties into a variable. The reason I have outsourced the regionprops calls to a function is because I use the terms in the function several times during the programme.
Hope that helps.
@Simon Chan thanks for this, but it appears this doesn't work for me. I've followed your syntax and in the function call, I say
[area, perim] = ...
but it doesn't seem to work unfortunately. I need to build a matrix, cell or struct of the regionprops outputs for each iteration of the loop, so it needs to go into a variable like area(i)...
"...I then want to store these properties into a variable."
You explained that you need to loop over folders and files, and that you need to store data.
I asked why you cannot just use that structure.
So... what is stoping you from just using that structure? You could probably even use a non-scalar structure with as many elements as files you need to process. It would probably be much simpler.
"I need to build a matrix, cell or struct of the regionprops outputs for each iteration of the loop,"
If you used a non-scalar structure then you can do that trivially after the loop:
@Stephen Cobeldick thank you, this is highly informative and the answer I was looking for! apologies for not knowing beforehand, although if I'd known this, I wouldn't need to ask the question!
I'm still unclear on the syntax, however. For example, if I have a struct, RG, within my loop, which is defined as
RG = regionprops(mask1, 'all');
then will RG not be overwritten for each iteration of the loop? Or would you suggest
RG(i) = regionprops(mask1, 'all');
and then extract the specific properties of the struct outside the loop with:
Area = {RG.Area};
"...will RG not be overwritten for each iteration of the loop?"
Yes, which is why you should use indexing, much like you showed.
@Stephen Cobeldick thanks for this, but as I mentioned in my previous comment I still need to access the new elements of the structure within the loop. So i'th Area term, for example, is needed to determine which threshold function I need to correctly threshold the i'th image. It seems like this technique doesn't allow for that.
"It seems like this technique doesn't allow for that."
Here are two simple approaches you could use. Either use the same index
for k = ..
RG(k) = regionprops(mask1, 'all');
RG(k).Area
..
end
or a temporary variable:
for k = ..
tmp = regionprops(mask1, 'all');
tmp.Area
..
RG(k) = tmp;
end
What did you try?
@Stephen Cobeldick thanks for this! I tried the former, but run across this error when partway through the loop, and am not sure what's causing it...I tried defining the variable RG = zeros(numImages, 32) at the start but the error still occurs at the 465th value of i. Can I please ask you why this might be?
Unable to perform assignment because the left and right sides have a different number of elements.
추가 답변 (0개)
카테고리
도움말 센터 및 File Exchange에서 Scripts에 대해 자세히 알아보기
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
