开发者

Matlab - moving window, avoiding nested loops

I'm trying to write a "weighted moving window" without nested loops for speed improvement. I already tried using arrayfun without getting exciting results, but maybe I did it in a wrong way.

The window has a different weight in each position (stored in B) and should be superimposed on a matrix A returning the values of the matrix A that lie inside the window, times the weight of the window in that position (read from B). Also, the windows can overlap one on the other and in this case the maximum value should be kept. Finally window's dimension and shift should be parameters of the function.

开发者_Go百科

It looks more difficult that it actually is, so I show you the code that I would like to improve:

A = reshape([1:35],7,5)';   % values matrix
B = [1:3;4:6];              % window s weight matrix

% matrices size
[m n] = size(A);
[a b] = size(B);

% window s parameters
shift = 2;                  % window s movement at each iteration
zone = 3;                   % window s size (zone x zone)

% preallocation
C = ones(m,n);              % to store the right weight to be applied in each position

% loop through positions and find the best weight when they overlap
for i=1:m
    for j=1:n
       C(i,j) = max(max(B( max(round((i-zone)/shift)+1,1) : min(ceil(i/shift),a) , max(round((j-zone)/shift)+1,1) : min(ceil(j/shift),b))));
    end
end

% find the output of the windows
result = C.*A;

I hope that I made myself clear, but if you need more details please ask. Thank you in advance for your help!


If you have access to the Image Processing Toolbox, you'll want to check out how to perform sliding neighborhood operations. In particular, I think the function NLFILTER can be used to achieve the result you want:

A = reshape([1:35],7,5)';  %'# Matrix to be filtered
B = [1:3;4:6];              %# Window weights
result = nlfilter(A,[2 3],@(M) max(M(:).*B(:)));


I would use im2col. Assuming your image is j x k, and your window is m x n, you'll get a matrix that is mn x (j-m+1)*(k-n+1). Then, you can just take every other column.

Example Code:

%A = your_image
B = im2col(A, [m n],'sliding');
C = B(:,1:2:end);

And there's your sliding window with "shift 2".


Try filter.

For example, to do a windowed average, over 5 elements:

outdata = filter([ 0.2 0.2 0.2 0.2 0.2 ], 1, indata);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜