2013-08-03 2 views
1

나는 아래에 설명 된 문제에 대한 좋은 해결책을 찾기 위해 오래 동안 고심하고 있습니다. 나는 루프를 피하고 싶지만, MATLAB의 기술이 그렇지 않으면 부적절하다고 생각합니다. 크기가 329x230x105 인 3D 위치 매트릭스가 있습니다. 이것은 10000x7000x3100 미터의 3d 볼륨을 정의합니다. MATIX 요소의 대부분은 서브 볼륨 제외 제로인 :Matlab : 볼륨의 윤곽선으로 마스크 만들기

enter image description here

내가 큰 submatices 분할 내 원래 행렬과 같은 크기의 마스크를 생성 할 필요가 각각 1000x1000x1000 m의 일반 서브 볼륨을 규정 내 원래 행렬에서 하나 이상의 on 요소 (0이 아닌)가 들어있는 부분 행렬의 모든 요소에 1을 대입합니다. XY 볼 : enter image description here

그래서 결과적으로 표시된 셀 내의 모든 요소 (적색)가 값 1 및 소자 외측 0으로 설정되어있는 3 차원 마스크 (XY 아래도)이다

enter image description here

볼륨 경계 상자 또는 볼록 선체 버텍스에 관심이 없습니다.

미리 감사드립니다.

추가 정보는, 대답은 @grantnz하기 :

잘, 나는 다음과 같은 코드가 여기에 모든 상황에서 작업을 수행하지만, 경우 아직 확실하지 않다 것은 내가 무엇을 (그리고 내 노트북에 약 10 초 소요) :

% get subscripts of non-zero 3d grid cells 
[u v w]=ind2sub(size(tmpT),find(tmpT)); % tmpT is the original 230x329x105 matrix 
increm = 30.480061;  % grid cell size in meters 
U=(u-1)*increm;   % convert subscripts to position in meters 
V=(v-1)*increm; 
W=(w-1)*increm; 
U=U/1000;     % round down to nearest 1000 meter 
V=V/1000; 
W=W/1000; 
U=floor(U); 
V=floor(V); 
W=floor(W); 
U=U*1000; 
V=V*1000; 
W=W*1000; 
U=round(U/increm);  % find subscripts of 1000 meter cells 
V=round(V/increm); 
W=round(W/increm); 
U(U==0)=1;    % make sure no zero 
V(V==0)=1; 
W(W==0)=1; 
IX=[U V W];    % make subscript matrix 
[q,i,j]=unique(IX,'rows'); % find unique vectors in subscript matrix 
myMask=zeros(size(tmpT)); % initiate mask matrix 
oneKM = 33;    % this many cells in 1000 meters 
for i=1:length(q)   % for each position vector, set mask (from:from+1000 meter) to 1 
    myMask(q(i,1):q(i,1)+oneKM,q(i,2):q(i,2)+oneKM,q(i,3):q(i,3)+oneKM)=1; 
end 
+0

for 루프 기반 코드가 이미 있습니까? 코드를 보여 주면 벡터화하려는 것을 이해하는 것이 더 쉬울 것입니다. – grantnz

답변

1

나는 다음과 같은 해결책을했다 :

clear all 
clc 

x=1:336; 
y=1:240; 
z=1:120; 

[meshy, meshx, meshz] = meshgrid(y, x, z); 

% myspace is just your volumentric dataset as a logical matrix 
s1 = [168 120 60]; 
myspace = sqrt((meshx - s1(1)).^2 + (meshy - s1(2)).^2 + (meshz - s1(3)).^2) < 15; 

% Now let's do the work 
div = [6 6 6]; % size of one submatrix 

cells_x = ceil(x ./ div(1)); 
cells_y = ceil(y ./ div(2)); 
cells_z = ceil(z ./ div(3)); 

% The order of x and y is correct 
[cmeshy, cmeshx, cmeshz] = meshgrid(cells_y, cells_x, cells_z); 

% Here, the transformation happens. 
volx = cmeshx(myspace); 
voly = cmeshy(myspace); 
volz = cmeshz(myspace); 

newspace = zeros(size(myspace) ./ div); 
indices = sub2ind(size(newspace), volx, voly, volz); 
newspace(indices) = 1; 

vol3d('cdata', newspace); 
view(3) ; 

코드는 매트릭스 크기가 행렬의 크기에 의해 균등하게 나눌 수 있다고 가정합니다. 그렇지 않은 경우 원래 행렬을 잘라내거나 채 웁니다.

div 변수가 하위 행렬의 크기를 지정한 후에 셀 변수가 계산됩니다. 여기에는 원래 공간의 각 색인에 대해 새 공간의 색인이 있습니다. 이들은 meshgrid로 확장됩니다. (x, y, z), cmeshz (x, y, z)와 같은 새로운 공간의 모든 좌표에 대해,)

그런 다음 논리적 색인을 사용하여 변환을 쉽게 수행 할 수 있습니다. 자, vol (xyz) vars에 (x, y, z) 튜플이 있습니다. 이를 새로운 공간에 넣으려면 선형 인덱스가 계산되고 적용됩니다.

+0

많은 감사하지만 코드를 실행하는 데 문제가 있습니다. 아마 나는 오해하고있다. "x = 1 : 336; y = 1 : 240; z = 1 : 120;"정의 된 "s1 = [168 120 60]", 즉 가운데에 있고 "div = [6 6 6] ", 내 공간을 다시 정의하여 중심에 큰 구 (0.5에서 15로 변경)를 갖도록했습니다. 그러나 결과는 X 축을 따라 계속 늘어나는 영역입니다. – user1641496

+0

시각화 코드를 제공해 주시겠습니까? 나는 그것과 약간의 문제가 있었고 가변보기로 확인해야했다. ... –

+0

나는 파일 교환에서 "vol3d.m"코드를 사용한다. – user1641496