我有一个矩阵,我想逐步将它分成更小的部分。在第一步中,它本身是一个1 by 1
矩阵,在第二步中,它被分为四个子矩阵2 by 2
矩阵,在下一步中,它被分为十六个子矩阵,4 by 4
矩阵和等等。
我的矩阵是n乘n和2的幂。
我怎样才能按照我所处的步骤快速完成?
这是我编写的代码,但效率不够。
function [A,B] = qtree(X,K,N,l)
L = log2(N);
wx = (size(X,1))/(2^l);
wk = (size(K,1))/(2^(L-l));
for n=1:2^l
m (n,:) = (n-1)*wx+1:n*wx ;
end
for n=1:2^(L-l)
mm (n,:) = (n-1)*wk+1:n*wk ;
end
% the ordering is like MATLAB, from top to bottom and left to right
k=1;
for i = 1:size(m,1)
for j= 1:size(m,1)
A(:,:,k) = X(m(j,:),m(i,:));
k = k+1;
end
end
kk=1;
for i = 1:size(mm,1)
for j= 1:size(mm,1)
B(:,:,kk) = K(mm(j,:),mm(i,:));
kk = kk+1;
end
end
答案 0 :(得分:0)
我要做的是使用mat2cell
来帮助您将矩阵分解为子矩阵,其中每个子矩阵属于一个单元格。在此之后,简单地将它们全部连接成3D数值矩阵,其中i th 切片表示i th 子矩阵。因此,从主标度(原始矩阵)开始,您可以简单地将行和列细分为2的幂,将它们放入单元格中,然后在空间上将所有这些单元格连接成数字3D矩阵。但是,此代码假定您的矩阵维度为2的幂。如果不是,则此方法将不起作用。我的一个建议是填充矩阵,使其均匀地适合2的幂。你可以做的是使用nextpow2
来确定行和列的最大兼容能力2,然后创建一个这个增加的大小的矩阵并将矩阵放在里面。但是,如果您的矩阵大小已经是2的幂,那么nextpow2
将只返回该数字的精确log2
,因此当我们完成时不会有任何零填充。它只是原始矩阵。
我不确定您正在使用哪种输入,但如果大小不是2的幂,这将处理所有通用大小矩阵。
换句话说,如果您的矩阵存储在A
中,并指定num_scales
作为您要执行这些细分的次数,请尝试以下操作:
[rows, cols] = size(A); %// Get dimensions
%// Determine compatible dimensions for matrix
rows_pad = 2^(nextpow2(rows));
cols_pad = 2^(nextpow2(cols));
%// Create padded matrix
Apad = zeros(rows_pad, cols_pad);
Apad(1:rows, 1:cols) = A;
num_scales = 5; %//Determines number of subdivisions
%// You can also intelligently figure this out by:
%// num_scales = min(log2(rows_pad), log2(cols_pad)) + 1;
for s = 1 : num_scales
Bcell = mat2cell(A, (rows_pad/(2^(s-1)))*ones(2^(s-1),1), (cols_pad/(2^(s-1)))*ones(2^(s-1),1)).';
B = cat(3,Bcell{:});
%// B contains this 3D matrix
%// Continue your processing...
%//
end
请注意,您可以通过获取行和列的log2
并确定最小值并添加1来智能地确定要分解图像的最大比例数。我已将其添加为注释设置num_scales
后。但是,我将此设置为常量,以防您不希望将矩阵一直分解为单个1 x 1
元素。
B
包含3D矩阵,其中每个切片是i th 子矩阵。请注意,此代码将按行存储块 。这意味着子矩阵从左到右,从上到下。如果您需要列主要订单,只需删除.'
语句末尾的转置运算符(Bcell = ...
)。
现在,Bcell = ...
声明可能会让你失望。让我们慢慢地逐步完成这个陈述。这里又是自我遏制:
Bcell = mat2cell(A, (rows_pad/(2^(s-1)))*ones(2^(s-1),1), (cols_pad/(2^(s-1)))*ones(2^(s-1),1)).';
mat2cell
的工作原理是您提供要分区为单元格的矩阵,在我们的示例中为Apad
。接下来的两个输入是1D向量,它们告诉您正在分区的每个块的大小。第二个输入适用于行,而第三个输入适用于列。因此,在第一次迭代中,我们只有一个相同大小的单个2D矩阵,因此在1
循环中的比例for
,我们只需得到相同大小的单元矩阵。 / p>
在下一次迭代中,我们的比例为2
,因此等效的调用将是:
Bcell = mat2cell(Apad, [rows_pad/2 rows_pad/2], [cols_pad/2 cols_pad/2]);
该语句基本上创建了4个子矩阵,其中细分发生在行的中间和列的中间。在第三次迭代中,我们的比例为4
,因此等效的调用将是:
Bcell = mat2cell(Apad, [rows_pad/4 rows_pad/4 rows_pad/4 rows_pad/4], ...
[cols_pad/4 cols_pad/4 cols_pad/4 cols_pad/4]);
因此,我们将行和列均分为4个段,在4 x 4网格中提供16个子矩阵。这就是ones
语句的目的,这样我们就可以根据需要多次复制这个语句。
最后,我们使用cat
将所有这些2D矩阵堆叠到一个3D矩阵中,并指定第三个维度,以便我们堆叠这些矩阵。 B
应包含您的最终3D矩阵,您可以从该点开始执行任何处理。
这应该足以让你开始。祝你好运!