2014-10-28 248 views
0

我有一个矩阵,我想将它分成更小的部分一步一步。在第一步中,它本身就是一个1 by 1矩阵,在第二步中将其分成四个子矩阵,2 by 2矩阵,下一步将其分为16个子矩阵,4 by 4矩阵等。快速四叉树构造,matlab中的矩阵分割

我的矩阵用的2

n和功率N如何我能做到这一点,根据步骤我在和一个快速的方法?

这是我写的代码,但效率不够高。

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 
+2

你能否描述一下你的算法并且定义你所说的级别? – Dan 2014-10-28 13:03:52

+0

@丹我已编辑它。 – 2014-10-28 13:24:54

+0

不要删除你的代码!你的矩阵也保证是* n * -by- * n *,其中* n *是2的幂。 – Dan 2014-10-28 14:05:34

回答

0

我会做的是使用mat2cell帮你分解成矩阵子矩阵,每个子矩阵属于一个小区。在此之后,将它们全部简单地连接成3D数字矩阵,其中片段表示子矩阵。因此,从主尺度(原始矩阵)开始,您可以简单地将行和列细分为2的幂,将它们放入单元格,然后将所有这些单元格空间连接成数字3D矩阵。但是,这个代码假设你的矩阵维度是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。不过,如果您不想将矩阵一直分解到单个元素,我将其设置为常量。

B包含3D矩阵,其中每个片段是我的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矩阵。接下来的两个输入是一维向量,它告诉你要划分的每个块的尺寸。第二个输入在行上工作,而第三个输入在列上工作。因此,在第一次迭代,我们只是一个相同大小的单个二维矩阵,所以在for循环规模1,我们只会看到同样大小的细胞基质。

在接下来的迭代,我们的规模是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×4的网格内的16子矩阵。这就是ones声明的目的,所以我们可以根据需要多次复制这些数据以满足规模要求。

最后,我们只是堆叠所有这些二维矩阵的成使用cat三维矩阵,我们指定该第三维,以在那里我们堆叠这些矩阵。 B应该包含最终的3D矩阵,并且您可以从该点开始执行任何您想要的处理。


这应该有希望足以让你开始。祝你好运!

+0

我试过'A = rand(1024,1024)'和'num_scales = 16'。它给出了一个错误 – 2014-10-28 14:56:30

+0

@shalooshaloo这是因为'log2(1024)= 10'。您正在指定比可以处理的更多的比例。改为使用'num_scales = 10'。 – rayryeng 2014-10-28 14:57:35

+0

@shalooshaloo - 如果需要,我还编辑了我的帖子,在评论中动态地计算了num_scales。 – rayryeng 2014-10-28 14:58:56