How to apply recursion?

2 views (last 30 days)
Krishna Chaitanya
Krishna Chaitanya on 9 Jan 2020
Commented: Guillaume on 17 Jan 2020
I am trying to use recursion to apply region growing but I have got an error: Out of memory. The likely cause is an infinite recursion within the program.
I am posting the code snippet here,Can somebody point out the error and make suggestions.Thank you.
Here,Ig is the grayscale image with intensities to check
i is column vector containing x-coordinates of seed pixels
j is column vector containing y-coordinates of seed pixels
threshold is column vector containing threshold values for seed pixels
reg_output is the final logical array output after region growing ,
visited is a matrix used to prevent redundant computations using recursion,
%REGION GROWING FROM ALL LOW INTENSITY PIXELS
global reg_output;
reg_output = zeros(size(Ig));
global visited;
visited = zeros(size(Ig));
global row;
global col;
row = [-1;-1;-1;0;0;1;1;1];
col = [-1;0;1;-1;1;-1;0;1];
global si;
global sj;
[si,sj] = size(Ig);
for ll = 1:length(i)
region_grow(i(ll),j(ll),threshold(ll));
end
figure,imshow(reg_output)
function region_grow(m,n,t)
global reg_output;
global visited;
global Ig;
global row;
global col;
global si;
global sj;
reg_output(m,n) = 1;
visited(m,n) = 1;
for kc = 1:length(row)
i = m+row(kc);
j = n+col(kc);
if i>=1 && i<=si && j>=1 && j<=sj
if visited(i,j)==0 && Ig(i,j)>= t
region_grow(i,j,t);
end
end
end
end
  4 Comments
Adam Danz
Adam Danz on 9 Jan 2020
All of those global variables reminds me of a mirror "fun house" where you have no idea where objects are coming from or where they are heading.
200109 085847-UI Figure.png
A better solution is to pass in a structure or cell array variable containing all of the globally accessed variables.
Which line is throwing the error?
Guillaume
Guillaume on 9 Jan 2020
it looks like the global are probably local to the functions, so possibly could be replaced by persistent variables.
However, even that I'm not convinced that it's needed, particularly if the recursion is removed. Recursion is rarely a good idea.

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 9 Jan 2020
Recursion is rarely an efficient coding method and I wouldn't be surprised if you hit the default recursion limit on some large images.
As we've commented global variables are an absolute no-no. They make understanding the code extremely hard and there are always cleaner alternatives.
The first (and only!) comment in your code states that it is for growing region around low intensity pixels, yet your algorithm look for pixels above a given threshold, hence look for high intensity pixels. So your (only!) comment is misleading. Note that code without comments is just as useless as code with globals.
If I understood your algorithm correctly, this is how I would code it:
function neighbours = region_grow(img, startrow, startcol, threshold, connectivity)
%find all the neighbouring pixels above the given threshold around a start pixel
%inputs:
%img: a 2D greyscale image, of size MxN
%startrow: row coordinate of start pixel. Must be a positive scalar <= M
%startcol: column coordinate of start pixel. Must be a positive scalar <= N
%threshold: minimum intensity of neighbouring pixel for it to be included in the neighbourhood. Scalar
%connectivy: either 4 for othogonal connectivity or 8 for orthogonal and diagonal
%returns:
%neighbours: logical matrix of size MxN where 1 indicates a pixel in the neighbourhood of the start pixel
abovethreshold = img >= threshold; %find all pixels above threshold, wherever they are
labels = bwlabel(abovethreshold, connectivity); %label all connected pixels with the same ID
startid = labels(startrow, startcol); %label associated with start pixel
if startid == 0
%a label of 0 is the background which means the start pixel intensity is below the threshold!
neighbours = false(size(img));
neighbours(startrow, startcol) = true; %then region is just that pixel
else
neighbours = labels == startid; %get all pixels connected to the startpixel, which are the ones with the same label.
end
end
And the calling code would be:
%better variable names than i, j, ll required!
reg_output = false(size(Ig));
for ll = 1:numel(i)
reg_output = reg_output | region_grow(Ig, i(ll), j(ll), threshold(ll), 8);
end
  2 Comments
Krishna Chaitanya
Krishna Chaitanya on 17 Jan 2020
Edited: Krishna Chaitanya on 17 Jan 2020
You sure this method will work? cause i'm getting a different output than what should i get.
Thank you.
Guillaume
Guillaume on 17 Jan 2020
Nowhere have you explained what the algorithm should do. As I wrote, your one and only comment states that you're looking for low intensity pixels, yet the code you wrote does the exact opposite. So, no, I don't know if the code does what you want since I don't know what you want. I've implemented the same as what I assumed your code was trying to do (ignoring the comment) in a much simpler manner.
You should use this as a starting point for doing whatever you want to do. If you are actually looking for low intensity pixels, the change the img >= threshold into img <= threshold. The code is heavily commented so you should be able to understand what it does.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!