2014-10-28 4 views
0

나는 작은 부분으로 그것을 단계적으로 나누고 싶은 매트릭스가있다. 1 단계에서는 그 자체가 1 by 1 행렬이고, 2 단계에서는 4 행렬로 나누어지고, 다음 행렬에서는 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

+0

@Dan 편집했습니다. –

+0

코드를 삭제하지 마십시오! 또한 행렬이 * n * -by- * n *이되도록 보장됩니다. 여기서 * n *은 2의 거듭 제곱입니까? – Dan

답변

0

내가 무엇을 할 것은 각 행렬은 하나 개의 셀에 속하는 위치를 행렬로 행렬을 분해하기 위해 mat2cell에 사용됩니다. 그 후, 모든 것을 간단히 3D 숫자 행렬로 연결하십시오. 여기에서 i th 슬라이스는 i th 서브 매트릭스를 나타냅니다. 따라서 마스터 스케일 (원래의 행렬)부터 시작하여 2의 거듭 제곱으로 행과 열을 세분하고이를 셀에 넣은 다음 이들 셀을 모두 공간적으로 숫자 3D 행렬로 연결합니다. 그러나이 코드에서는 행렬 차원이 2의 제곱에 있다고 가정합니다. 그렇지 않으면이 메서드는 작동하지 않습니다. 내가 가진 한 가지 제안은 매트릭스가 2의 거듭 제곱에 균등하게 맞도록 매트릭스를 채우는 것입니다. 할 수있는 일은 nextpow2을 사용하여 행과 열의 가장 적합한 힘 2를 결정한 다음이 증가 된 크기의 행렬을 만들고 행렬을 안에 배치합니다. 그러나 행렬 크기가 이미 2의 거듭 제곱 인 경우 nextpow2은 해당 숫자의 정확히 log2을 반환하기 때문에 작업이 완료되면 0이 채워지지 않습니다. 단순히 원래의 행렬이됩니다.

난 당신이 사용하고있는 입력의 어떤 종류의 확실하지 않다, 그러나 이것은 당신의 매트릭스 주어진 크기 즉 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 

주행과 열의을 확인하고 가장 작은 값을 구하고 1을 더하십시오.이 값을 num_scales으로 설정 한 후 주석으로 추가했습니다. 그러나 행렬을 단일 요소 1 x 1 요소로 모두 분해하지 않으려는 경우이를 상수로 설정합니다.

B은 각 슬라이스가 번째 서브 매트릭스 인 3D 매트릭스를 포함합니다. 이 코드는 블록 을 행 주요 순서에 저장합니다. 이것은 부분 행렬이 왼쪽에서 오른쪽, 위에서 아래로 취해진다는 것을 의미합니다. 열의 주 순서을 원할 경우 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 행렬 만 있으므로 for 루프의 1 크기에서 동일한 크기의 셀 행렬을 얻습니다. 다음 반복에서

, 우리의 규모는 2, 그래서 해당 호출은 다음과 같습니다

Bcell = mat2cell(Apad, [rows_pad/2 rows_pad/2], [cols_pad/2 cols_pad/2]); 

이 문장은 기본적으로 4 개 세분 바로 행의 중간에 발생하는 서브 매트릭스, 그리고 중간을 만듭니다 기둥들. 세 번째 반복에서, 우리 스케일 4이므로 해당 호출 될 것이다 : 따라서, 똑같이 4 × 4 그리드 내의 16 행렬로 제공 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]); 

. 그것이 ones 구문의 목적이므로 우리가 척도를 제공 할 때 필요한만큼 반복 할 수 있습니다.

마지막으로 cat을 사용하여 이러한 2D 행렬을 모두 3D 행렬에 쌓기 만하면이 행렬을 어디에 쌓을 지 3 차원을 지정합니다. B에는 최종 3D 매트릭스가 있어야하며 그 시점부터 원하는 모든 처리를 수행 할 수 있습니다.


이렇게하면 시작하기에 충분합니다. 행운을 빕니다!

+0

'A = rand (1024,1024)'와'num_scales = 16'을 시도했습니다. 그것은 오류를 준다 –

+0

@shalooshaloo 그것은'log2 (1024) = 10'이기 때문이다. 처리 할 수있는 것보다 많은 비율을 지정하고 있습니다. 대신에'num_scales = 10'을 사용하십시오. – rayryeng

+0

@shalooshaloo - 또한 원하는 경우 의견에서 동적으로 num_scales를 계산하기 위해 내 게시물을 편집했습니다. – rayryeng