Best practise for quickly changing parameters of a function?

13 views (last 30 days)
Let's say I have the below function (just as an example), which segments objects in an image. I'm testing it on different images. Each time I run it I might want to adjust parameters, e.g. in this case, the numbers 0.38, 800, and 32, to see if it now works better with my images.
function burnedAnt = createAntSegmentation(ant)
greyant = rgb2gray(ant);
adaptedAnt = adaptthresh(greyant, 0.38,"ForegroundPolarity","dark"); % threshold image.
BW = imbinarize(greyant,adaptedAnt); % binarize ant image
BWopen = bwareaopen(~BW,800); % exclude pixels smaller than X
se = strel("disk",32); % create shape used for dilating image
BWdilate = imdilate(BWopen,se); % dilate image
BWfilled = imfill(BWdilate,"holes"); % fill in any holes
burnedAnt = imoverlay(ant,~BWfilled,"k"); %produce final image
end
Instead of scrolling through the code and manually changing each value, what is the best way / reccomended way to quickly do this? I was thinking of having several variables at the top of my script, and then calling these variables in the function. This intuitively seems good to me as it's visually easy to see what they are.
% adjust these values before running function
adaptedThreshValue = 0.38
BWopenValue = 800
seDiskSize = 32
Or is it better to have the values all in one matrix, like this, and index them in the function instead?
functionValues = [0.38, 800, 32]
% 1 = adapted threshold value
% 2 = BWopen value
% 3 = se disk size value
In this way, when I've got a couple of functions in one script, I figure it'll make things much quicker to change, and I can copy + paste the parameters that I ran before, and save them as text in several lines to keep track of what I've been trying out. But, I've only been working on Matlab for a few weeks so thought I would see what everyone reccomends. Thanks!
  2 Comments
Mathieu NOE
Mathieu NOE on 26 Feb 2021
hello
IMO, the best way is to create a structure of parameters and pass this structure as an argument in your function
so the main script starts with the structure initialization :
param. threshold_value = 0.38
param. BWopen_value = 800
param. disk_size_value = 32
when you call your function, this is how to pass the arguments :
function burnedAnt = createAntSegmentation(ant,param)
and inside the function you can retrieve the individual parameters :
threshold_value = param.threshold_value;
BWopen_value = param.BWopen_value;
disk_size_value = param.disk_size_value;
and use those parameters in your code
the beauty with structures is that you can add as many parameters you want without having to modify how to pass the param structure to the functions
BC
BC on 26 Feb 2021
Edited: BC on 26 Feb 2021
This works perfectly, thank you. I can also just directly call the structure fields in the function without the last part of the code you provided. Is there any reason (in general) not to do this? e.g.
adaptedAnt = adaptthresh(greyant, param.threshold_value,"ForegroundPolarity","dark"); % threshold image.
EDIT: by the way, if you want to copy and paste your comment to an answer, I can accept it as the answer :)

Sign in to comment.

Accepted Answer

Image Analyst
Image Analyst on 26 Feb 2021
Try this:
functionValues = [0.38, 800, 32;
0.5, 700, 64;
0.4, 750, 16] % Whatever values you want
% Loop through all sets of values passing them to the segmentation function.
for k = 1 : size(functionValues, 1)
threshold = functionValues(k, 1);
minBlobSize = functionValues(k, 2);
radius = functionValues(k, 3);
burnedAnt = createAntSegmentation(ant, threshold, minBlobSize, radius);
% Now do something with burnedAnt, like display it, save it, call regionprops, or whatever...
end
%===============================================================================
function burnedAnt = createAntSegmentation(ant, threshold, minBlobSize, radius)
% Convert to gray scale if necessary. Calling rgb2gray() on a grayscale image will throw an error. Needs to be a color image.
if ndims(ant) == 3
greyant = rgb2gray(ant);
else
greyand = ant;
end
adaptedAnt = adaptthresh(greyant, threshold, "ForegroundPolarity", "dark"); % threshold image.
BW = imbinarize(greyant,adaptedAnt); % binarize ant image
BWopen = bwareaopen(~BW, minBlobSize); % exclude pixels smaller than X
se = strel("disk", radius); % create shape used for dilating image
BWdilate = imdilate(BWopen, se); % dilate image
BWfilled = imfill(BWdilate, "holes"); % fill in any holes
burnedAnt = imoverlay(ant, ~BWfilled, "k"); %produce final image
end
  1 Comment
BC
BC on 26 Feb 2021
Thanks for this, appreciate the effort into writing the code! This will come in handy for testing a few different parameters quickly, though creating a structure as per the other suggestions also helps too.
Out of interest given the relevance and your experience, I have another open question regarding this segmentation function that hasn't had any responses yet - if you ever get a chance I would hugely appreciate any thoughts on it. Thanks again!

Sign in to comment.

More Answers (1)

Simon Allosserie
Simon Allosserie on 26 Feb 2021
For each number you want to change regularly, make it also an input parameter to your function.
Then, you can write a little script to go through all the options, by listing the different options per parameter in a list or matrix, and then looping through the matrix to execute the function over and over again using all the different input combinations.
  2 Comments
BC
BC on 26 Feb 2021
Thank you, definitely a more elegant solution than what I was thinking!
Simon Allosserie
Simon Allosserie on 26 Feb 2021
You're welcome :) Please vote my answer as the correct one to close this question. Thanks!

Sign in to comment.

Categories

Find more on Image Processing Toolbox in Help Center and File Exchange

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!