How to rewrite a loop in a logical way?

1 view (last 30 days)
I have this loop but it takes too much time for processing it because of the big amount of elements of "x" and "y"... I have tried to write it in a more compact way but it was not successful... I have an image "im_raw" with "2546x3318" elements. It has a lot of holes which are set with "nan" values and I need to fill these "nan" values with the maximum of a submatrix around each gridpoint (9x9 neighbours). So where I have stopped is in this point when I have to find for each gridpoint, which must coincide with the x and y which contain the coordinates where the "nan" values are located and I want to replace by the maximum of that submatrix (9x9) centered in each gridpoint. Could somebody take a look at this example and send me a feedback? I would appreciate it... Thanks in advance.
for i = 10:max(x(:,1))-9
for j = 10:max(y(:,1))-9
im_raw(x(i,1),y(j,1)) = max(max(im_raw(i-9:1:i+9,j-9:1:j+9)))
end
end
  1 Comment
Stephen23
Stephen23 on 3 Feb 2015
Note that you should not use i or j as variable names, as these are the names of the inbuilt imaginary unit .

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 29 Jan 2015
Edited: Guillaume on 3 Feb 2015
Is your neighbourhood 9x9 as in your description or 19x19 as in your code?
I'm sure there must be something for this in the image processing toolbox but I can't think of it right now. In any case, does this work for you?
im_raw(isnan(im_raw)) = -inf; %replace nans with -Inf so it doesn't mess up |max|
%pad matrix to avoid edge issues:
im_raw2 = ones(size(im_raw) + 18) * -Inf; %assuming a 19x19 neighbourhood
im_raw2(10:end-9, 10:end-9) = im_raw; %assuming a 19x19 neighbourhood
[r, c] = find(isinf(im_raw)); %find values to replace
for p = 1:numel(r)
neighbourhood = im_raw2(r(p):r(p)+18, c(p):c(p)+18);
im_raw(r(p), c(p)) = max(neighbourhood(:));
end
edit: fixed bug pointed out by Michael
  7 Comments
Guillaume
Guillaume on 3 Feb 2015
Timing demo:
im_raw = randi(1000, 2546, 3318);
im_raw(im_raw > 998) = NaN;
fprintf('original image has %d nans\n\n', sum(isnan(im_raw(:))));
orig_im = im_raw;
tic
im_raw(isnan(im_raw)) = -inf; %replace nans with -Inf so it doesn't mess up |max|
%pad matrix to avoid edge issues:
im_raw2 = ones(size(im_raw) + 18) * -Inf; %assuming a 19x19 neighbourhood
im_raw2(10:end-9, 10:end-9) = im_raw; %assuming a 19x19 neighbourhood
[r, c] = find(isinf(im_raw)); %find values to replace
for p = 1:numel(r)
neighbourhood = im_raw2(r(p):r(p)+18, c(p):c(p)+18);
im_raw(r(p), c(p)) = max(neighbourhood(:));
end
toc
Displays (on my machine)
original image has 17055 nans
Elapsed time is 0.184098 seconds.
Antonio
Antonio on 3 Feb 2015
Thanks a lot!... now it has worked...;-))

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!