【问题标题】:Sliding window summation of a matrix矩阵的滑动窗口求和
【发布时间】:2020-07-23 13:23:16
【问题描述】:

我有一个 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

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

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

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

【问题讨论】:

  • 滑动窗口求和可以使用result = conv2(A, ones(10), 'valid');完成
  • 窗口是垂直滑动、水平滑动还是任意方向滑动?
  • @kkuilla 全方位。我想要每一个可能的 10x10 窗口。

标签: arrays matlab matrix


【解决方案1】:

问题 #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');

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

result = movsum(movsum(M, N, 1, 'Endpoints', 'discard'), N, 2, 'Endpoints', 'discard');

例子:

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

问题 #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

在这个例子中,

out_coords =
     1     2
     2     2
     3     2
     1     3
     2     3
     3     3

【讨论】:

【解决方案2】:

编辑:您想要conv2 解决方案。当你只问身体里有什么而不​​是 cmets 时,我回答了这个问题,所以我回答了如何让窗户对角滑动。如果你想要全部,你想要 conv2 Luis 建议的那样。

回答#1

num_pixels_box=10;
offset=[1,1];
num_offsets=size(img,1)/num_pixels_box; % assumes square image and box

for ii=1:num_offsets
    index_start=[0,0]+ii*offset;
    index_end = index_start+[num_pixels_box-1,num_pixels_box-1];
    result(ii)=sum(sum(img(index_start(1):index_end(1),index_start(2):index_end(2))));
end

我还没有测试过,但应该是关于如何以 MATLABesque 方式创建它的一般想法。你可以将这些东西组合成其他变量,或更紧凑的形式,但我希望这样是有意义的。

回答#2

如果你有一个正方形的上限和下限,知道一个点是否在它里面,它只是几个 if 条件。为清楚起见,创建一个函数is_in_square()。然后只需遍历现有的窗口。

【讨论】:

    猜你喜欢
    • 2016-08-16
    • 2013-08-21
    • 2019-02-09
    • 2014-08-14
    • 2013-05-01
    • 2018-05-12
    • 2014-01-12
    • 2016-11-25
    • 2018-09-25
    相关资源
    最近更新 更多