计算子矩阵之和的最快方法

时间:2015-11-14 21:28:10

标签: matlab

计算子矩阵之和的最快方法是什么?目前我正在通过以下方式解决这个问题:

x = [1     2     3     4
     1     2     3     4
     1     2     3     4
     1     2     3     4]

>> y = x(1:2, 1:2);
>> y

y =

     1     2
     1     2

>> sum(y(:))

ans =

     6

>> 

如何计算x的所有子矩阵的总和?

修改

在矩阵中的每个点(x,y),我想计算大小为2M + 1的窗口的总和。例如,如果我有一个4x4矩阵,我想在可能的每个点计算3x3窗口的总和(例如,边缘是不可能的,因为窗口会溢出矩阵)

for i = M:ncols-M
    for j=M:nrows-M

    end
end

示例 对于窗口大小为3的4x4矩阵,我希望得到这些总和:

总和为(2,2)

+ + + x
+ + + x
+ + + x
x x x x

总和为(3,2)

x + + +
x + + +
x + + +
x x x x

总和为(2,3)

x x x x
+ + + x
+ + + x
+ + + x

总和为(3,3)

x x x x
x + + +
x + + +
x + + +

4 个答案:

答案 0 :(得分:3)

您正在考虑计算summed area table。简而言之,输出中第i行和列j - (i,j)的每个元素都是从左上角到感兴趣点{{1}的子矩阵的总和用作右下角的。

使用cumsum非常简单:

(i,j)

示例:

y = cumsum(cumsum(x, 1), 2);

...和输出:

>> x = repmat(1:4, 4, 1); %// your example
>> x

x =

     1     2     3     4
     1     2     3     4
     1     2     3     4
     1     2     3     4

因此,对于您的示例,从左上角到>> y = cumsum(cumsum(x, 1), 2) y = 1 3 6 10 2 6 12 20 3 9 18 30 4 12 24 40 的子矩阵求和等于6。

答案 1 :(得分:3)

如果是" submatrix"你的意思是一个固定大小的滑动 2D窗口,它本质上是一个二维卷积:

x = [1     2     3     4
     1     2     3     4
     1     2     3     4
     1     2     3     4];
m = 2; n = 2; %// submatrix size
result = conv2(x, ones(m, n), 'valid');

在此示例中,

result =
     6    10    14
     6    10    14
     6    10    14

答案 2 :(得分:2)

这个答案是在OP澄清之前创建的。它假设子矩阵不重叠

如果您拥有图像处理工具箱,则可以使用blockproc

A = blockproc(x,[2 2],@(k) sum(k.data(:)))

如果您没有,可以使用accumarray

n = 2;              %// number of elements per block in row direction
N = size(x,1)/n;    %// number of blocks in row direction
m = 2;              %// number of elements per block in column direction
M = size(x,2)/m;    %// number of blocks in column direction

idx = repelem( reshape(1:(N*M),N,M),n,m)
B = reshape( accumarray(x(:),idx(:)), N, M )

一些重型重塑也会起作用:

C = reshape(sum(reshape(permute(sum(reshape(x,n,m,[])),[2,3,1]).',n,[])),n,[]).'
A = B = C =

     6    14
     6    14

答案 3 :(得分:0)

x = repmat(1:4, 4, 1); %// your example
[A,B] = size(x);
kk=1;
for ii = 1:2:A
    for jj = 1:2:B
        subsummed(kk) = sum(sum(x(ii:ii+1,jj:jj+1)));
        kk = kk+1;
    end
end

我的循环版本,如果您指的是构成完整矩阵的四个2x2矩阵的“子矩阵”。