计算子矩阵之和的最快方法是什么?目前我正在通过以下方式解决这个问题:
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 + + +
答案 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
矩阵的“子矩阵”。