# How to reduce for loops in a moving window based operation?

1 view (last 30 days)
h612 on 27 May 2017
Edited: Jan on 27 May 2017
How to reduce for loops in a moving window based operation? I'm using a 15x15 window across two images and performing multiplication to get average value per pixel.
win1=15;
pp=1;qq=1;
[ma,na]=size(g); g represents an image
z= (win1 -1)/2;%centre of window
ini=z+1;
for i= ini :(ma-z)
for j= ini:(na-z)
for a= (i-z):(i+z)
for b=(j-z):(j+z)
W(pp,qq)= g(a, b);%window on image
Es(pp,qq)=edg(a,b);%window on image containing edges
qq=qq+1;
end
qq=1;
pp=pp+1;
end
pp=1;
E(i,j)=sum(sum(W.*Es))/sum(sum(Es));
end
end
h612 on 27 May 2017
@Jan Simon, kindly refer to the code now.

Jan on 27 May 2017
Edited: Jan on 27 May 2017
Based on some guessing:
[ma,na] = size(g);
z = (win1 -1)/2;%centre of window
ini = z+1;
E = zeros(ma-z, na-z); % Pre-allocate!!!
for i = ini:(ma-z)
for j = ini:(na-z)
W = g((i-z):(i+z), (j-z):(j+z));
Es = edg((i-z):(i+z), (j-z):(j+z));
E(i,j) = sum(sum(W .* Es)) / sum(sum(Es));
% Faster:
% E(i,j) = (W(:).' * Es(:)) / sum(Es(:));
end
end
Here the element W(i1,i2) is multiplied 2*z times with Es(i1,i2). This is a waste of time. What about starting with:
S = g .* edg;
and then dividing the moving sum of S by the moving sum of edg? This would be the filter2 approach suggested by dpb.
S = g .* edg;
M = ones(z, z);
E = filter2(M, S, 'same') ./ filter2(M, edg, 'same');
This code is not tested and it thought as a demonstration only. Adjust it to you your needs.