矩阵的滑动窗口求和

use*_*926 7 arrays matlab matrix

我有一个 50x50 矩阵,我想对每 10x10(或另一个设置大小值 - 始终为正方形)重叠网格中的值求和,即:

在此处输入图片说明

为清楚起见,重叠窗口仅显示在对角线上。我尝试做的第一个任务是定义每个窗口的坐标:

win=10;
start = [1,10,1,10];
for y=1:(50-win)
    for g=1:(50-win)
        tmp = [start(g,1)+1,start(g,2)+1,start(end,3),start(end,4)];
        start = [start;tmp];
    end
    start(end+1,1:4) = [1,10,1+y,10+y];
end
Run Code Online (Sandbox Code Playgroud)

然后我会遍历坐标列表,使用sum每个窗口的逻辑索引。

问题#1:上面的代码不是特别有说服力。任何人都可以展示一种更“MATLABesque”的方式或更简洁的方式吗?

问题#2:然后我想在矩阵中定义一个特定的坐标(索引),例如m(26,26)并获取包含该坐标的所有窗口的列表。但我不知道该怎么做。有人可以告诉我怎么做吗?

Lui*_*ndo 5

问题#1

我能想到的最类似于 Matlab 的方法是二维卷积 ( conv2) (正如我现在看到的,@rahnema1 评论了):

M = randi(9, 5, 5); % input: square matrix, arbitrary size
N = 3; % block size, assumed square, not larger than M
result = conv2(M, ones(N), 'valid');
Run Code Online (Sandbox Code Playgroud)

等效地,您可以使用最近引入的movsum函数两次(每个维度一次):

result = movsum(movsum(M, N, 1, 'Endpoints', 'discard'), N, 2, 'Endpoints', 'discard');
Run Code Online (Sandbox Code Playgroud)

例子:

M =
     4     4     3     1     2
     2     8     7     1     6
     3     6     7     5     5
     6     5     4     8     1
     5     9     6     9     4

result =
    44    42    37
    48    51    44
    51    59    49
Run Code Online (Sandbox Code Playgroud)

问题#2

最简单的方法(不是最有效的方法)是再次使用包含true在所需位置的逻辑矩阵false的卷积,否则,并检查卷积不为零的位置:

in_coords = [3 4]; % example input coordinates
T = false(size(M)); % initiallize matrix containing false, same size as M
T(in_coords(1), in_coords(2)) = true; % true at the desired coordinates
C = conv2(T, ones(N), 'valid'); % this gives 1 for blocks affected by in_coords
[ii, jj] = find(C); % row and column indices of nonzero values 
out_coords = [ii jj]; % build result
Run Code Online (Sandbox Code Playgroud)

在这个例子中,

out_coords =
     1     2
     2     2
     3     2
     1     3
     2     3
     3     3
Run Code Online (Sandbox Code Playgroud)